From 8fbdcdd69c3bdf6ce43fcaa7509e32f91c7126d2 Mon Sep 17 00:00:00 2001 From: Shiqi Yang Date: Wed, 30 Oct 2024 12:16:35 -0400 Subject: [PATCH 1/8] Allow checking path conflicts from a child AST node Signed-off-by: Shiqi Yang --- ast/compile.go | 9 ++ ast/compile_test.go | 5 +- ast/conflicts.go | 32 +++++- plugins/bundle/plugin.go | 4 + plugins/bundle/plugin_test.go | 188 ++++++++++++++++++++++++++++++++++ 5 files changed, 235 insertions(+), 3 deletions(-) diff --git a/ast/compile.go b/ast/compile.go index 9025f862b2..a50bd451c9 100644 --- a/ast/compile.go +++ b/ast/compile.go @@ -127,6 +127,7 @@ type Compiler struct { maxErrs int sorted []string // list of sorted module names pathExists func([]string) (bool, error) + pathConflictCheckRoots []string after map[string][]CompilerStageDefinition metrics metrics.Metrics capabilities *Capabilities // user-supplied capabilities @@ -383,6 +384,14 @@ func (c *Compiler) WithPathConflictsCheck(fn func([]string) (bool, error)) *Comp return c } +// WithPathConflictsCheckRoot enables checking path conflicts from the specified root instead +// of the top root node. This would enable optimizting path conflict checks during bundle +// activation if a bundle already defines its own root paths. +func (c *Compiler) WithPathConflictsCheckRoot(rootPaths []string) *Compiler { + c.pathConflictCheckRoots = rootPaths + return c +} + // WithStageAfter registers a stage to run during compilation after // the named stage. func (c *Compiler) WithStageAfter(after string, stage CompilerStageDefinition) *Compiler { diff --git a/ast/compile_test.go b/ast/compile_test.go index dade9ed506..74912f7a59 100644 --- a/ast/compile_test.go +++ b/ast/compile_test.go @@ -1954,6 +1954,9 @@ bar.baz contains "quz" if true`, "mod8.rego": `package badrules.complete_partial p := 1 p[r] := 2 if { r := "foo" }`, + + "mod9.rego": `package anotherbadrules.dataoverlap +p { true }`, }) c.WithPathConflictsCheck(func(path []string) (bool, error) { @@ -1963,7 +1966,7 @@ p[r] := 2 if { r := "foo" }`, return false, fmt.Errorf("unexpected error") } return false, nil - }) + }).WithPathConflictsCheckRoot([]string{"badrules"}) compileStages(c, c.checkRuleConflicts) diff --git a/ast/conflicts.go b/ast/conflicts.go index c2713ad576..5c57f7fda0 100644 --- a/ast/conflicts.go +++ b/ast/conflicts.go @@ -18,8 +18,36 @@ func CheckPathConflicts(c *Compiler, exists func([]string) (bool, error)) Errors return nil } - for _, node := range root.Children { - errs = append(errs, checkDocumentConflicts(node, exists, nil)...) + if len(c.pathConflictCheckRoots) == 0 { + for _, child := range root.Children { + errs = append(errs, checkDocumentConflicts(child, exists, nil)...) + } + return errs + } + + for _, rootPath := range c.pathConflictCheckRoots { + // traverse AST from `path` to go to the new root + paths := strings.Split(rootPath, "/") + node := root + nodeNotFound := false + for _, key := range paths { + child := node.Child(String(key)) + if child == nil { + nodeNotFound = true + break + } + node = child + } + + if nodeNotFound { + // could not find the node from the AST (e.g. `path` is from a data file) + // then no conflict is possible + continue + } + + for _, child := range node.Children { + errs = append(errs, checkDocumentConflicts(child, exists, paths)...) + } } return errs diff --git a/plugins/bundle/plugin.go b/plugins/bundle/plugin.go index 53ccde387c..834e5771dc 100644 --- a/plugins/bundle/plugin.go +++ b/plugins/bundle/plugin.go @@ -615,6 +615,10 @@ func (p *Plugin) activate(ctx context.Context, name string, b *bundle.Bundle, is compiler = compiler.WithPathConflictsCheck(storage.NonEmpty(ctx, p.manager.Store, txn)). WithEnablePrintStatements(p.manager.EnablePrintStatements()) + if b.Manifest.Roots != nil { + compiler = compiler.WithPathConflictsCheckRoot(*b.Manifest.Roots) + } + var activateErr error opts := &bundle.ActivateOpts{ diff --git a/plugins/bundle/plugin_test.go b/plugins/bundle/plugin_test.go index 4650689f73..fc961f28ed 100644 --- a/plugins/bundle/plugin_test.go +++ b/plugins/bundle/plugin_test.go @@ -6574,6 +6574,194 @@ func TestGetNormalizedBundleName(t *testing.T) { } } +func TestBundleActivationWithRootOverlap(t *testing.T) { + ctx := context.Background() + plugin := getPluginWithExistingLoadedBundle( + t, + "policy-bundle", + []string{"foo/bar"}, + nil, + []testModule{ + { + Path: "foo/bar/bar.rego", + Data: `package foo.bar +result := true`, + }, + }, + ) + + bundleName := "new-bundle" + plugin.status[bundleName] = &Status{Name: bundleName, Metrics: metrics.New()} + plugin.downloaders[bundleName] = download.New(download.Config{}, plugin.manager.Client(""), bundleName) + + b := getTestBundleWithData( + []string{"foo/bar/baz"}, + []byte(`{"foo": {"bar": 1, "baz": "qux"}}`), + nil, + ) + + b.Manifest.Init() + plugin.oneShot(ctx, bundleName, download.Update{Bundle: &b, Metrics: metrics.New(), Size: snapshotBundleSize}) + + // "foo/bar" and "foo/bar/baz" overlap with each other; activation will fail + status, ok := plugin.status[bundleName] + if !ok { + t.Fatalf("Expected to find status for %s, found nil", bundleName) + } + if status.Code != errCode { + t.Fatalf(`Expected status code to be %s, found %s`, errCode, status.Code) + } + if !strings.Contains(status.Message, "detected overlapping") { + t.Fatalf(`Expected status message to contain detected overlapping roots", found %s`, status.Message) + } +} + +func TestBundleActivationWithNoManifestRootsButWithPathConflict(t *testing.T) { + ctx := context.Background() + plugin := getPluginWithExistingLoadedBundle( + t, + "policy-bundle", + []string{"foo/bar"}, + nil, + []testModule{ + { + Path: "foo/bar/bar.rego", + Data: `package foo.bar +result := true`, + }, + }, + ) + + bundleName := "new-bundle" + plugin.status[bundleName] = &Status{Name: bundleName, Metrics: metrics.New()} + plugin.downloaders[bundleName] = download.New(download.Config{}, plugin.manager.Client(""), bundleName) + + b := getTestBundleWithData( + nil, + []byte(`{"foo": {"bar": 1, "baz": "qux"}}`), + nil, + ) + + b.Manifest.Init() + plugin.oneShot(ctx, bundleName, download.Update{Bundle: &b, Metrics: metrics.New(), Size: snapshotBundleSize}) + + // new bundle has path "foo/bar" which overlaps with existing bundle with path "foo/bar"; activation will fail + status, ok := plugin.status[bundleName] + if !ok { + t.Fatalf("Expected to find status for %s, found nil", bundleName) + } + if status.Code != errCode { + t.Fatalf(`Expected status code to be %s, found %s`, errCode, status.Code) + } + if !strings.Contains(status.Message, "detected overlapping") { + t.Fatalf(`Expected status message to contain detected overlapping roots", found %s`, status.Message) + } +} + +func TestBundleActivationWithNoManifestRootsOverlap(t *testing.T) { + ctx := context.Background() + plugin := getPluginWithExistingLoadedBundle( + t, + "policy-bundle", + []string{"foo/bar"}, + nil, + []testModule{ + { + Path: "foo/bar/bar.rego", + Data: `package foo.bar +result := true`, + }, + }, + ) + + bundleName := "new-bundle" + plugin.status[bundleName] = &Status{Name: bundleName, Metrics: metrics.New()} + plugin.downloaders[bundleName] = download.New(download.Config{}, plugin.manager.Client(""), bundleName) + + b := getTestBundleWithData( + []string{"foo/baz"}, + nil, + []testModule{ + { + Path: "foo/bar/baz.rego", + Data: `package foo.baz +result := true`, + }, + }, + ) + + b.Manifest.Init() + plugin.oneShot(ctx, bundleName, download.Update{Bundle: &b, Metrics: metrics.New(), Size: snapshotBundleSize}) + + status, ok := plugin.status[bundleName] + if !ok { + t.Fatalf("Expected to find status for %s, found nil", bundleName) + } + if status.Code != "" { + t.Fatalf(`Expected status code to be empty, found %s`, status.Code) + } +} + +type testModule struct { + Path string + Data string +} + +func getTestBundleWithData(roots []string, data []byte, modules []testModule) bundle.Bundle { + b := bundle.Bundle{} + + if len(roots) > 0 { + b.Manifest = bundle.Manifest{Roots: &roots} + } + + if len(data) > 0 { + b.Data = util.MustUnmarshalJSON(data).(map[string]interface{}) + } + + for _, m := range modules { + if len(m.Data) > 0 { + b.Modules = append(b.Modules, + bundle.ModuleFile{ + Path: m.Path, + Parsed: ast.MustParseModule(m.Data), + Raw: []byte(m.Data), + }, + ) + } + } + + b.Manifest.Init() + + return b +} + +func getPluginWithExistingLoadedBundle(t *testing.T, bundleName string, roots []string, data []byte, modules []testModule) *Plugin { + ctx := context.Background() + store := inmem.NewWithOpts(inmem.OptRoundTripOnWrite(false), inmem.OptReturnASTValuesOnRead(true)) + manager := getTestManagerWithOpts(nil, store) + plugin := New(&Config{}, manager) + plugin.status[bundleName] = &Status{Name: bundleName, Metrics: metrics.New()} + plugin.downloaders[bundleName] = download.New(download.Config{}, plugin.manager.Client(""), bundleName) + + ensurePluginState(t, plugin, plugins.StateNotReady) + + b := getTestBundleWithData(roots, data, modules) + + plugin.oneShot(ctx, bundleName, download.Update{Bundle: &b, Metrics: metrics.New(), Size: snapshotBundleSize}) + + ensurePluginState(t, plugin, plugins.StateOK) + + if status, ok := plugin.status[bundleName]; !ok { + t.Fatalf("Expected to find status for %s, found nil", bundleName) + } else if status.Type != bundle.SnapshotBundleType { + t.Fatalf("expected snapshot bundle but got %v", status.Type) + } else if status.Size != snapshotBundleSize { + t.Fatalf("expected snapshot bundle size %d but got %d", snapshotBundleSize, status.Size) + } + + return plugin +} + func writeTestBundleToDisk(t *testing.T, srcDir string, signed bool) bundle.Bundle { t.Helper() From 99c92e4be3a1c1ddef3717a6c96a7d8527dd9dad Mon Sep 17 00:00:00 2001 From: Ashutosh Narkar Date: Wed, 30 Oct 2024 16:50:22 -0700 Subject: [PATCH 2/8] Prepare v0.70.0 release Signed-off-by: Ashutosh Narkar --- CHANGELOG.md | 49 +- builtin_metadata.json | 199 ++ capabilities/v0.70.0.json | 4843 +++++++++++++++++++++++++++++++++++++ version/version.go | 2 +- 4 files changed, 5091 insertions(+), 2 deletions(-) create mode 100644 capabilities/v0.70.0.json diff --git a/CHANGELOG.md b/CHANGELOG.md index b0f98ff848..7907a46994 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,54 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased +## 0.70.0 + +This release contains a mix of features, performance improvements, and bugfixes. + +### Optimized read mode for OPA's in-memory store ([#7125](https://github.com/open-policy-agent/opa/pull/7125)) + +A new optimized read mode has been added to the default in-memory store, where data written to the store is eagerly converted +to AST values (the data format used during evaluation). This removes the time spent converting raw data values to AST +during policy evaluation, thereby improving performance. + +The memory footprint of the store will increase, as processed AST values generally take up more space in memory than the +corresponding raw data values, but overall memory usage of OPA might remain more stable over time, as pre-converted data +is shared across evaluations and isn't recomputed for each evaluation, which can cause spikes in memory usage. + +This mode can be enabled for `opa run`, `opa eval`, and `opa bench` by setting the `--optimize-store-for-read-speed` flag. + +More information about this feature can be found [here](https://www.openpolicyagent.org/docs/v0.70.0/policy-performance/#storage-optimization). + +Co-authored by @johanfylling and @ashutosh-narkar. + +### Topdown and Rego +- topdown: Use new Inter-Query Value Cache for `json.match_schema` built-in function ([#7011](https://github.com/open-policy-agent/opa/issues/7011)) authored by @anderseknert reported by @lcarva +- ast: Fix location text attribute for multi-value rules with generated body ([#7128](https://github.com/open-policy-agent/opa/issues/7128)) authored by @anderseknert +- ast: Fix regression in `opa check` where a file that referenced non-provided schemas failed validation ([#7124](https://github.com/open-policy-agent/opa/pull/7124)) authored by @tjons +- test/cases/testdata: Fix bug in test by replacing unification by explicit equality check ([#7093](https://github.com/open-policy-agent/opa/pull/7093)) authored by @matajoh +- ast: Replace use of yaml.v2 library with yaml.v3. The earlier version would parse `yes`/`no` values as boolean. The usage of yaml.v2 in the parser was unintentional and now has been updated to yaml.v3 ([#7090](https://github.com/open-policy-agent/opa/issues/7090)) authored by @anderseknert + +### Runtime, Tooling, SDK +- cmd: Make `opa check` respect `--ignore` when `--bundle` flag is set ([#7136](https://github.com/open-policy-agent/opa/issues/7136)) authored by @anderseknert +- server/writer: Properly handle result encoding errors which earlier on failure would emit logs such as `superfluous call to WriteHeader()` while still returning `200` HTTP status code. Now, errors encoding the payload properly lead to `500` HTTP status code, without extra logs. Also use Header().Set() not Header().Add() to avoid duplicate content-type headers ([#7114](https://github.com/open-policy-agent/opa/pull/7114)) authored by @srenatus +- cmd: Support `file://` format for TLS key material file flags in `opa run` ([#7094](https://github.com/open-policy-agent/opa/pull/7094)) authored by @alexrohozneanu +- plugins/rest/azure: Support managed identity for App Service / Container Apps ([#7085](https://github.com/open-policy-agent/opa/issues/7085)) reported and authored by @apc-kamezaki +- debug: Fix step-over behaviour when exiting partial rules ([#7096](https://github.com/open-policy-agent/opa/pull/7096)) authored by @johanfylling +- util+plugins: Fix potential memory leaks with explicit timer cancellation ([#7089](https://github.com/open-policy-agent/opa/pull/7089)) authored by @philipaconrad + +### Docs, Website, Ecosystem +- docs: Fix OCI example with updated flag used by the ORAS CLI ([#7130](https://github.com/open-policy-agent/opa/pull/7130)) authored by @b3n3d17 +- docs: Delete Atom editor from supported editor integrations ([#7111](https://github.com/open-policy-agent/opa/pull/7111)) authored by @KaranbirSingh7 +- docs/website: Add Styra OPA ASP.NET Core SDK integration ([#7073](https://github.com/open-policy-agent/opa/pull/7073)) authored by @philipaconrad +- docs/website: Update compatibility information on the rego-cpp integration ([#7078](https://github.com/open-policy-agent/opa/pull/7078)) authored by @matajoh + +### Miscellaneous +- Dependency updates; notably: + - build(deps): bump github.com/containerd/containerd from 1.7.22 to 1.7.23 + - build(deps): bump github.com/prometheus/client_golang from 1.20.4 to 1.20.5 + - build(deps): bump golang.org/x/net from 0.29.0 to 0.30.0 + - build(deps): bump golang.org/x/time from 0.6.0 to 0.7.0 + - build(deps): bump google.golang.org/grpc from 1.67.0 to 1.67.1 ## 0.69.0 diff --git a/builtin_metadata.json b/builtin_metadata.json index 29e531ebb3..0b3ffeafd2 100644 --- a/builtin_metadata.json +++ b/builtin_metadata.json @@ -360,6 +360,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the number without its sign.", @@ -485,6 +486,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -613,6 +615,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the intersection of two sets.", @@ -739,6 +742,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -867,6 +871,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Concatenates two arrays.", @@ -944,6 +949,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the reverse of a given array.", @@ -1081,6 +1087,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a slice of a given array. If `start` is greater or equal than `stop`, `slice` is `[]`.", @@ -1209,6 +1216,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": ":=", @@ -1333,6 +1341,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Deserializes the base64 encoded input string.", @@ -1459,6 +1468,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input string into base64 encoding.", @@ -1564,6 +1574,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies the input string is base64 encoded.", @@ -1690,6 +1701,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Deserializes the base64url encoded input string.", @@ -1816,6 +1828,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input string into base64url encoding.", @@ -1919,6 +1932,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input string into base64url encoding without padding.", @@ -2045,6 +2059,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the bitwise \"AND\" of two integers.", @@ -2170,6 +2185,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a new integer with its bits shifted `s` bits to the left.", @@ -2291,6 +2307,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the bitwise negation (flip) of an integer.", @@ -2416,6 +2433,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the bitwise \"OR\" of two integers.", @@ -2541,6 +2559,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a new integer with its bits shifted `s` bits to the right.", @@ -2666,6 +2685,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the bitwise \"XOR\" (exclusive-or) of two integers.", @@ -2790,6 +2810,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -2913,6 +2934,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -3036,6 +3058,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -3159,6 +3182,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -3282,6 +3306,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -3405,6 +3430,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -3501,6 +3527,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Rounds the number _up_ to the nearest integer.", @@ -3632,6 +3659,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Joins a set or array of strings with a delimiter.", @@ -3763,6 +3791,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the search string is included in the base string", @@ -3890,6 +3919,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": " Count takes a collection or string and returns the number of elements (or characters) in it.", @@ -3938,6 +3968,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a boolean representing the result of comparing two MACs for equality without leaking timing information.", @@ -4020,6 +4051,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the MD5 HMAC of the input message using the input key.", @@ -4102,6 +4134,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the SHA1 HMAC of the input message using the input key.", @@ -4184,6 +4217,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the SHA256 HMAC of the input message using the input key.", @@ -4266,6 +4300,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the SHA512 HMAC of the input message using the input key.", @@ -4392,6 +4427,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the input string hashed with the MD5 function", @@ -4431,6 +4467,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns zero or more private keys from the given encoded string containing DER certificate data.\n\nIf the input is empty, the function will return null. The input string should be a list of one or more concatenated PEM blocks. The whole input of concatenated PEM blocks can optionally be Base64 encoded.", @@ -4557,6 +4594,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the input string hashed with the SHA1 function", @@ -4683,6 +4721,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string representing the input string hashed with the SHA256 function", @@ -4769,6 +4808,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns one or more certificates from the given string containing PEM\nor base64 encoded DER certificates after verifying the supplied certificates form a complete\ncertificate chain back to a trusted root.\n\nThe first certificate is treated as the root and the last is treated as the leaf,\nwith all others being treated as intermediates.", @@ -4803,6 +4843,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns one or more certificates from the given string containing PEM\nor base64 encoded DER certificates after verifying the supplied certificates form a complete\ncertificate chain back to a trusted root. A config option passed as the second argument can\nbe used to configure the validation options used.\n\nThe first certificate is treated as the root and the last is treated as the leaf,\nwith all others being treated as intermediates.", @@ -4915,6 +4956,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a PKCS #10 certificate signing request from the given PEM-encoded PKCS#10 certificate signing request.", @@ -5042,6 +5084,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns zero or more certificates from the given encoded string containing\nDER certificate data.\n\nIf the input is empty, the function will return null. The input string should be a list of one or more\nconcatenated PEM blocks. The whole input of concatenated PEM blocks can optionally be Base64 encoded.", @@ -5089,6 +5132,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a valid key pair", @@ -5172,6 +5216,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a JWK for signing a JWT from the given PEM-encoded RSA private key.", @@ -5304,6 +5349,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Divides the first number by the second number.", @@ -5437,6 +5483,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns true if the search string ends with the base string.", @@ -5565,6 +5612,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "=", @@ -5693,6 +5741,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "==", @@ -5791,6 +5840,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Rounds the number _down_ to the nearest integer.", @@ -5923,6 +5973,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the string representation of the number in the given base after rounding it down to an integer value.", @@ -6058,6 +6109,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Parses and matches strings against the glob notation. Not to be confused with `regex.globs_match`.", @@ -6184,6 +6236,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a string which represents a version of the pattern where all asterisks have been escaped.", @@ -6307,6 +6360,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Computes the set of reachable nodes in the graph from a set of starting nodes.", @@ -6387,6 +6441,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Computes the set of reachable paths in the graph from a set of starting nodes.", @@ -6458,6 +6513,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks that a GraphQL query is valid against a given schema. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", @@ -6529,6 +6585,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns AST objects for a given GraphQL query and schema after validating the query against the schema. Returns undefined if errors were encountered during parsing or validation. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", @@ -6600,6 +6657,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a boolean indicating success or failure alongside the parsed ASTs for a given GraphQL query and schema after validating the query against the schema. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", @@ -6667,6 +6725,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns an AST object for a GraphQL query.", @@ -6734,6 +6793,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns an AST object for a GraphQL schema.", @@ -6793,6 +6853,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks that the input is a valid GraphQL schema. The schema can be either a GraphQL string or an AST object from the other GraphQL builtin functions.", @@ -6923,6 +6984,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "\u003e", @@ -7053,6 +7115,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "\u003e=", @@ -7157,6 +7220,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Deserializes the hex-encoded input string.", @@ -7260,6 +7324,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input string using hex-encoding.", @@ -7386,6 +7451,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a HTTP response to the given HTTP request.", @@ -7517,6 +7583,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the index of a substring contained inside a string.", @@ -7597,6 +7664,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a list of all the indexes of a substring contained inside a string.", @@ -7679,6 +7747,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "in", @@ -7762,6 +7831,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "in", @@ -7839,6 +7909,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "introduced": "v0.34.0", @@ -7961,6 +8032,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the intersection of the given input sets.", @@ -8088,6 +8160,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Decodes a JSON Web Token and outputs it as an object.", @@ -8220,6 +8293,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies a JWT signature under parameterized constraints and decodes the claims if it is valid.\nSupports the following algorithms: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384 and PS512.", @@ -8357,6 +8431,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Encodes and optionally signs a JSON Web Token. Inputs are taken as objects, not encoded strings (see `io.jwt.encode_sign_raw`).", @@ -8494,6 +8569,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Encodes and optionally signs a JSON Web Token.", @@ -8626,6 +8702,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a ES256 JWT signature is valid.", @@ -8749,6 +8826,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a ES384 JWT signature is valid.", @@ -8872,6 +8950,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a ES512 JWT signature is valid.", @@ -9004,6 +9083,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a HS256 (secret) JWT signature is valid.", @@ -9127,6 +9207,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a HS384 (secret) JWT signature is valid.", @@ -9250,6 +9331,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a HS512 (secret) JWT signature is valid.", @@ -9382,6 +9464,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a PS256 JWT signature is valid.", @@ -9505,6 +9588,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a PS384 JWT signature is valid.", @@ -9628,6 +9712,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a PS512 JWT signature is valid.", @@ -9760,6 +9845,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a RS256 JWT signature is valid.", @@ -9883,6 +9969,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a RS384 JWT signature is valid.", @@ -10006,6 +10093,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies if a RS512 JWT signature is valid.", @@ -10132,6 +10220,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the input value is an array.", @@ -10258,6 +10347,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the input value is a boolean.", @@ -10384,6 +10474,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the input value is null.", @@ -10510,6 +10601,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the input value is a number.", @@ -10636,6 +10728,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns true if the input value is an object", @@ -10762,6 +10855,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the input value is a set.", @@ -10888,6 +10982,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `true` if the input value is a string.", @@ -11019,6 +11114,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Filters the object. For example: `json.filter({\"a\": {\"b\": \"x\", \"c\": \"y\"}}, [\"a/b\"])` will result in `{\"a\": {\"b\": \"x\"}}`). Paths are not filtered in-order and are deduplicated before being evaluated.", @@ -11124,6 +11220,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies the input string is a valid JSON document.", @@ -11251,6 +11348,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input term to JSON.", @@ -11284,6 +11382,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input term JSON, with additional formatting options via the `opts` parameter. `opts` accepts keys `pretty` (enable multi-line/formatted JSON), `prefix` (string to prefix lines with, default empty string) and `indent` (string to indent with, default `\\t`).", @@ -11336,6 +11435,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks that the document matches the JSON schema.", @@ -11440,6 +11540,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Patches an object according to RFC6902. For example: `json.patch({\"a\": {\"foo\": 1}}, [{\"op\": \"add\", \"path\": \"/a/bar\", \"value\": 2}])` results in `{\"a\": {\"foo\": 1, \"bar\": 2}`. The patches are applied atomically: if any of them fails, the result will be undefined. Additionally works on sets, where a value contained in the set is considered to be its path.", @@ -11567,6 +11668,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Removes paths from an object. For example: `json.remove({\"a\": {\"b\": \"x\", \"c\": \"y\"}}, [\"a/b\"])` will result in `{\"a\": {\"c\": \"y\"}}`. Paths are not removed in-order and are deduplicated before being evaluated.", @@ -11694,6 +11796,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Deserializes the input string.", @@ -11741,6 +11844,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks that the input is a valid JSON schema object. The schema can be either a JSON string or an JSON object.", @@ -11868,6 +11972,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the input string but with all characters in lower-case.", @@ -11998,6 +12103,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "\u003c", @@ -12128,6 +12234,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "\u003c=", @@ -12254,6 +12361,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the maximum value in a collection.", @@ -12380,6 +12488,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the minimum value in a collection.", @@ -12510,6 +12619,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Minus subtracts the second number from the first number or computes the difference between two sets.", @@ -12641,6 +12751,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Multiplies two numbers.", @@ -12772,6 +12883,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "infix": "!=", @@ -12902,6 +13014,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks if a CIDR or IP is contained within another CIDR. `output` is `true` if `cidr_or_ip` (e.g. `127.0.0.64/26` or `127.0.0.1`) is contained within `cidr` (e.g. `127.0.0.1/24`) and `false` otherwise. Supports both IPv4 and IPv6 notations.", @@ -13026,6 +13139,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks if collections of cidrs or ips are contained within another collection of cidrs and returns matches. This function is similar to `net.cidr_contains` except it allows callers to pass collections of CIDRs or IPs as arguments and returns the matches (as opposed to a boolean result indicating a match between two CIDRs/IPs).", @@ -13152,6 +13266,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Expands CIDR to set of hosts (e.g., `net.cidr_expand(\"192.168.0.0/30\")` generates 4 hosts: `{\"192.168.0.0\", \"192.168.0.1\", \"192.168.0.2\", \"192.168.0.3\"}`).", @@ -13282,6 +13397,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks if a CIDR intersects with another CIDR (e.g. `192.168.0.0/16` overlaps with `192.168.1.0/24`). Supports both IPv4 and IPv6 notations.", @@ -13340,6 +13456,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Parses an IPv4/IPv6 CIDR and returns a boolean indicating if the provided CIDR is valid.", @@ -13445,6 +13562,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Merges IP addresses and subnets into the smallest possible list of CIDRs (e.g., `net.cidr_merge([\"192.0.128.0/24\", \"192.0.129.0/24\"])` generates `{\"192.0.128.0/23\"}`.This function merges adjacent subnets where possible, those contained within others and also removes any duplicates.\nSupports both IPv4 and IPv6 notations. IPv6 inputs need a prefix length (e.g. \"/128\").", @@ -13573,6 +13691,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -13649,6 +13768,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the set of IP addresses (both v4 and v6) that the passed-in `name` resolves to using the standard name resolution mechanisms available.", @@ -13762,6 +13882,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns an array of numbers in the given (inclusive) range. If `a==b`, then `range == [a]`; if `a \u003e b`, then `range` is in descending order.", @@ -13807,6 +13928,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns an array of numbers in the given (inclusive) range incremented by a positive step.\n\tIf \"a==b\", then \"range == [a]\"; if \"a \u003e b\", then \"range\" is in descending order.\n\tIf the provided \"step\" is less then 1, an error will be thrown.\n\tIf \"b\" is not in the range of the provided \"step\", \"b\" won't be included in the result.\n\t", @@ -13936,6 +14058,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Filters the object by keeping only specified keys. For example: `object.filter({\"a\": {\"b\": \"x\", \"c\": \"y\"}, \"d\": \"z\"}, [\"a\"])` will result in `{\"a\": {\"b\": \"x\", \"c\": \"y\"}}`).", @@ -14073,6 +14196,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns value of an object's key if present, otherwise a default. If the supplied `key` is an `array`, then `object.get` will search through a nested object or array using each key in turn. For example: `object.get({\"a\": [{ \"b\": true }]}, [\"a\", 0, \"b\"], false)` results in `true`.", @@ -14129,6 +14253,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a set of an object's keys. For example: `object.keys({\"a\": 1, \"b\": true, \"c\": \"d\")` results in `{\"a\", \"b\", \"c\"}`.", @@ -14259,6 +14384,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Removes specified keys from an object.", @@ -14331,6 +14457,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Determines if an object `sub` is a subset of another object `super`.Object `sub` is a subset of object `super` if and only if every key in `sub` is also in `super`, **and** for all keys which `sub` and `super` share, they have the same value. This function works with objects, sets, arrays and a set of array and set.If both arguments are objects, then the operation is recursive, e.g. `{\"c\": {\"x\": {10, 15, 20}}` is a subset of `{\"a\": \"b\", \"c\": {\"x\": {10, 15, 20, 25}, \"y\": \"z\"}`. If both arguments are sets, then this function checks if every element of `sub` is a member of `super`, but does not attempt to recurse. If both arguments are arrays, then this function checks if `sub` appears contiguously in order within `super`, and also does not attempt to recurse. If `super` is array and `sub` is set, then this function checks if `super` contains every element of `sub` with no consideration of ordering, and also does not attempt to recurse.", @@ -14459,6 +14586,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Creates a new object of the asymmetric union of two objects. For example: `object.union({\"a\": 1, \"b\": 2, \"c\": {\"d\": 3}}, {\"a\": 7, \"c\": {\"d\": 4, \"e\": 5}})` will result in `{\"a\": 7, \"b\": 2, \"c\": {\"d\": 4, \"e\": 5}}`.", @@ -14533,6 +14661,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Creates a new object that is the asymmetric union of all objects merged from left to right. For example: `object.union_n([{\"a\": 1}, {\"b\": 2}, {\"a\": 3}])` will result in `{\"b\": 2, \"a\": 3}`.", @@ -14654,6 +14783,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns an object that describes the runtime environment where OPA is deployed.", @@ -14784,6 +14914,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the union of two sets.", @@ -14915,6 +15046,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Plus adds two numbers together.", @@ -14991,6 +15123,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "introduced": "v0.34.0", @@ -15112,6 +15245,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Muliplies elements of an array or set of numbers", @@ -15175,6 +15309,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Signs an HTTP request object for Amazon Web Services. Currently implements [AWS Signature Version 4 request signing](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) by the `Authorization` header method.", @@ -15263,6 +15398,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a random integer between `0` and `n` (`n` exclusive). If `n` is `0`, then `y` is always `0`. For any given argument pair (`str`, `n`), the output will be consistent throughout a query evaluation.", @@ -15391,6 +15527,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -15526,6 +15663,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns all successive matches of the expression.", @@ -15662,6 +15800,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the specified number of matches when matching the input against the pattern.", @@ -15792,6 +15931,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks if the intersection of two glob-style regular expressions matches a non-empty set of non-empty strings.\nThe set of regex symbols is limited for this builtin: only `.`, `*`, `+`, `[`, `-`, `]` and `\\` are treated as special symbols.", @@ -15900,6 +16040,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Checks if a string is a valid regular expression: the detailed syntax for patterns is defined by https://github.com/google/re2/wiki/Syntax.", @@ -16013,6 +16154,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Matches a string against a regular expression.", @@ -16083,6 +16225,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Find and replaces the text using the regular expression pattern.", @@ -16214,6 +16357,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Splits the input string by the occurrences of the given pattern.", @@ -16356,6 +16500,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Matches a string against a pattern, where there pattern may be glob-like", @@ -16418,6 +16563,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the chain of metadata for the active rule.\nOrdered starting at the active rule, going outward to the most distant node in its package ancestry.\nA chain entry is a JSON document with two members: \"path\", an array representing the path of the node; and \"annotations\", a JSON document containing the annotations declared for the node.\nThe first entry in the chain always points to the active rule, even if it has no declared annotations (in which case the \"annotations\" member is not present).", @@ -16481,6 +16627,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns annotations declared for the active rule and using the _rule_ scope.", @@ -16613,6 +16760,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Parses the input Rego string and returns an object representation of the AST.", @@ -16742,6 +16890,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the remainder for of `x` divided by `y`, for `y != 0`.", @@ -16880,6 +17029,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Replace replaces all instances of a sub-string.", @@ -17007,6 +17157,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Rounds the number to the nearest integer.", @@ -17120,6 +17271,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Compares valid SemVer formatted version strings.", @@ -17229,6 +17381,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Validates that the input is a valid SemVer string.", @@ -17357,6 +17510,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "deprecated": true, @@ -17482,6 +17636,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a sorted array.", @@ -17614,6 +17769,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Split returns an array containing elements of the input string split on a delimiter.", @@ -17746,6 +17902,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the given string, formatted.", @@ -17878,6 +18035,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns true if the search string begins with the base string.", @@ -17945,6 +18103,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns true if any of the search strings begins with any of the base strings.", @@ -18012,6 +18171,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns true if any of the search strings ends with any of the base strings.", @@ -18041,6 +18201,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the number of non-overlapping instances of a substring in a string.", @@ -18080,6 +18241,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Renders a templated string with given template variables injected. For a given templated string and key/value mapping, values will be injected into the template where they are referenced by key.\n\tFor examples of templating syntax, see https://pkg.go.dev/text/template", @@ -18212,6 +18374,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Replaces a string from a list of old, new string pairs.\nReplacements are performed in the order they appear in the target string, without overlapping matches.\nThe old string comparisons are done in argument order.", @@ -18287,6 +18450,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Reverses a given string.", @@ -18422,6 +18586,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the portion of a string for a given `offset` and a `length`. If `length \u003c 0`, `output` is the remainder of the string.", @@ -18548,6 +18713,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Sums elements of an array or set of numbers.", @@ -18681,6 +18847,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the nanoseconds since epoch after adding years, months and days to nanoseconds. Month \u0026 day values outside their usual ranges after the operation and will be normalized - for example, October 32 would become November 1. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", @@ -18808,6 +18975,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the `[hour, minute, second]` of the day for the nanoseconds since epoch.", @@ -18935,6 +19103,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the `[year, month, day]` for the nanoseconds since epoch.", @@ -19033,6 +19202,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the difference between two unix timestamps in nanoseconds (with optional timezone strings).", @@ -19084,6 +19254,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the formatted timestamp for the nanoseconds since epoch.", @@ -19205,6 +19376,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the current time since epoch in nanoseconds.", @@ -19332,6 +19504,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the duration in nanoseconds represented by a string.", @@ -19464,6 +19637,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the time in nanoseconds parsed from the string in the given format. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", @@ -19590,6 +19764,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the time in nanoseconds parsed from the string in RFC3339 format. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", @@ -19717,6 +19892,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the day of the week (Monday, Tuesday, ...) for the nanoseconds since epoch.", @@ -19843,6 +20019,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Converts a string, bool, or number value to a number: Strings are converted to numbers using `strconv.Atoi`, Boolean `false` is converted to 0 and `true` is converted to 1.", @@ -19969,6 +20146,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Emits `note` as a `Note` event in the query explanation. Query explanations show the exact expressions evaluated by OPA during policy execution. For example, `trace(\"Hello There!\")` includes `Note \"Hello There!\"` in the query explanation. To include variables in the message, use `sprintf`. For example, `person := \"Bob\"; trace(sprintf(\"Hello There! %v\", [person]))` will emit `Note \"Hello There! Bob\"` inside of the explanation.", @@ -20101,6 +20279,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `value` with all leading or trailing instances of the `cutset` characters removed.", @@ -20233,6 +20412,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `value` with all leading instances of the `cutset` characters removed.", @@ -20365,6 +20545,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `value` without the prefix. If `value` doesn't start with `prefix`, it is returned unchanged.", @@ -20497,6 +20678,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `value` with all trailing instances of the `cutset` characters removed.", @@ -20624,6 +20806,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Return the given string with all leading and trailing white space removed.", @@ -20756,6 +20939,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns `value` without the suffix. If `value` doesn't end with `suffix`, it is returned unchanged.", @@ -20882,6 +21066,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the type of its input value.", @@ -21009,6 +21194,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the union of the given input sets.", @@ -21077,6 +21263,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Converts strings like \"10G\", \"5K\", \"4M\", \"1500m\" and the like into a number.\nThis number can be a non-integer, such as 1.5, 0.22, etc. Supports standard metric decimal and\nbinary SI units (e.g., K, Ki, M, Mi, G, Gi etc.) m, K, M, G, T, P, and E are treated as decimal\nunits and Ki, Mi, Gi, Ti, Pi, and Ei are treated as binary units.\n\nNote that 'm' and 'M' are case-sensitive, to allow distinguishing between \"milli\" and \"mega\" units respectively. Other units are case-insensitive.", @@ -21204,6 +21391,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Converts strings like \"10GB\", \"5K\", \"4mb\" into an integer number of bytes.\nSupports standard byte units (e.g., KB, KiB, etc.) KB, MB, GB, and TB are treated as decimal\nunits and KiB, MiB, GiB, and TiB are treated as binary units. The bytes symbol (b/B) in the\nunit is optional and omitting it wil give the same result (e.g. Mi and MiB).", @@ -21331,6 +21519,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns the input string but with all characters in upper-case.", @@ -21457,6 +21646,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Decodes a URL-encoded input string.", @@ -21563,6 +21753,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Decodes the given URL query string into an object.", @@ -21689,6 +21880,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Encodes the input string into a URL-encoded string.", @@ -21815,6 +22007,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Encodes the given object into a URL encoded query string.", @@ -21851,6 +22044,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Parses the string value as an UUID and returns an object with the well-defined fields of the UUID if valid.", @@ -21968,6 +22162,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Returns a new UUIDv4.", @@ -22094,6 +22289,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Generates `[path, value]` tuples for all nested documents of `x` (recursively). Queries can use `walk` to traverse documents nested under `x`.", @@ -22200,6 +22396,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Verifies the input string is a valid YAML document.", @@ -22327,6 +22524,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Serializes the input term to YAML.", @@ -22454,6 +22652,7 @@ "v0.67.1", "v0.68.0", "v0.69.0", + "v0.70.0", "edge" ], "description": "Deserializes the input string.", diff --git a/capabilities/v0.70.0.json b/capabilities/v0.70.0.json new file mode 100644 index 0000000000..862a4555f9 --- /dev/null +++ b/capabilities/v0.70.0.json @@ -0,0 +1,4843 @@ +{ + "builtins": [ + { + "name": "abs", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "all", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "and", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "\u0026" + }, + { + "name": "any", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "array.concat", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.reverse", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "array.slice", + "decl": { + "args": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "assign", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": ":=" + }, + { + "name": "base64.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "base64url.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "base64url.encode_no_pad", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "bits.and", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.lsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.negate", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.or", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.rsh", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "bits.xor", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "cast_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "cast_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "cast_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "null" + }, + "type": "function" + } + }, + { + "name": "cast_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "cast_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "cast_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "ceil", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "concat", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "count", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.equal", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.md5", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha1", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.hmac.sha512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.md5", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.parse_private_keys", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.sha1", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.sha256", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_and_verify_certificates_with_options", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificate_request", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_certificates", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_keypair", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "crypto.x509.parse_rsa_private_key", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "div", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "/" + }, + { + "name": "endswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "eq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "=" + }, + { + "name": "equal", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "==" + }, + { + "name": "floor", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "format_int", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "glob.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "of": [ + { + "type": "null" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + } + ], + "type": "any" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "glob.quote_meta", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "graph.reachable", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graph.reachable_paths", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "graphql.is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "graphql.parse", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_and_verify", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_query", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.parse_schema", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "graphql.schema_is_valid", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "gt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e" + }, + { + "name": "gte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003e=" + }, + { + "name": "hex.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "hex.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "http.send", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "indexof", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "indexof_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "internal.member_2", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.member_3", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "in" + }, + { + "name": "internal.print", + "decl": { + "args": [ + { + "dynamic": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "array" + } + ], + "type": "function" + } + }, + { + "name": "intersection", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "static": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "io.jwt.decode_verify", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "array" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.encode_sign_raw", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "io.jwt.verify_es256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_es512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_hs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_ps512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs256", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs384", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "io.jwt.verify_rs512", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_array", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_boolean", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_null", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_number", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_object", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_set", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "is_string", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "json.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.marshal_with_options", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "indent", + "value": { + "type": "string" + } + }, + { + "key": "prefix", + "value": { + "type": "string" + } + }, + { + "key": "pretty", + "value": { + "type": "boolean" + } + } + ], + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "json.match_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "dynamic": { + "static": [ + { + "key": "desc", + "value": { + "type": "string" + } + }, + { + "key": "error", + "value": { + "type": "string" + } + }, + { + "key": "field", + "value": { + "type": "string" + } + }, + { + "key": "type", + "value": { + "type": "string" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "json.patch", + "decl": { + "args": [ + { + "type": "any" + }, + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "static": [ + { + "key": "op", + "value": { + "type": "string" + } + }, + { + "key": "path", + "value": { + "type": "any" + } + } + ], + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "json.verify_schema", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "boolean" + }, + { + "of": [ + { + "type": "null" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "lower", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "lt", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c" + }, + { + "name": "lte", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "\u003c=" + }, + { + "name": "max", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "min", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "minus", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": [ + { + "type": "number" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + "type": "function" + }, + "infix": "-" + }, + { + "name": "mul", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "*" + }, + { + "name": "neq", + "decl": { + "args": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + }, + "infix": "!=" + }, + { + "name": "net.cidr_contains", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_contains_matches", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "static": [ + { + "type": "any" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_expand", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_intersects", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.cidr_merge", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "of": [ + { + "type": "string" + } + ], + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "net.cidr_overlap", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "net.lookup_ip_addr", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "of": { + "type": "string" + }, + "type": "set" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "numbers.range", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "numbers.range_step", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "object.filter", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.get", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "any" + }, + { + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.keys", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "object.remove", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.subset", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "object.union_n", + "decl": { + "args": [ + { + "dynamic": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "opa.runtime", + "decl": { + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "or", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + }, + "infix": "|" + }, + { + "name": "plus", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "+" + }, + { + "name": "print", + "decl": { + "type": "function", + "variadic": { + "type": "any" + } + } + }, + { + "name": "product", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "providers.aws.sign_req", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "key": { + "type": "any" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rand.intn", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "re_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.find_all_string_submatch_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.find_n", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "number" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.globs_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "regex.replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "regex.split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "regex.template_match", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.chain", + "decl": { + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "rego.metadata.rule", + "decl": { + "result": { + "type": "any" + }, + "type": "function" + } + }, + { + "name": "rego.parse_module", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "rem", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + }, + "infix": "%" + }, + { + "name": "replace", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "round", + "decl": { + "args": [ + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.compare", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "semver.is_valid", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "set_diff", + "decl": { + "args": [ + { + "of": { + "type": "any" + }, + "type": "set" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "sort", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "of": { + "type": "any" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "split", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + "type": "function" + } + }, + { + "name": "sprintf", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "any" + }, + "type": "array" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "startswith", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_prefix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.any_suffix_match", + "decl": { + "args": [ + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "strings.count", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "strings.render_template", + "decl": { + "args": [ + { + "type": "string" + }, + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.replace_n", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "strings.reverse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "substring", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "sum", + "decl": { + "args": [ + { + "of": [ + { + "dynamic": { + "type": "number" + }, + "type": "array" + }, + { + "of": { + "type": "number" + }, + "type": "set" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.add_date", + "decl": { + "args": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.clock", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.date", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.diff", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + }, + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "static": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "type": "array" + }, + "type": "function" + } + }, + { + "name": "time.format", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "time.now_ns", + "decl": { + "result": { + "type": "number" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "time.parse_duration_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_ns", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.parse_rfc3339_ns", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "time.weekday", + "decl": { + "args": [ + { + "of": [ + { + "type": "number" + }, + { + "static": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "array" + } + ], + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "to_number", + "decl": { + "args": [ + { + "of": [ + { + "type": "null" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "type": "any" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "trace", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "trim", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_left", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_prefix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_right", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_space", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "trim_suffix", + "decl": { + "args": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "type_name", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "union", + "decl": { + "args": [ + { + "of": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "set" + } + ], + "result": { + "of": { + "type": "any" + }, + "type": "set" + }, + "type": "function" + } + }, + { + "name": "units.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "units.parse_bytes", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "number" + }, + "type": "function" + } + }, + { + "name": "upper", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.decode_object", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "dynamic": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "urlquery.encode_object", + "decl": { + "args": [ + { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "of": [ + { + "type": "string" + }, + { + "dynamic": { + "type": "string" + }, + "type": "array" + }, + { + "of": { + "type": "string" + }, + "type": "set" + } + ], + "type": "any" + } + }, + "type": "object" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "uuid.parse", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "dynamic": { + "key": { + "type": "string" + }, + "value": { + "type": "any" + } + }, + "type": "object" + }, + "type": "function" + } + }, + { + "name": "uuid.rfc4122", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "string" + }, + "type": "function" + }, + "nondeterministic": true + }, + { + "name": "walk", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "static": [ + { + "dynamic": { + "type": "any" + }, + "type": "array" + }, + { + "type": "any" + } + ], + "type": "array" + }, + "type": "function" + }, + "relation": true + }, + { + "name": "yaml.is_valid", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "boolean" + }, + "type": "function" + } + }, + { + "name": "yaml.marshal", + "decl": { + "args": [ + { + "type": "any" + } + ], + "result": { + "type": "string" + }, + "type": "function" + } + }, + { + "name": "yaml.unmarshal", + "decl": { + "args": [ + { + "type": "string" + } + ], + "result": { + "type": "any" + }, + "type": "function" + } + } + ], + "future_keywords": [ + "contains", + "every", + "if", + "in" + ], + "wasm_abi_versions": [ + { + "version": 1, + "minor_version": 1 + }, + { + "version": 1, + "minor_version": 2 + } + ], + "features": [ + "rule_head_ref_string_prefixes", + "rule_head_refs", + "rego_v1_import" + ] +} diff --git a/version/version.go b/version/version.go index 0d5f52d3db..862556bce0 100644 --- a/version/version.go +++ b/version/version.go @@ -11,7 +11,7 @@ import ( ) // Version is the canonical version of OPA. -var Version = "0.70.0-dev" +var Version = "0.70.0" // GoVersion is the version of Go this was built with var GoVersion = runtime.Version() From fb7e88970c4584190e354a26d5eceee29074962f Mon Sep 17 00:00:00 2001 From: Ashutosh Narkar Date: Thu, 31 Oct 2024 12:45:45 -0700 Subject: [PATCH 3/8] Prepare v0.71.0 development Signed-off-by: Ashutosh Narkar --- CHANGELOG.md | 2 ++ version/version.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7907a46994..f9db6335fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + ## 0.70.0 This release contains a mix of features, performance improvements, and bugfixes. diff --git a/version/version.go b/version/version.go index 862556bce0..3f1e4329cd 100644 --- a/version/version.go +++ b/version/version.go @@ -11,7 +11,7 @@ import ( ) // Version is the canonical version of OPA. -var Version = "0.70.0" +var Version = "0.71.0-dev" // GoVersion is the version of Go this was built with var GoVersion = runtime.Version() From 9710eefedf9ad20b83df9191410ec2dfe4254856 Mon Sep 17 00:00:00 2001 From: Anders Eknert Date: Mon, 4 Nov 2024 14:00:23 +0100 Subject: [PATCH 4/8] Add description to all built-in function args and return values (#7153) Fixes #7151 Signed-off-by: Anders Eknert --- ast/builtins.go | 265 ++++++++++++++++++++++-------------------- ast/builtins_test.go | 34 +++++- builtin_metadata.json | 122 ++++++++++++++++++- 3 files changed, 294 insertions(+), 127 deletions(-) diff --git a/ast/builtins.go b/ast/builtins.go index f54d91d317..4db7352933 100644 --- a/ast/builtins.go +++ b/ast/builtins.go @@ -563,7 +563,7 @@ var Abs = &Builtin{ Description: "Returns the number without its sign.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), + types.Named("x", types.N).Description("the number to take the absolute value of"), ), types.Named("y", types.N).Description("the absolute value of `x`"), ), @@ -593,10 +593,10 @@ var BitsOr = &Builtin{ Description: "Returns the bitwise \"OR\" of two integers.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("y", types.N), + types.Named("x", types.N).Description("the first integer"), + types.Named("y", types.N).Description("the second integer"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise OR of `x` and `y`"), ), } @@ -605,10 +605,10 @@ var BitsAnd = &Builtin{ Description: "Returns the bitwise \"AND\" of two integers.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("y", types.N), + types.Named("x", types.N).Description("the first integer"), + types.Named("y", types.N).Description("the second integer"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise AND of `x` and `y`"), ), } @@ -617,9 +617,9 @@ var BitsNegate = &Builtin{ Description: "Returns the bitwise negation (flip) of an integer.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), + types.Named("x", types.N).Description("the integer to negate"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise negation of `x`"), ), } @@ -628,10 +628,10 @@ var BitsXOr = &Builtin{ Description: "Returns the bitwise \"XOR\" (exclusive-or) of two integers.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("y", types.N), + types.Named("x", types.N).Description("the first integer"), + types.Named("y", types.N).Description("the second integer"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the bitwise XOR of `x` and `y`"), ), } @@ -640,10 +640,10 @@ var BitsShiftLeft = &Builtin{ Description: "Returns a new integer with its bits shifted `s` bits to the left.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("s", types.N), + types.Named("x", types.N).Description("the integer to shift"), + types.Named("s", types.N).Description("the number of bits to shift"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the result of shifting `x` `s` bits to the left"), ), } @@ -652,10 +652,10 @@ var BitsShiftRight = &Builtin{ Description: "Returns a new integer with its bits shifted `s` bits to the right.", Decl: types.NewFunction( types.Args( - types.Named("x", types.N), - types.Named("s", types.N), + types.Named("x", types.N).Description("the integer to shift"), + types.Named("s", types.N).Description("the number of bits to shift"), ), - types.Named("z", types.N), + types.Named("z", types.N).Description("the result of shifting `x` `s` bits to the right"), ), } @@ -671,8 +671,8 @@ var And = &Builtin{ Description: "Returns the intersection of two sets.", Decl: types.NewFunction( types.Args( - types.Named("x", types.NewSet(types.A)), - types.Named("y", types.NewSet(types.A)), + types.Named("x", types.NewSet(types.A)).Description("the first set"), + types.Named("y", types.NewSet(types.A)).Description("the second set"), ), types.Named("z", types.NewSet(types.A)).Description("the intersection of `x` and `y`"), ), @@ -749,7 +749,7 @@ var Sum = &Builtin{ types.Named("collection", types.NewAny( types.NewSet(types.N), types.NewArray(nil, types.N), - )), + )).Description("the set or array of numbers to sum"), ), types.Named("n", types.N).Description("the sum of all elements"), ), @@ -758,13 +758,13 @@ var Sum = &Builtin{ var Product = &Builtin{ Name: "product", - Description: "Muliplies elements of an array or set of numbers", + Description: "Multiplies elements of an array or set of numbers", Decl: types.NewFunction( types.Args( types.Named("collection", types.NewAny( types.NewSet(types.N), types.NewArray(nil, types.N), - )), + )).Description("the set or array of numbers to multiply"), ), types.Named("n", types.N).Description("the product of all elements"), ), @@ -779,7 +779,7 @@ var Max = &Builtin{ types.Named("collection", types.NewAny( types.NewSet(types.A), types.NewArray(nil, types.A), - )), + )).Description("the set or array to be searched"), ), types.Named("n", types.A).Description("the maximum of all elements"), ), @@ -794,7 +794,7 @@ var Min = &Builtin{ types.Named("collection", types.NewAny( types.NewSet(types.A), types.NewArray(nil, types.A), - )), + )).Description("the set or array to be searched"), ), types.Named("n", types.A).Description("the minimum of all elements"), ), @@ -829,8 +829,8 @@ var ArrayConcat = &Builtin{ Description: "Concatenates two arrays.", Decl: types.NewFunction( types.Args( - types.Named("x", types.NewArray(nil, types.A)), - types.Named("y", types.NewArray(nil, types.A)), + types.Named("x", types.NewArray(nil, types.A)).Description("the first array"), + types.Named("y", types.NewArray(nil, types.A)).Description("the second array"), ), types.Named("z", types.NewArray(nil, types.A)).Description("the concatenation of `x` and `y`"), ), @@ -875,9 +875,9 @@ var ToNumber = &Builtin{ types.S, types.B, types.NewNull(), - )), + )).Description("value to convert"), ), - types.Named("num", types.N), + types.Named("num", types.N).Description("the numeric representation of `x`"), ), Categories: conversions, } @@ -894,7 +894,7 @@ var RegexMatch = &Builtin{ types.Named("pattern", types.S).Description("regular expression"), types.Named("value", types.S).Description("value to match against `pattern`"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if `value` matches `pattern`"), ), } @@ -905,7 +905,7 @@ var RegexIsValid = &Builtin{ types.Args( types.Named("pattern", types.S).Description("regular expression"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if `pattern` is a valid regular expression"), ), } @@ -918,7 +918,7 @@ var RegexFindAllStringSubmatch = &Builtin{ types.Named("value", types.S).Description("string to match"), types.Named("number", types.N).Description("number of matches to return; `-1` means all matches"), ), - types.Named("output", types.NewArray(nil, types.NewArray(nil, types.S))), + types.Named("output", types.NewArray(nil, types.NewArray(nil, types.S))).Description("array of all matches"), ), } @@ -932,7 +932,7 @@ var RegexTemplateMatch = &Builtin{ types.Named("delimiter_start", types.S).Description("start delimiter of the regular expression in `template`"), types.Named("delimiter_end", types.S).Description("end delimiter of the regular expression in `template`"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if `value` matches the `template`"), ), } // TODO(sr): example:`regex.template_match("urn:foo:{.*}", "urn:foo:bar:baz", "{", "}")`` returns ``true``. @@ -974,10 +974,10 @@ var GlobsMatch = &Builtin{ The set of regex symbols is limited for this builtin: only ` + "`.`, `*`, `+`, `[`, `-`, `]` and `\\` are treated as special symbols.", Decl: types.NewFunction( types.Args( - types.Named("glob1", types.S), - types.Named("glob2", types.S), + types.Named("glob1", types.S).Description("first glob-style regular expression"), + types.Named("glob2", types.S).Description("second glob-style regular expression"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("true if the intersection of `glob1` and `glob2` matches a non-empty set of non-empty strings"), ), } @@ -1033,13 +1033,13 @@ var Concat = &Builtin{ Description: "Joins a set or array of strings with a delimiter.", Decl: types.NewFunction( types.Args( - types.Named("delimiter", types.S), + types.Named("delimiter", types.S).Description("string to use as a delimiter"), types.Named("collection", types.NewAny( types.NewSet(types.S), types.NewArray(nil, types.S), )).Description("strings to join"), ), - types.Named("output", types.S), + types.Named("output", types.S).Description("the joined string"), ), Categories: stringsCat, } @@ -1088,7 +1088,7 @@ var Substring = &Builtin{ Description: "Returns the portion of a string for a given `offset` and a `length`. If `length < 0`, `output` is the remainder of the string.", Decl: types.NewFunction( types.Args( - types.Named("value", types.S), + types.Named("value", types.S).Description("string to extract substring from"), types.Named("offset", types.N).Description("offset, must be positive"), types.Named("length", types.N).Description("length of the substring starting from `offset`"), ), @@ -1215,7 +1215,7 @@ The old string comparisons are done in argument order.`, ).Description("replacement pairs"), types.Named("value", types.S).Description("string to replace substring matches in"), ), - types.Named("output", types.S), + types.Named("output", types.S).Description("string with replaced substrings"), ), } @@ -1228,7 +1228,7 @@ var RegexReplace = &Builtin{ types.Named("pattern", types.S).Description("regex pattern to be applied"), types.Named("value", types.S).Description("regex value"), ), - types.Named("output", types.S), + types.Named("output", types.S).Description("string with replaced substrings"), ), } @@ -1327,9 +1327,9 @@ var StringReverse = &Builtin{ Description: "Reverses a given string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to reverse"), ), - types.Named("y", types.S), + types.Named("y", types.S).Description("reversed string"), ), Categories: stringsCat, } @@ -1359,8 +1359,8 @@ var RandIntn = &Builtin{ Description: "Returns a random integer between `0` and `n` (`n` exclusive). If `n` is `0`, then `y` is always `0`. For any given argument pair (`str`, `n`), the output will be consistent throughout a query evaluation.", Decl: types.NewFunction( types.Args( - types.Named("str", types.S), - types.Named("n", types.N), + types.Named("str", types.S).Description("seed string for the random number"), + types.Named("n", types.N).Description("upper bound of the random number (exclusive)"), ), types.Named("y", types.N).Description("random integer in the range `[0, abs(n))`"), ), @@ -1373,8 +1373,8 @@ var NumbersRange = &Builtin{ Description: "Returns an array of numbers in the given (inclusive) range. If `a==b`, then `range == [a]`; if `a > b`, then `range` is in descending order.", Decl: types.NewFunction( types.Args( - types.Named("a", types.N), - types.Named("b", types.N), + types.Named("a", types.N).Description("the start of the range"), + types.Named("b", types.N).Description("the end of the range (inclusive)"), ), types.Named("range", types.NewArray(nil, types.N)).Description("the range between `a` and `b`"), ), @@ -1389,9 +1389,9 @@ var NumbersRangeStep = &Builtin{ `, Decl: types.NewFunction( types.Args( - types.Named("a", types.N), - types.Named("b", types.N), - types.Named("step", types.N), + types.Named("a", types.N).Description("the start of the range"), + types.Named("b", types.N).Description("the end of the range (inclusive)"), + types.Named("step", types.N).Description("the step between numbers in the range"), ), types.Named("range", types.NewArray(nil, types.N)).Description("the range between `a` and `b` in `step` increments"), ), @@ -1443,7 +1443,7 @@ var UUIDRFC4122 = &Builtin{ Description: "Returns a new UUIDv4.", Decl: types.NewFunction( types.Args( - types.Named("k", types.S), + types.Named("k", types.S).Description("seed string"), ), types.Named("output", types.S).Description("a version 4 UUID; for any given `k`, the output will be consistent throughout a query evaluation"), ), @@ -1456,7 +1456,7 @@ var UUIDParse = &Builtin{ Categories: nil, Decl: types.NewFunction( types.Args( - types.Named("uuid", types.S), + types.Named("uuid", types.S).Description("UUID string to parse"), ), types.Named("result", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))).Description("Properties of UUID if valid (version, variant, etc). Undefined otherwise."), ), @@ -1479,7 +1479,7 @@ var JSONFilter = &Builtin{ types.Named("object", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("object to filter"), types.Named("paths", types.NewAny( types.NewArray( nil, @@ -1517,7 +1517,7 @@ var JSONRemove = &Builtin{ types.Named("object", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("object to remove paths from"), types.Named("paths", types.NewAny( types.NewArray( nil, @@ -1553,7 +1553,7 @@ var JSONPatch = &Builtin{ "Additionally works on sets, where a value contained in the set is considered to be its path.", Decl: types.NewFunction( types.Args( - types.Named("object", types.A), // TODO(sr): types.A? + types.Named("object", types.A).Description("the object to patch"), // TODO(sr): types.A? types.Named("patches", types.NewArray( nil, types.NewObject( @@ -1563,7 +1563,7 @@ var JSONPatch = &Builtin{ }, types.NewDynamicProperty(types.A, types.A), ), - )), + )).Description("the JSON patches to apply"), ), types.Named("output", types.A).Description("result obtained after consecutively applying all patch operations in `patches`"), ), @@ -1589,15 +1589,13 @@ var ObjectSubset = &Builtin{ types.Named("super", types.NewAny(types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - ), - types.NewSet(types.A), + ), types.NewSet(types.A), types.NewArray(nil, types.A), )).Description("object to test if sub is a subset of"), types.Named("sub", types.NewAny(types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - ), - types.NewSet(types.A), + ), types.NewSet(types.A), types.NewArray(nil, types.A), )).Description("object to test if super is a superset of"), ), @@ -1614,11 +1612,11 @@ var ObjectUnion = &Builtin{ types.Named("a", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("left-hand object"), types.Named("b", types.NewObject( nil, types.NewDynamicProperty(types.A, types.A), - )), + )).Description("right-hand object"), ), types.Named("output", types.A).Description("a new object which is the result of an asymmetric recursive union of two objects where conflicts are resolved by choosing the key from the right-hand object `b`"), ), // TODO(sr): types.A? ^^^^^^^ (also below) @@ -1633,7 +1631,7 @@ var ObjectUnionN = &Builtin{ types.Named("objects", types.NewArray( nil, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), - )), + )).Description("list of objects to merge"), ), types.Named("output", types.A).Description("asymmetric recursive union of all objects in `objects`, merged from left to right, where conflicts are resolved by choosing the key from the right-hand object"), ), @@ -1672,7 +1670,7 @@ var ObjectFilter = &Builtin{ types.NewArray(nil, types.A), types.NewSet(types.A), types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), - )), + )).Description("keys to keep in `object`"), ), types.Named("filtered", types.A).Description("remaining data from `object` with only keys specified in `keys`"), ), @@ -1772,7 +1770,7 @@ var Base64Encode = &Builtin{ Description: "Serializes the input string into base64 encoding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("base64 serialization of `x`"), ), @@ -1784,7 +1782,7 @@ var Base64Decode = &Builtin{ Description: "Deserializes the base64 encoded input string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to decode"), ), types.Named("y", types.S).Description("base64 deserialization of `x`"), ), @@ -1796,7 +1794,7 @@ var Base64IsValid = &Builtin{ Description: "Verifies the input string is base64 encoded.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to check"), ), types.Named("result", types.B).Description("`true` if `x` is valid base64 encoded value, `false` otherwise"), ), @@ -1808,7 +1806,7 @@ var Base64UrlEncode = &Builtin{ Description: "Serializes the input string into base64url encoding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("base64url serialization of `x`"), ), @@ -1820,7 +1818,7 @@ var Base64UrlEncodeNoPad = &Builtin{ Description: "Serializes the input string into base64url encoding without padding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("base64url serialization of `x`"), ), @@ -1832,7 +1830,7 @@ var Base64UrlDecode = &Builtin{ Description: "Deserializes the base64url encoded input string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to decode"), ), types.Named("y", types.S).Description("base64url deserialization of `x`"), ), @@ -1844,7 +1842,7 @@ var URLQueryDecode = &Builtin{ Description: "Decodes a URL-encoded input string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("the URL-encoded string"), ), types.Named("y", types.S).Description("URL-encoding deserialization of `x`"), ), @@ -1856,7 +1854,7 @@ var URLQueryEncode = &Builtin{ Description: "Encodes the input string into a URL-encoded string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("the string to encode"), ), types.Named("y", types.S).Description("URL-encoding serialization of `x`"), ), @@ -1875,7 +1873,11 @@ var URLQueryEncodeObject = &Builtin{ types.NewAny( types.S, types.NewArray(nil, types.S), - types.NewSet(types.S)))))), + types.NewSet(types.S)), + ), + ), + ).Description("the object to encode"), + ), types.Named("y", types.S).Description("the URL-encoded serialization of `object`"), ), Categories: encoding, @@ -1937,7 +1939,7 @@ var HexEncode = &Builtin{ Description: "Serializes the input string using hex-encoding.", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("string to encode"), ), types.Named("y", types.S).Description("serialization of `x` using hex-encoding"), ), @@ -2219,7 +2221,7 @@ var ParseRFC3339Nanos = &Builtin{ Description: "Returns the time in nanoseconds parsed from the string in RFC3339 format. `undefined` if the result would be outside the valid time range that can fit within an `int64`.", Decl: types.NewFunction( types.Args( - types.Named("value", types.S), + types.Named("value", types.S).Description("input string to parse in RFC3339 format"), ), types.Named("ns", types.N).Description("`value` in nanoseconds since epoch"), ), @@ -2300,9 +2302,9 @@ var AddDate = &Builtin{ Decl: types.NewFunction( types.Args( types.Named("ns", types.N).Description("nanoseconds since the epoch"), - types.Named("years", types.N), - types.Named("months", types.N), - types.Named("days", types.N), + types.Named("years", types.N).Description("number of years to add"), + types.Named("months", types.N).Description("number of months to add"), + types.Named("days", types.N).Description("number of days to add"), ), types.Named("output", types.N).Description("nanoseconds since the epoch representing the input time, with years, months and days added"), ), @@ -2316,11 +2318,11 @@ var Diff = &Builtin{ types.Named("ns1", types.NewAny( types.N, types.NewArray([]types.Type{types.N, types.S}, nil), - )), + )).Description("nanoseconds since the epoch; or a two-element array of the nanoseconds, and a timezone string"), types.Named("ns2", types.NewAny( types.N, types.NewArray([]types.Type{types.N, types.S}, nil), - )), + )).Description("nanoseconds since the epoch; or a two-element array of the nanoseconds, and a timezone string"), ), types.Named("output", types.NewArray([]types.Type{types.N, types.N, types.N, types.N, types.N, types.N}, nil)).Description("difference between `ns1` and `ns2` (in their supplied timezones, if supplied, or UTC) as array of numbers: `[years, months, days, hours, minutes, seconds]`"), ), @@ -2440,7 +2442,7 @@ var CryptoMd5 = &Builtin{ Description: "Returns a string representing the input string hashed with the MD5 function", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("input string"), ), types.Named("y", types.S).Description("MD5-hash of `x`"), ), @@ -2451,7 +2453,7 @@ var CryptoSha1 = &Builtin{ Description: "Returns a string representing the input string hashed with the SHA1 function", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("input string"), ), types.Named("y", types.S).Description("SHA1-hash of `x`"), ), @@ -2462,7 +2464,7 @@ var CryptoSha256 = &Builtin{ Description: "Returns a string representing the input string hashed with the SHA256 function", Decl: types.NewFunction( types.Args( - types.Named("x", types.S), + types.Named("x", types.S).Description("input string"), ), types.Named("y", types.S).Description("SHA256-hash of `x`"), ), @@ -2539,7 +2541,7 @@ var WalkBuiltin = &Builtin{ Description: "Generates `[path, value]` tuples for all nested documents of `x` (recursively). Queries can use `walk` to traverse documents nested under `x`.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("value to walk"), ), types.Named("output", types.NewArray( []types.Type{ @@ -2602,7 +2604,7 @@ var IsNumber = &Builtin{ Description: "Returns `true` if the input value is a number.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is a number, `false` otherwise."), ), @@ -2614,7 +2616,7 @@ var IsString = &Builtin{ Description: "Returns `true` if the input value is a string.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is a string, `false` otherwise."), ), @@ -2626,7 +2628,7 @@ var IsBoolean = &Builtin{ Description: "Returns `true` if the input value is a boolean.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is an boolean, `false` otherwise."), ), @@ -2638,7 +2640,7 @@ var IsArray = &Builtin{ Description: "Returns `true` if the input value is an array.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is an array, `false` otherwise."), ), @@ -2650,7 +2652,7 @@ var IsSet = &Builtin{ Description: "Returns `true` if the input value is a set.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is a set, `false` otherwise."), ), @@ -2662,7 +2664,7 @@ var IsObject = &Builtin{ Description: "Returns true if the input value is an object", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is an object, `false` otherwise."), ), @@ -2674,7 +2676,7 @@ var IsNull = &Builtin{ Description: "Returns `true` if the input value is null.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("result", types.B).Description("`true` if `x` is null, `false` otherwise."), ), @@ -2691,7 +2693,7 @@ var TypeNameBuiltin = &Builtin{ Description: "Returns the type of its input value.", Decl: types.NewFunction( types.Args( - types.Named("x", types.A), + types.Named("x", types.A).Description("input value"), ), types.Named("type", types.S).Description(`one of "null", "boolean", "number", "string", "array", "object", "set"`), ), @@ -2708,9 +2710,11 @@ var HTTPSend = &Builtin{ Description: "Returns a HTTP response to the given HTTP request.", Decl: types.NewFunction( types.Args( - types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), + types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("the HTTP request object"), ), - types.Named("response", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))), + types.Named("response", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))). + Description("the HTTP response object"), ), Nondeterministic: true, } @@ -2725,8 +2729,10 @@ var GraphQLParse = &Builtin{ Description: "Returns AST objects for a given GraphQL query and schema after validating the query against the schema. Returns undefined if errors were encountered during parsing or validation. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL query"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL schema"), ), types.Named("output", types.NewArray([]types.Type{ types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)), @@ -2741,8 +2747,10 @@ var GraphQLParseAndVerify = &Builtin{ Description: "Returns a boolean indicating success or failure alongside the parsed ASTs for a given GraphQL query and schema after validating the query against the schema. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL query"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL schema"), ), types.Named("output", types.NewArray([]types.Type{ types.B, @@ -2759,7 +2767,7 @@ var GraphQLParseQuery = &Builtin{ Description: "Returns an AST object for a GraphQL query.", Decl: types.NewFunction( types.Args( - types.Named("query", types.S), + types.Named("query", types.S).Description("GraphQL query string"), ), types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))).Description("AST object for the GraphQL query."), ), @@ -2772,7 +2780,7 @@ var GraphQLParseSchema = &Builtin{ Description: "Returns an AST object for a GraphQL schema.", Decl: types.NewFunction( types.Args( - types.Named("schema", types.S), + types.Named("schema", types.S).Description("GraphQL schema string"), ), types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))).Description("AST object for the GraphQL schema."), ), @@ -2785,8 +2793,10 @@ var GraphQLIsValid = &Builtin{ Description: "Checks that a GraphQL query is valid against a given schema. The query and/or schema can be either GraphQL strings or AST objects from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("query", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL query"), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the GraphQL schema"), ), types.Named("output", types.B).Description("`true` if the query is valid under the given schema. `false` otherwise."), ), @@ -2799,7 +2809,8 @@ var GraphQLSchemaIsValid = &Builtin{ Description: "Checks that the input is a valid GraphQL schema. The schema can be either a GraphQL string or an AST object from the other GraphQL builtin functions.", Decl: types.NewFunction( types.Args( - types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))), + types.Named("schema", types.NewAny(types.S, types.NewObject(nil, types.NewDynamicProperty(types.A, types.A)))). + Description("the schema to verify"), ), types.Named("output", types.B).Description("`true` if the schema is a valid GraphQL schema. `false` otherwise."), ), @@ -2869,11 +2880,14 @@ var ProvidersAWSSignReqObj = &Builtin{ Description: "Signs an HTTP request object for Amazon Web Services. Currently implements [AWS Signature Version 4 request signing](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) by the `Authorization` header method.", Decl: types.NewFunction( types.Args( - types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), - types.Named("aws_config", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), - types.Named("time_ns", types.N), + types.Named("request", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("HTTP request object"), + types.Named("aws_config", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("AWS configuration object"), + types.Named("time_ns", types.N).Description("nanoseconds since the epoch"), ), - types.Named("signed_request", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))), + types.Named("signed_request", types.NewObject(nil, types.NewDynamicProperty(types.A, types.A))). + Description("HTTP request object with `Authorization` header"), ), Categories: providersAWSCat, } @@ -2890,7 +2904,8 @@ var RegoParseModule = &Builtin{ types.Named("filename", types.S).Description("file name to attach to AST nodes' locations"), types.Named("rego", types.S).Description("Rego module"), ), - types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))), // TODO(tsandall): import AST schema + types.Named("output", types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))). + Description("AST object for the Rego module"), ), } @@ -2958,12 +2973,12 @@ var GlobMatch = &Builtin{ Description: "Parses and matches strings against the glob notation. Not to be confused with `regex.globs_match`.", Decl: types.NewFunction( types.Args( - types.Named("pattern", types.S), + types.Named("pattern", types.S).Description("glob pattern"), types.Named("delimiters", types.NewAny( types.NewArray(nil, types.S), types.NewNull(), )).Description("glob pattern delimiters, e.g. `[\".\", \":\"]`, defaults to `[\".\"]` if unset. If `delimiters` is `null`, glob match without delimiter."), - types.Named("match", types.S), + types.Named("match", types.S).Description("string to match against `pattern`"), ), types.Named("result", types.B).Description("true if `match` can be found in `pattern` which is separated by `delimiters`"), ), @@ -2974,7 +2989,7 @@ var GlobQuoteMeta = &Builtin{ Description: "Returns a string which represents a version of the pattern where all asterisks have been escaped.", Decl: types.NewFunction( types.Args( - types.Named("pattern", types.S), + types.Named("pattern", types.S).Description("glob pattern"), ), types.Named("output", types.S).Description("the escaped string of `pattern`"), ), @@ -2990,10 +3005,10 @@ var NetCIDRIntersects = &Builtin{ Description: "Checks if a CIDR intersects with another CIDR (e.g. `192.168.0.0/16` overlaps with `192.168.1.0/24`). Supports both IPv4 and IPv6 notations.", Decl: types.NewFunction( types.Args( - types.Named("cidr1", types.S), - types.Named("cidr2", types.S), + types.Named("cidr1", types.S).Description("first CIDR"), + types.Named("cidr2", types.S).Description("second CIDR"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("`true` if `cidr1` intersects with `cidr2`"), ), } @@ -3002,7 +3017,7 @@ var NetCIDRExpand = &Builtin{ Description: "Expands CIDR to set of hosts (e.g., `net.cidr_expand(\"192.168.0.0/30\")` generates 4 hosts: `{\"192.168.0.0\", \"192.168.0.1\", \"192.168.0.2\", \"192.168.0.3\"}`).", Decl: types.NewFunction( types.Args( - types.Named("cidr", types.S), + types.Named("cidr", types.S).Description("CIDR to expand"), ), types.Named("hosts", types.NewSet(types.S)).Description("set of IP addresses the CIDR `cidr` expands to"), ), @@ -3013,10 +3028,10 @@ var NetCIDRContains = &Builtin{ Description: "Checks if a CIDR or IP is contained within another CIDR. `output` is `true` if `cidr_or_ip` (e.g. `127.0.0.64/26` or `127.0.0.1`) is contained within `cidr` (e.g. `127.0.0.1/24`) and `false` otherwise. Supports both IPv4 and IPv6 notations.", Decl: types.NewFunction( types.Args( - types.Named("cidr", types.S), - types.Named("cidr_or_ip", types.S), + types.Named("cidr", types.S).Description("CIDR to check against"), + types.Named("cidr_or_ip", types.S).Description("CIDR or IP to check"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("`true` if `cidr_or_ip` is contained within `cidr`"), ), } @@ -3026,8 +3041,8 @@ var NetCIDRContainsMatches = &Builtin{ "This function is similar to `net.cidr_contains` except it allows callers to pass collections of CIDRs or IPs as arguments and returns the matches (as opposed to a boolean result indicating a match between two CIDRs/IPs).", Decl: types.NewFunction( types.Args( - types.Named("cidrs", netCidrContainsMatchesOperandType), - types.Named("cidrs_or_ips", netCidrContainsMatchesOperandType), + types.Named("cidrs", netCidrContainsMatchesOperandType).Description("CIDRs to check against"), + types.Named("cidrs_or_ips", netCidrContainsMatchesOperandType).Description("CIDRs or IPs to check"), ), types.Named("output", types.NewSet(types.NewArray([]types.Type{types.A, types.A}, nil))).Description("tuples identifying matches where `cidrs_or_ips` are contained within `cidrs`"), ), @@ -3054,9 +3069,9 @@ var NetCIDRIsValid = &Builtin{ Description: "Parses an IPv4/IPv6 CIDR and returns a boolean indicating if the provided CIDR is valid.", Decl: types.NewFunction( types.Args( - types.Named("cidr", types.S), + types.Named("cidr", types.S).Description("CIDR to validate"), ), - types.Named("result", types.B), + types.Named("result", types.B).Description("`true` if `cidr` is a valid CIDR"), ), } @@ -3101,7 +3116,7 @@ var SemVerIsValid = &Builtin{ Description: "Validates that the input is a valid SemVer string.", Decl: types.NewFunction( types.Args( - types.Named("vsn", types.A), + types.Named("vsn", types.A).Description("input to validate"), ), types.Named("result", types.B).Description("`true` if `vsn` is a valid SemVer; `false` otherwise"), ), @@ -3112,8 +3127,8 @@ var SemVerCompare = &Builtin{ Description: "Compares valid SemVer formatted version strings.", Decl: types.NewFunction( types.Args( - types.Named("a", types.S), - types.Named("b", types.S), + types.Named("a", types.S).Description("first version string"), + types.Named("b", types.S).Description("second version string"), ), types.Named("result", types.N).Description("`-1` if `a < b`; `1` if `a > b`; `0` if `a == b`"), ), diff --git a/ast/builtins_test.go b/ast/builtins_test.go index 68a0b0843b..16ce596782 100644 --- a/ast/builtins_test.go +++ b/ast/builtins_test.go @@ -6,13 +6,13 @@ package ast import ( "encoding/json" + "fmt" "testing" "github.com/open-policy-agent/opa/types" ) func TestBuiltinDeclRoundtrip(t *testing.T) { - bs, err := json.Marshal(Plus) if err != nil { t.Fatal(err) @@ -28,3 +28,35 @@ func TestBuiltinDeclRoundtrip(t *testing.T) { t.Fatal("expected:", Plus, "got:", cpy) } } + +func TestAllBuiltinsHaveDescribedArguments(t *testing.T) { + for _, b := range Builtins { + if b.deprecated || b.Infix != "" || b.Name == "print" || b.Name == "internal.print" { + continue + } + + t.Run(b.Name, func(t *testing.T) { + namedAndDescribed(t, "arg", b.Decl.NamedFuncArgs().Args...) + namedAndDescribed(t, "res", b.Decl.NamedResult()) + }) + } +} + +func namedAndDescribed(t *testing.T, typ string, args ...types.Type) { + t.Helper() + + for i, arg := range args { + t.Run(fmt.Sprintf("%s=%d", typ, i), func(t *testing.T) { + typ, ok := arg.(*types.NamedType) + if !ok { + t.Fatalf("expected arg to be %T, got %T", typ, arg) + } + if typ.Name == "" { + t.Error("empty name") + } + if typ.Descr == "" { + t.Error("empty description") + } + }) + } +} diff --git a/builtin_metadata.json b/builtin_metadata.json index 0b3ffeafd2..9163e169d4 100644 --- a/builtin_metadata.json +++ b/builtin_metadata.json @@ -248,6 +248,7 @@ "abs": { "args": [ { + "description": "the number to take the absolute value of", "name": "x", "type": "number" } @@ -499,10 +500,12 @@ "and": { "args": [ { + "description": "the first set", "name": "x", "type": "set[any]" }, { + "description": "the second set", "name": "y", "type": "set[any]" } @@ -755,10 +758,12 @@ "array.concat": { "args": [ { + "description": "the first array", "name": "x", "type": "array[any]" }, { + "description": "the second array", "name": "y", "type": "array[any]" } @@ -1229,6 +1234,7 @@ "base64.decode": { "args": [ { + "description": "string to decode", "name": "x", "type": "string" } @@ -1356,6 +1362,7 @@ "base64.encode": { "args": [ { + "description": "string to encode", "name": "x", "type": "string" } @@ -1483,6 +1490,7 @@ "base64.is_valid": { "args": [ { + "description": "string to check", "name": "x", "type": "string" } @@ -1589,6 +1597,7 @@ "base64url.decode": { "args": [ { + "description": "string to decode", "name": "x", "type": "string" } @@ -1716,6 +1725,7 @@ "base64url.encode": { "args": [ { + "description": "string to encode", "name": "x", "type": "string" } @@ -1843,6 +1853,7 @@ "base64url.encode_no_pad": { "args": [ { + "description": "string to encode", "name": "x", "type": "string" } @@ -1947,10 +1958,12 @@ "bits.and": { "args": [ { + "description": "the first integer", "name": "x", "type": "number" }, { + "description": "the second integer", "name": "y", "type": "number" } @@ -2065,6 +2078,7 @@ "description": "Returns the bitwise \"AND\" of two integers.", "introduced": "v0.18.0", "result": { + "description": "the bitwise AND of `x` and `y`", "name": "z", "type": "number" }, @@ -2073,10 +2087,12 @@ "bits.lsh": { "args": [ { + "description": "the integer to shift", "name": "x", "type": "number" }, { + "description": "the number of bits to shift", "name": "s", "type": "number" } @@ -2191,6 +2207,7 @@ "description": "Returns a new integer with its bits shifted `s` bits to the left.", "introduced": "v0.18.0", "result": { + "description": "the result of shifting `x` `s` bits to the left", "name": "z", "type": "number" }, @@ -2199,6 +2216,7 @@ "bits.negate": { "args": [ { + "description": "the integer to negate", "name": "x", "type": "number" } @@ -2313,6 +2331,7 @@ "description": "Returns the bitwise negation (flip) of an integer.", "introduced": "v0.18.0", "result": { + "description": "the bitwise negation of `x`", "name": "z", "type": "number" }, @@ -2321,10 +2340,12 @@ "bits.or": { "args": [ { + "description": "the first integer", "name": "x", "type": "number" }, { + "description": "the second integer", "name": "y", "type": "number" } @@ -2439,6 +2460,7 @@ "description": "Returns the bitwise \"OR\" of two integers.", "introduced": "v0.18.0", "result": { + "description": "the bitwise OR of `x` and `y`", "name": "z", "type": "number" }, @@ -2447,10 +2469,12 @@ "bits.rsh": { "args": [ { + "description": "the integer to shift", "name": "x", "type": "number" }, { + "description": "the number of bits to shift", "name": "s", "type": "number" } @@ -2565,6 +2589,7 @@ "description": "Returns a new integer with its bits shifted `s` bits to the right.", "introduced": "v0.18.0", "result": { + "description": "the result of shifting `x` `s` bits to the right", "name": "z", "type": "number" }, @@ -2573,10 +2598,12 @@ "bits.xor": { "args": [ { + "description": "the first integer", "name": "x", "type": "number" }, { + "description": "the second integer", "name": "y", "type": "number" } @@ -2691,6 +2718,7 @@ "description": "Returns the bitwise \"XOR\" (exclusive-or) of two integers.", "introduced": "v0.18.0", "result": { + "description": "the bitwise XOR of `x` and `y`", "name": "z", "type": "number" }, @@ -3542,6 +3570,7 @@ "concat": { "args": [ { + "description": "string to use as a delimiter", "name": "delimiter", "type": "string" }, @@ -3665,6 +3694,7 @@ "description": "Joins a set or array of strings with a delimiter.", "introduced": "v0.17.0", "result": { + "description": "the joined string", "name": "output", "type": "string" }, @@ -4315,6 +4345,7 @@ "crypto.md5": { "args": [ { + "description": "input string", "name": "x", "type": "string" } @@ -4482,6 +4513,7 @@ "crypto.sha1": { "args": [ { + "description": "input string", "name": "x", "type": "string" } @@ -4609,6 +4641,7 @@ "crypto.sha256": { "args": [ { + "description": "input string", "name": "x", "type": "string" } @@ -5988,6 +6021,7 @@ "glob.match": { "args": [ { + "description": "glob pattern", "name": "pattern", "type": "string" }, @@ -5997,6 +6031,7 @@ "type": "any\u003cnull, array[string]\u003e" }, { + "description": "string to match against `pattern`", "name": "match", "type": "string" } @@ -6124,6 +6159,7 @@ "glob.quote_meta": { "args": [ { + "description": "glob pattern", "name": "pattern", "type": "string" } @@ -6456,10 +6492,12 @@ "graphql.is_valid": { "args": [ { + "description": "the GraphQL query", "name": "query", "type": "any\u003cstring, object[any: any]\u003e" }, { + "description": "the GraphQL schema", "name": "schema", "type": "any\u003cstring, object[any: any]\u003e" } @@ -6528,10 +6566,12 @@ "graphql.parse": { "args": [ { + "description": "the GraphQL query", "name": "query", "type": "any\u003cstring, object[any: any]\u003e" }, { + "description": "the GraphQL schema", "name": "schema", "type": "any\u003cstring, object[any: any]\u003e" } @@ -6600,10 +6640,12 @@ "graphql.parse_and_verify": { "args": [ { + "description": "the GraphQL query", "name": "query", "type": "any\u003cstring, object[any: any]\u003e" }, { + "description": "the GraphQL schema", "name": "schema", "type": "any\u003cstring, object[any: any]\u003e" } @@ -6672,6 +6714,7 @@ "graphql.parse_query": { "args": [ { + "description": "GraphQL query string", "name": "query", "type": "string" } @@ -6740,6 +6783,7 @@ "graphql.parse_schema": { "args": [ { + "description": "GraphQL schema string", "name": "schema", "type": "string" } @@ -6808,6 +6852,7 @@ "graphql.schema_is_valid": { "args": [ { + "description": "the schema to verify", "name": "schema", "type": "any\u003cstring, object[any: any]\u003e" } @@ -7235,6 +7280,7 @@ "hex.encode": { "args": [ { + "description": "string to encode", "name": "x", "type": "string" } @@ -7339,6 +7385,7 @@ "http.send": { "args": [ { + "description": "the HTTP request object", "name": "request", "type": "object[string: any]" } @@ -7457,6 +7504,7 @@ "description": "Returns a HTTP response to the given HTTP request.", "introduced": "v0.17.0", "result": { + "description": "the HTTP response object", "name": "response", "type": "object[any: any]" }, @@ -10108,6 +10156,7 @@ "is_array": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10235,6 +10284,7 @@ "is_boolean": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10362,6 +10412,7 @@ "is_null": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10489,6 +10540,7 @@ "is_number": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10616,6 +10668,7 @@ "is_object": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10743,6 +10796,7 @@ "is_set": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10870,6 +10924,7 @@ "is_string": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -10997,6 +11052,7 @@ "json.filter": { "args": [ { + "description": "object to filter", "name": "object", "type": "object[any: any]" }, @@ -11450,10 +11506,12 @@ "json.patch": { "args": [ { + "description": "the object to patch", "name": "object", "type": "any" }, { + "description": "the JSON patches to apply", "name": "patches", "type": "array[object\u003cop: string, path: any\u003e[any: any]]" } @@ -11555,6 +11613,7 @@ "json.remove": { "args": [ { + "description": "object to remove paths from", "name": "object", "type": "object[any: any]" }, @@ -12249,6 +12308,7 @@ "max": { "args": [ { + "description": "the set or array to be searched", "name": "collection", "type": "any\u003carray[any], set[any]\u003e" } @@ -12376,6 +12436,7 @@ "min": { "args": [ { + "description": "the set or array to be searched", "name": "collection", "type": "any\u003carray[any], set[any]\u003e" } @@ -12898,10 +12959,12 @@ "net.cidr_contains": { "args": [ { + "description": "CIDR to check against", "name": "cidr", "type": "string" }, { + "description": "CIDR or IP to check", "name": "cidr_or_ip", "type": "string" } @@ -13020,6 +13083,7 @@ "description": "Checks if a CIDR or IP is contained within another CIDR. `output` is `true` if `cidr_or_ip` (e.g. `127.0.0.64/26` or `127.0.0.1`) is contained within `cidr` (e.g. `127.0.0.1/24`) and `false` otherwise. Supports both IPv4 and IPv6 notations.", "introduced": "v0.17.0", "result": { + "description": "`true` if `cidr_or_ip` is contained within `cidr`", "name": "result", "type": "boolean" }, @@ -13028,10 +13092,12 @@ "net.cidr_contains_matches": { "args": [ { + "description": "CIDRs to check against", "name": "cidrs", "type": "any\u003cstring, array[any\u003cstring, array[any]\u003e], object[string: any\u003cstring, array[any]\u003e], set[any\u003cstring, array[any]\u003e]\u003e" }, { + "description": "CIDRs or IPs to check", "name": "cidrs_or_ips", "type": "any\u003cstring, array[any\u003cstring, array[any]\u003e], object[string: any\u003cstring, array[any]\u003e], set[any\u003cstring, array[any]\u003e]\u003e" } @@ -13154,6 +13220,7 @@ "net.cidr_expand": { "args": [ { + "description": "CIDR to expand", "name": "cidr", "type": "string" } @@ -13281,10 +13348,12 @@ "net.cidr_intersects": { "args": [ { + "description": "first CIDR", "name": "cidr1", "type": "string" }, { + "description": "second CIDR", "name": "cidr2", "type": "string" } @@ -13403,6 +13472,7 @@ "description": "Checks if a CIDR intersects with another CIDR (e.g. `192.168.0.0/16` overlaps with `192.168.1.0/24`). Supports both IPv4 and IPv6 notations.", "introduced": "v0.17.0", "result": { + "description": "`true` if `cidr1` intersects with `cidr2`", "name": "result", "type": "boolean" }, @@ -13411,6 +13481,7 @@ "net.cidr_is_valid": { "args": [ { + "description": "CIDR to validate", "name": "cidr", "type": "string" } @@ -13462,6 +13533,7 @@ "description": "Parses an IPv4/IPv6 CIDR and returns a boolean indicating if the provided CIDR is valid.", "introduced": "v0.46.0", "result": { + "description": "`true` if `cidr` is a valid CIDR", "name": "result", "type": "boolean" }, @@ -13783,10 +13855,12 @@ "numbers.range": { "args": [ { + "description": "the start of the range", "name": "a", "type": "number" }, { + "description": "the end of the range (inclusive)", "name": "b", "type": "number" } @@ -13897,14 +13971,17 @@ "numbers.range_step": { "args": [ { + "description": "the start of the range", "name": "a", "type": "number" }, { + "description": "the end of the range (inclusive)", "name": "b", "type": "number" }, { + "description": "the step between numbers in the range", "name": "step", "type": "number" } @@ -13948,6 +14025,7 @@ "type": "object[any: any]" }, { + "description": "keys to keep in `object`", "name": "keys", "type": "any\u003carray[any], object[any: any], set[any]\u003e" } @@ -14472,10 +14550,12 @@ "object.union": { "args": [ { + "description": "left-hand object", "name": "a", "type": "object[any: any]" }, { + "description": "right-hand object", "name": "b", "type": "object[any: any]" } @@ -14601,6 +14681,7 @@ "object.union_n": { "args": [ { + "description": "list of objects to merge", "name": "objects", "type": "array[object[any: any]]" } @@ -15133,6 +15214,7 @@ "product": { "args": [ { + "description": "the set or array of numbers to multiply", "name": "collection", "type": "any\u003carray[number], set[number]\u003e" } @@ -15248,7 +15330,7 @@ "v0.70.0", "edge" ], - "description": "Muliplies elements of an array or set of numbers", + "description": "Multiplies elements of an array or set of numbers", "introduced": "v0.17.0", "result": { "description": "the product of all elements", @@ -15260,14 +15342,17 @@ "providers.aws.sign_req": { "args": [ { + "description": "HTTP request object", "name": "request", "type": "object[string: any]" }, { + "description": "AWS configuration object", "name": "aws_config", "type": "object[string: any]" }, { + "description": "nanoseconds since the epoch", "name": "time_ns", "type": "number" } @@ -15315,6 +15400,7 @@ "description": "Signs an HTTP request object for Amazon Web Services. Currently implements [AWS Signature Version 4 request signing](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) by the `Authorization` header method.", "introduced": "v0.47.0", "result": { + "description": "HTTP request object with `Authorization` header", "name": "signed_request", "type": "object[any: any]" }, @@ -15323,10 +15409,12 @@ "rand.intn": { "args": [ { + "description": "seed string for the random number", "name": "str", "type": "string" }, { + "description": "upper bound of the random number (exclusive)", "name": "n", "type": "number" } @@ -15669,6 +15757,7 @@ "description": "Returns all successive matches of the expression.", "introduced": "v0.17.0", "result": { + "description": "array of all matches", "name": "output", "type": "array[array[string]]" }, @@ -15815,10 +15904,12 @@ "regex.globs_match": { "args": [ { + "description": "first glob-style regular expression", "name": "glob1", "type": "string" }, { + "description": "second glob-style regular expression", "name": "glob2", "type": "string" } @@ -15937,6 +16028,7 @@ "description": "Checks if the intersection of two glob-style regular expressions matches a non-empty set of non-empty strings.\nThe set of regex symbols is limited for this builtin: only `.`, `*`, `+`, `[`, `-`, `]` and `\\` are treated as special symbols.", "introduced": "v0.17.0", "result": { + "description": "true if the intersection of `glob1` and `glob2` matches a non-empty set of non-empty strings", "name": "result", "type": "boolean" }, @@ -16046,6 +16138,7 @@ "description": "Checks if a string is a valid regular expression: the detailed syntax for patterns is defined by https://github.com/google/re2/wiki/Syntax.", "introduced": "v0.23.0", "result": { + "description": "true if `pattern` is a valid regular expression", "name": "result", "type": "boolean" }, @@ -16160,6 +16253,7 @@ "description": "Matches a string against a regular expression.", "introduced": "v0.23.0", "result": { + "description": "true if `value` matches `pattern`", "name": "result", "type": "boolean" }, @@ -16231,6 +16325,7 @@ "description": "Find and replaces the text using the regular expression pattern.", "introduced": "v0.45.0", "result": { + "description": "string with replaced substrings", "name": "output", "type": "string" }, @@ -16506,6 +16601,7 @@ "description": "Matches a string against a pattern, where there pattern may be glob-like", "introduced": "v0.17.0", "result": { + "description": "true if `value` matches the `template`", "name": "result", "type": "boolean" }, @@ -16766,6 +16862,7 @@ "description": "Parses the input Rego string and returns an object representation of the AST.", "introduced": "v0.17.0", "result": { + "description": "AST object for the Rego module", "name": "output", "type": "object[string: any]" }, @@ -17172,10 +17269,12 @@ "semver.compare": { "args": [ { + "description": "first version string", "name": "a", "type": "string" }, { + "description": "second version string", "name": "b", "type": "string" } @@ -17286,6 +17385,7 @@ "semver.is_valid": { "args": [ { + "description": "input to validate", "name": "vsn", "type": "any" } @@ -18380,6 +18480,7 @@ "description": "Replaces a string from a list of old, new string pairs.\nReplacements are performed in the order they appear in the target string, without overlapping matches.\nThe old string comparisons are done in argument order.", "introduced": "v0.17.0", "result": { + "description": "string with replaced substrings", "name": "output", "type": "string" }, @@ -18388,6 +18489,7 @@ "strings.reverse": { "args": [ { + "description": "string to reverse", "name": "x", "type": "string" } @@ -18456,6 +18558,7 @@ "description": "Reverses a given string.", "introduced": "v0.36.0", "result": { + "description": "reversed string", "name": "y", "type": "string" }, @@ -18464,6 +18567,7 @@ "substring": { "args": [ { + "description": "string to extract substring from", "name": "value", "type": "string" }, @@ -18601,6 +18705,7 @@ "sum": { "args": [ { + "description": "the set or array of numbers to sum", "name": "collection", "type": "any\u003carray[number], set[number]\u003e" } @@ -18733,14 +18838,17 @@ "type": "number" }, { + "description": "number of years to add", "name": "years", "type": "number" }, { + "description": "number of months to add", "name": "months", "type": "number" }, { + "description": "number of days to add", "name": "days", "type": "number" } @@ -19118,10 +19226,12 @@ "time.diff": { "args": [ { + "description": "nanoseconds since the epoch; or a two-element array of the nanoseconds, and a timezone string", "name": "ns1", "type": "any\u003cnumber, array\u003cnumber, string\u003e\u003e" }, { + "description": "nanoseconds since the epoch; or a two-element array of the nanoseconds, and a timezone string", "name": "ns2", "type": "any\u003cnumber, array\u003cnumber, string\u003e\u003e" } @@ -19652,6 +19762,7 @@ "time.parse_rfc3339_ns": { "args": [ { + "description": "input string to parse in RFC3339 format", "name": "value", "type": "string" } @@ -19907,6 +20018,7 @@ "to_number": { "args": [ { + "description": "value to convert", "name": "x", "type": "any\u003cnull, boolean, number, string\u003e" } @@ -20025,6 +20137,7 @@ "description": "Converts a string, bool, or number value to a number: Strings are converted to numbers using `strconv.Atoi`, Boolean `false` is converted to 0 and `true` is converted to 1.", "introduced": "v0.17.0", "result": { + "description": "the numeric representation of `x`", "name": "num", "type": "number" }, @@ -20954,6 +21067,7 @@ "type_name": { "args": [ { + "description": "input value", "name": "x", "type": "any" } @@ -21534,6 +21648,7 @@ "urlquery.decode": { "args": [ { + "description": "the URL-encoded string", "name": "x", "type": "string" } @@ -21768,6 +21883,7 @@ "urlquery.encode": { "args": [ { + "description": "the string to encode", "name": "x", "type": "string" } @@ -21895,6 +22011,7 @@ "urlquery.encode_object": { "args": [ { + "description": "the object to encode", "name": "object", "type": "object[string: any\u003cstring, array[string], set[string]\u003e]" } @@ -22022,6 +22139,7 @@ "uuid.parse": { "args": [ { + "description": "UUID string to parse", "name": "uuid", "type": "string" } @@ -22059,6 +22177,7 @@ "uuid.rfc4122": { "args": [ { + "description": "seed string", "name": "k", "type": "string" } @@ -22177,6 +22296,7 @@ "walk": { "args": [ { + "description": "value to walk", "name": "x", "type": "any" } From f7903696d08d8242ee1ca87841587bf4d2f7b00b Mon Sep 17 00:00:00 2001 From: Peter Macdonald Date: Mon, 4 Nov 2024 14:16:20 +0100 Subject: [PATCH 5/8] Add VodafoneZiggo as adopters (#7154) Signed-off-by: Peter Macdonald --- ADOPTERS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ADOPTERS.md b/ADOPTERS.md index eee94307ee..da4d99934f 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -288,6 +288,8 @@ pre-production (in alphabetical order): * [Magda](https://github.com/magda-io/magda) is a federated, Kubernetes-based, open-source data catalog system. Working as Magda's central authorisation policy engine, OPA helps not only the API endpoint authorisation. Magda also uses its partial evaluation feature to translate datasets authorisation decisions to other database-specific DSLs (e.g. SQL or Elasticsearch DSL) and use them for dataset authorisation enforcement in different databases. +* [VodafoneZiggo](https://www.vodafoneziggo.nl/) Is a Dutch telecommunications company that uses OPA to power authorisation decisions in our internal developer platform based on Backstage, it is also used as a way to enforce and validate component metadata that is onboarded as software components into the Backstage software catalog. + Other adopters that have gone into production or various stages of testing include: From 3b1a948256366ce3cb5f6d6ae5017104d0a6e2e2 Mon Sep 17 00:00:00 2001 From: Shiqi Yang Date: Mon, 4 Nov 2024 12:02:06 -0500 Subject: [PATCH 6/8] Fix default root path check Signed-off-by: Shiqi Yang --- ast/conflicts.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ast/conflicts.go b/ast/conflicts.go index 5c57f7fda0..c1ff48b157 100644 --- a/ast/conflicts.go +++ b/ast/conflicts.go @@ -5,6 +5,7 @@ package ast import ( + "slices" "strings" ) @@ -18,7 +19,7 @@ func CheckPathConflicts(c *Compiler, exists func([]string) (bool, error)) Errors return nil } - if len(c.pathConflictCheckRoots) == 0 { + if len(c.pathConflictCheckRoots) == 0 || slices.Contains(c.pathConflictCheckRoots, "") { for _, child := range root.Children { errs = append(errs, checkDocumentConflicts(child, exists, nil)...) } From 7b6b25133d0a5495d3502d20c44d706b92b8fbb4 Mon Sep 17 00:00:00 2001 From: Shiqi Yang Date: Mon, 4 Nov 2024 13:19:33 -0500 Subject: [PATCH 7/8] Add missing quote to test message Signed-off-by: Shiqi Yang --- plugins/bundle/plugin_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/bundle/plugin_test.go b/plugins/bundle/plugin_test.go index fc961f28ed..5d81c4dc66 100644 --- a/plugins/bundle/plugin_test.go +++ b/plugins/bundle/plugin_test.go @@ -6609,10 +6609,10 @@ result := true`, t.Fatalf("Expected to find status for %s, found nil", bundleName) } if status.Code != errCode { - t.Fatalf(`Expected status code to be %s, found %s`, errCode, status.Code) + t.Fatalf("Expected status code to be %s, found %s", errCode, status.Code) } if !strings.Contains(status.Message, "detected overlapping") { - t.Fatalf(`Expected status message to contain detected overlapping roots", found %s`, status.Message) + t.Fatalf(`Expected status message to contain "detected overlapping roots", found %s`, status.Message) } } @@ -6651,10 +6651,10 @@ result := true`, t.Fatalf("Expected to find status for %s, found nil", bundleName) } if status.Code != errCode { - t.Fatalf(`Expected status code to be %s, found %s`, errCode, status.Code) + t.Fatalf("Expected status code to be %s, found %s", errCode, status.Code) } if !strings.Contains(status.Message, "detected overlapping") { - t.Fatalf(`Expected status message to contain detected overlapping roots", found %s`, status.Message) + t.Fatalf(`Expected status message to contain "detected overlapping roots", found %s`, status.Message) } } @@ -6698,7 +6698,7 @@ result := true`, t.Fatalf("Expected to find status for %s, found nil", bundleName) } if status.Code != "" { - t.Fatalf(`Expected status code to be empty, found %s`, status.Code) + t.Fatalf("Expected status code to be empty, found %s", status.Code) } } @@ -6754,9 +6754,9 @@ func getPluginWithExistingLoadedBundle(t *testing.T, bundleName string, roots [] if status, ok := plugin.status[bundleName]; !ok { t.Fatalf("Expected to find status for %s, found nil", bundleName) } else if status.Type != bundle.SnapshotBundleType { - t.Fatalf("expected snapshot bundle but got %v", status.Type) + t.Fatalf("Expected snapshot bundle but got %v", status.Type) } else if status.Size != snapshotBundleSize { - t.Fatalf("expected snapshot bundle size %d but got %d", snapshotBundleSize, status.Size) + t.Fatalf("Expected snapshot bundle size %d but got %d", snapshotBundleSize, status.Size) } return plugin From 5cd286b70d907fa94b28f267d57b952888b8b169 Mon Sep 17 00:00:00 2001 From: Shiqi Yang Date: Mon, 4 Nov 2024 13:48:09 -0500 Subject: [PATCH 8/8] Use plural form Signed-off-by: Shiqi Yang --- ast/compile.go | 4 ++-- ast/compile_test.go | 2 +- plugins/bundle/plugin.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ast/compile.go b/ast/compile.go index a50bd451c9..7b15bdc4c5 100644 --- a/ast/compile.go +++ b/ast/compile.go @@ -384,10 +384,10 @@ func (c *Compiler) WithPathConflictsCheck(fn func([]string) (bool, error)) *Comp return c } -// WithPathConflictsCheckRoot enables checking path conflicts from the specified root instead +// WithPathConflictsCheckRoots enables checking path conflicts from the specified root instead // of the top root node. This would enable optimizting path conflict checks during bundle // activation if a bundle already defines its own root paths. -func (c *Compiler) WithPathConflictsCheckRoot(rootPaths []string) *Compiler { +func (c *Compiler) WithPathConflictsCheckRoots(rootPaths []string) *Compiler { c.pathConflictCheckRoots = rootPaths return c } diff --git a/ast/compile_test.go b/ast/compile_test.go index 74912f7a59..898a57d775 100644 --- a/ast/compile_test.go +++ b/ast/compile_test.go @@ -1966,7 +1966,7 @@ p { true }`, return false, fmt.Errorf("unexpected error") } return false, nil - }).WithPathConflictsCheckRoot([]string{"badrules"}) + }).WithPathConflictsCheckRoots([]string{"badrules"}) compileStages(c, c.checkRuleConflicts) diff --git a/plugins/bundle/plugin.go b/plugins/bundle/plugin.go index 834e5771dc..efd8eedcf4 100644 --- a/plugins/bundle/plugin.go +++ b/plugins/bundle/plugin.go @@ -616,7 +616,7 @@ func (p *Plugin) activate(ctx context.Context, name string, b *bundle.Bundle, is WithEnablePrintStatements(p.manager.EnablePrintStatements()) if b.Manifest.Roots != nil { - compiler = compiler.WithPathConflictsCheckRoot(*b.Manifest.Roots) + compiler = compiler.WithPathConflictsCheckRoots(*b.Manifest.Roots) } var activateErr error