diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..0ece4a7
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,27 @@
+name: Test
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+ workflow_dispatch:
+
+jobs:
+ build_and_test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out repository code
+ uses: actions/checkout@v4
+
+ - name: Install Node 20
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'npm'
+
+ - name: Test
+ run: |
+ npm ci
+ npm run test
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c9e4b0..991ce9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
All notable changes to this project will be documented in this file.
+## v0.4.0 2024-04-20
+
+- Add Cedar human-readable schema support
+- Update copyright to Cedar Contributors
+
## v0.3.0 2024-01-20
- Update pattern matching
diff --git a/README.md b/README.md
index b137bb7..73611dc 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,62 @@
-# highlight.js support for Cedar policy language
+# highlight.js support for Cedar policy language and Cedar human-readable schema
-[highlight.js](https://highlightjs.org/) (syntax highlighting for the Web) support for Cedar based on [Grammar specification for Cedar policy syntax](https://docs.cedarpolicy.com/syntax-grammar.html) based on structure from [language contributor checklist](https://highlightjs.readthedocs.io/en/latest/language-contribution.html) and mapped to the [Stylable Scopes](https://highlightjs.readthedocs.io/en/latest/css-classes-reference.html).
+[highlight.js](https://highlightjs.org/) (syntax highlighting for the Web) support for Cedar based on [Grammar specification for Cedar policy syntax](https://docs.cedarpolicy.com/syntax-grammar.html) and for Cedar human-readable schema based on [Grammar specification for human-readable schemas](https://docs.cedarpolicy.com/schema/human-readable-schema-grammar.html). Project structure derived from [language contributor checklist](https://highlightjs.readthedocs.io/en/latest/language-contribution.html) and mapped to the [Stylable Scopes](https://highlightjs.readthedocs.io/en/latest/css-classes-reference.html).
See it in action on
// contains, containsAll, containsAny
// see https://docs.cedarpolicy.com/policies/syntax-operators.html
@@ -33,7 +36,7 @@ contains.cedar
};
-
// decimal(), lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual
// see https://docs.cedarpolicy.com/policies/syntax-operators.html#decimal-parse-string-and-convert-to-decimal
@@ -47,7 +50,7 @@ decimal.cedar
};
-
// see https://docs.cedarpolicy.com/policies/syntax-policy.html
@id("F1")
@@ -68,7 +71,7 @@ forbid.cedar
};
-
// poorly formed: This identifier is reserved and cannot be used: XX
permit (principal, action, resource)
@@ -79,7 +82,7 @@ identifier.cedar
when { resource.permit.forbid.when.unless };
-
permit (
principal,
@@ -98,7 +101,7 @@ if-then-else.cedar
};
-
// ip(), isIpv4, isIpv6, isLoopback, isMulticast, isInRange
// see https://docs.cedarpolicy.com/policies/syntax-operators.html#ip-address-functions
@@ -113,7 +116,7 @@ ip.cedar
};
-
// https://docs.cedarpolicy.com/policies/syntax-operators.html#operator-is
permit (
@@ -128,7 +131,7 @@ is.cedar
};
-
// you "must" be 54" tall to ride (wink)
@id("54\" rule") // 54" is 4' 6"
@@ -136,7 +139,7 @@ quotes.cedar
when { resource.restriction == "54\"" && principal.height < 54 };
-
// see https://docs.cedarpolicy.com/policies/templates.html
permit (
@@ -148,6 +151,68 @@ template.cedar
context.readOnly == true
};
+
+
+// https://docs.cedarpolicy.com/schema/human-readable-schema-grammar.html
+namespace NS {
+ type T = {"type": __cedar::String, namespace: String};
+ entity E in E = {action: String};
+ entity R in [R] = {entity: E};
+ action "a" appliesTo {
+ principal: [NS::E],
+ resource: [NS::R],
+ context: {}
+ };
+}
+
+
+
+// nicely formatted with spaces
+namespace N1 {
+ type C = {
+ a: String
+ };
+ entity E;
+ action a1 appliesTo {
+ principal: [E],
+ resource: [E],
+ context: {}
+ };
+ action a2 appliesTo {
+ principal: [N2::E],
+ resource: [N2::E],
+ context: {}
+ };
+}
+
+// no spaces still valid and should highlight
+namespace N2 {
+ type C={"a":String};
+ entity E;
+ action "a1" appliesTo {
+ principal:[N1::E],
+ resource:[N1::E],
+ context:{}
+ };
+ action "astar" in[N1::Action::"a1", N1::Action::"a2",a1,a2]appliesTo{context:{}};
+ action "a2" appliesTo {
+ principal:[E],
+ resource:[E],
+ context:{}
+ };
+}
+
+// no namespace
+entity Y;
+
+
+
diff --git a/test/update-html-files.js b/test/update-html-files.js
index 2d647d0..d4d8433 100644
--- a/test/update-html-files.js
+++ b/test/update-html-files.js
@@ -1,28 +1,48 @@
// Copyright Cedar Contributors
// SPDX-License-Identifier: Apache-2.0
/*
- * updates each index.html file with *.cedar files
+ * updates each index.html file with *.cedar and *.cedarschema files
*/
-const path = require('path');
-const fs = require('fs');
+const path = require('node:path');
+const fs = require('node:fs');
function buildExamples() {
- let html = '';
+ let html = '',
+ cedarHTML = '',
+ cedarschemaHTML = '';
- const files = fs
- .readdirSync(path.join(__dirname, 'data'))
- .filter((f) => f.endsWith('.cedar'));
+ const files = fs.readdirSync(path.join(__dirname, 'data')).filter((f) => {
+ return f.endsWith('.cedar') || f.endsWith('.cedarschema');
+ });
files.forEach((file) => {
const code = fs.readFileSync(path.join(__dirname, 'data', file), 'utf8');
- html += `
-
+${code.replaceAll('<', '<')}
+
+`;
+ } else {
+ cedarHTML += `
+
${code.replaceAll('<', '<')}
`;
+ }
});
+ html = `
+
// contains, containsAll, containsAny
// see https://docs.cedarpolicy.com/policies/syntax-operators.html
@@ -24,7 +26,7 @@ contains.cedar
};
-
// decimal(), lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual
// see https://docs.cedarpolicy.com/policies/syntax-operators.html#decimal-parse-string-and-convert-to-decimal
@@ -38,7 +40,7 @@ decimal.cedar
};
-
// see https://docs.cedarpolicy.com/policies/syntax-policy.html
@id("F1")
@@ -59,7 +61,7 @@ forbid.cedar
};
-
// poorly formed: This identifier is reserved and cannot be used: XX
permit (principal, action, resource)
@@ -70,7 +72,7 @@ identifier.cedar
when { resource.permit.forbid.when.unless };
-
permit (
principal,
@@ -89,7 +91,7 @@ if-then-else.cedar
};
-
// ip(), isIpv4, isIpv6, isLoopback, isMulticast, isInRange
// see https://docs.cedarpolicy.com/policies/syntax-operators.html#ip-address-functions
@@ -104,7 +106,7 @@ ip.cedar
};
-
// https://docs.cedarpolicy.com/policies/syntax-operators.html#operator-is
permit (
@@ -119,7 +121,7 @@ is.cedar
};
-
// you "must" be 54" tall to ride (wink)
@id("54\" rule") // 54" is 4' 6"
@@ -127,7 +129,7 @@ quotes.cedar
when { resource.restriction == "54\"" && principal.height < 54 };
-
// see https://docs.cedarpolicy.com/policies/templates.html
permit (
@@ -139,6 +141,68 @@ template.cedar
context.readOnly == true
};
+
+
+// https://docs.cedarpolicy.com/schema/human-readable-schema-grammar.html
+namespace NS {
+ type T = {"type": __cedar::String, namespace: String};
+ entity E in E = {action: String};
+ entity R in [R] = {entity: E};
+ action "a" appliesTo {
+ principal: [NS::E],
+ resource: [NS::R],
+ context: {}
+ };
+}
+
+
+
+// nicely formatted with spaces
+namespace N1 {
+ type C = {
+ a: String
+ };
+ entity E;
+ action a1 appliesTo {
+ principal: [E],
+ resource: [E],
+ context: {}
+ };
+ action a2 appliesTo {
+ principal: [N2::E],
+ resource: [N2::E],
+ context: {}
+ };
+}
+
+// no spaces still valid and should highlight
+namespace N2 {
+ type C={"a":String};
+ entity E;
+ action "a1" appliesTo {
+ principal:[N1::E],
+ resource:[N1::E],
+ context:{}
+ };
+ action "astar" in[N1::Action::"a1", N1::Action::"a2",a1,a2]appliesTo{context:{}};
+ action "a2" appliesTo {
+ principal:[E],
+ resource:[E],
+ context:{}
+ };
+}
+
+// no namespace
+entity Y;
+
+
+