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 -## Install +## Use + +Web browser ` + + +``` + +ECMAScript module `import` usage example from `test/vite/index.html` (adjust the import `from` paths as required): + +```javascript +import hljs from 'highlight.js'; +import { hljsCedar, hljsCedarschema } from 'hljs-cedar.mjs'; +hljs.registerLanguage('cedar', hljsCedar); +hljs.registerLanguage('cedarschema', hljsCedarschema); +hljs.highlightAll(); +``` + +## Development + +### Install Install the project dependencies using `npm install`. `src/cedar.js` is the main source file in ECMAScript module format. -## Build +### Build The `npm run build` script uses [esbuild](https://esbuild.github.io/api/)to create multiple files in the `dist` folder: -- `hljs-cedar.js` - Web browser ` - +

static script src test page for highlightjs-cedar

@@ -20,7 +21,9 @@

static script src test page for highlightjs-cedar

-

contains.cedar

+

Cedar

+ +

contains.cedar


 // contains, containsAll, containsAny
 // see https://docs.cedarpolicy.com/policies/syntax-operators.html
@@ -33,7 +36,7 @@ 

contains.cedar

};
-

decimal.cedar

+

decimal.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

};
-

forbid.cedar

+

forbid.cedar


 // see https://docs.cedarpolicy.com/policies/syntax-policy.html
 @id("F1")
@@ -68,7 +71,7 @@ 

forbid.cedar

};
-

identifier.cedar

+

identifier.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 };
-

if-then-else.cedar

+

if-then-else.cedar


 permit (
   principal,
@@ -98,7 +101,7 @@ 

if-then-else.cedar

};
-

ip.cedar

+

ip.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

};
-

is.cedar

+

is.cedar


 // https://docs.cedarpolicy.com/policies/syntax-operators.html#operator-is
 permit (
@@ -128,7 +131,7 @@ 

is.cedar

};
-

quotes.cedar

+

quotes.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 };
-

template.cedar

+

template.cedar


 // see https://docs.cedarpolicy.com/policies/templates.html
 permit (
@@ -148,6 +151,68 @@ 

template.cedar

context.readOnly == true };
+ +
+ +

Cedar schema

+ +

keywords.cedarschema

+

+// 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: {}
+  };
+}
+
+ +

namespaces.cedarschema

+

+// 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 += ` -

${file}

+ if (file.endsWith('.cedarschema')) { + cedarschemaHTML += ` +

${file}

+

+${code.replaceAll('<', '<')}
+
+`; + } else { + cedarHTML += ` +

${file}


 ${code.replaceAll('<', '<')}
 
`; + } }); + html = ` +

Cedar

+${cedarHTML} +
+ +

Cedar schema

+${cedarschemaHTML} +`; + return html; } diff --git a/test/vite/index.html b/test/vite/index.html index bed9f91..6807bde 100644 --- a/test/vite/index.html +++ b/test/vite/index.html @@ -11,7 +11,9 @@

Vite ESM test page for highlightjs-cedar

-

contains.cedar

+

Cedar

+ +

contains.cedar


 // contains, containsAll, containsAny
 // see https://docs.cedarpolicy.com/policies/syntax-operators.html
@@ -24,7 +26,7 @@ 

contains.cedar

};
-

decimal.cedar

+

decimal.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

};
-

forbid.cedar

+

forbid.cedar


 // see https://docs.cedarpolicy.com/policies/syntax-policy.html
 @id("F1")
@@ -59,7 +61,7 @@ 

forbid.cedar

};
-

identifier.cedar

+

identifier.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 };
-

if-then-else.cedar

+

if-then-else.cedar


 permit (
   principal,
@@ -89,7 +91,7 @@ 

if-then-else.cedar

};
-

ip.cedar

+

ip.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

};
-

is.cedar

+

is.cedar


 // https://docs.cedarpolicy.com/policies/syntax-operators.html#operator-is
 permit (
@@ -119,7 +121,7 @@ 

is.cedar

};
-

quotes.cedar

+

quotes.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 };
-

template.cedar

+

template.cedar


 // see https://docs.cedarpolicy.com/policies/templates.html
 permit (
@@ -139,6 +141,68 @@ 

template.cedar

context.readOnly == true };
+ +
+ +

Cedar schema

+ +

keywords.cedarschema

+

+// 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: {}
+  };
+}
+
+ +

namespaces.cedarschema

+

+// 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/vite/main.js b/test/vite/main.js index 12f23f2..ab3c4ec 100644 --- a/test/vite/main.js +++ b/test/vite/main.js @@ -1,7 +1,8 @@ // Copyright Cedar Contributors // SPDX-License-Identifier: Apache-2.0 -import '../../node_modules/highlight.js/styles/github.css'; +import '../../dist/github.min.css'; import hljs from 'highlight.js'; -import hljsCedar from '../../dist/hljs-cedar.mjs'; +import { hljsCedar, hljsCedarschema } from '../../dist/hljs-cedar.mjs'; hljs.registerLanguage('cedar', hljsCedar); +hljs.registerLanguage('cedarschema', hljsCedarschema); hljs.highlightAll();