Added support for Firestore security rules (#2010)

This adds support for Google Cloud Firestore security rules.
This commit is contained in:
Michael Schmidt 2019-08-17 14:36:50 +02:00 committed by GitHub
parent ebe363f426
commit 9f72258641
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 348 additions and 5 deletions

File diff suppressed because one or more lines are too long

View File

@ -285,6 +285,11 @@
"require": "clike",
"owner": "simonreynolds7"
},
"firestore-security-rules": {
"title": "Firestore security rules",
"require": "clike",
"owner": "RunDevelopment"
},
"flow": {
"title": "Flow",
"require": "javascript",

View File

@ -0,0 +1,35 @@
Prism.languages['firestore-security-rules'] = Prism.languages.extend('clike', {
'comment': /\/\/.*/,
'keyword': /\b(?:allow|function|if|match|null|return|rules_version|service)\b/,
'operator': /&&|\|\||[<>!=]=?|[-+*/%=]|\b(?:in|is)\b/,
});
delete Prism.languages['firestore-security-rules']['class-name'];
Prism.languages.insertBefore('firestore-security-rules', 'keyword', {
'path': {
pattern: /(^|[\s(),])(?:\/(?:[\w\xA0-\uFFFF]+|\{[\w\xA0-\uFFFF]+(?:=\*\*)?\}|\$\([\w\xA0-\uFFFF.]+\)))+/,
lookbehind: true,
greedy: true,
inside: {
'variable': {
pattern: /\{[\w\xA0-\uFFFF]+(?:=\*\*)?\}|\$\([\w\xA0-\uFFFF.]+\)/,
inside: {
'operator': /=/,
'keyword': /\*\*/,
'punctuation': /[.$(){}]/
}
},
'punctuation': /[/]/
}
},
'method': {
// to make the pattern shorter, the actual method names are omitted
pattern: /(\ballow\s+)[a-z]+(?:\s*,\s*[a-z]+)*(?=\s*[:;])/,
lookbehind: true,
alias: 'builtin',
inside: {
'punctuation': /,/
}
},
});

View File

@ -0,0 +1 @@
Prism.languages["firestore-security-rules"]=Prism.languages.extend("clike",{comment:/\/\/.*/,keyword:/\b(?:allow|function|if|match|null|return|rules_version|service)\b/,operator:/&&|\|\||[<>!=]=?|[-+*/%=]|\b(?:in|is)\b/}),delete Prism.languages["firestore-security-rules"]["class-name"],Prism.languages.insertBefore("firestore-security-rules","keyword",{path:{pattern:/(^|[\s(),])(?:\/(?:[\w\xA0-\uFFFF]+|\{[\w\xA0-\uFFFF]+(?:=\*\*)?\}|\$\([\w\xA0-\uFFFF.]+\)))+/,lookbehind:!0,greedy:!0,inside:{variable:{pattern:/\{[\w\xA0-\uFFFF]+(?:=\*\*)?\}|\$\([\w\xA0-\uFFFF.]+\)/,inside:{operator:/=/,keyword:/\*\*/,punctuation:/[.$(){}]/}},punctuation:/[/]/}},method:{pattern:/(\ballow\s+)[a-z]+(?:\s*,\s*[a-z]+)*(?=\s*[:;])/,lookbehind:!0,alias:"builtin",inside:{punctuation:/,/}}});

View File

@ -0,0 +1,37 @@
<h2>Full example</h2>
<pre><code>rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Returns `true` if the requested post is 'published'
// or the user authored the post
function authorOrPublished() {
return resource.data.published == true || request.auth.uid == resource.data.author;
}
match /{path=**}/posts/{post} {
// Anyone can query published posts
// Authors can query their unpublished posts
allow list: if authorOrPublished();
// Anyone can retrieve a published post
// Authors can retrieve an unpublished post
allow get: if authorOrPublished();
}
match /forums/{forumid}/posts/{postid} {
// Only a post's author can write to a post
allow write: if request.auth.uid == resource.data.author;
}
}
match /databases/{database}/reviews {
// Assign roles to all users and refine access based on user roles
match /some_collection/{document} {
allow read: if get(/databases/$(database)/reviews/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/reviews/users/$(request.auth.uid)).data.role == "Writer"
}
}
}</code></pre>

View File

@ -31,6 +31,7 @@
"markup-templating"
],
"fsharp": "clike",
"firestore-security-rules": "clike",
"flow": "javascript",
"glsl": "clike",
"gml": "clike",

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var r={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:["markup","csharp"],bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike",flow:"javascript",glsl:"clike",gml:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike"],"js-extras":"javascript","js-templates":"javascript",jsonp:"json",json5:"json",kotlin:"clike",less:"css",lilypond:"scheme",markdown:"markup","markup-templating":"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:["clike","markup-templating"],phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],qore:"clike",jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sas:"sql",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",soy:"markup-templating",swift:"clike",tap:"yaml",textile:"markup",tt2:["clike","markup-templating"],twig:"markup",typescript:"javascript","t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","visual-basic"],vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup",xquery:"markup"},l={html:"markup",xml:"markup",svg:"markup",mathml:"markup",js:"javascript",adoc:"asciidoc",shell:"bash",rbnf:"bnf",cs:"csharp",dotnet:"csharp",coffee:"coffeescript",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gamemakerlanguage:"gml",hs:"haskell",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",n4jsd:"n4js",objectpascal:"pascal",px:"pcaxis",py:"python",rb:"ruby",trig:"turtle",ts:"typescript",t4:"t4-cs",vb:"visual-basic",xeoracube:"xeora",yml:"yaml"},n={},e=document.getElementsByTagName("script"),a=e[e.length-1],t="components/",s=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)js$/i,i=/[\w-]+\.(?:min\.)js$/i;if(a.hasAttribute("data-autoloader-path"))t=a.getAttribute("data-autoloader-path").trim().replace(/\/?$/,"/");else{var c=a.src;s.test(c)?t=c.replace(s,"components/"):i.test(c)&&(t=c.replace(i,"components/"))}var p=Prism.plugins.autoloader={languages_path:t,use_minified:!0,loadLanguages:o};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&"none"!==e.language&&function(e,a){e in l&&(e=l[e]);var t=a.getAttribute("data-dependencies"),s=a.parentElement;!t&&s&&"pre"===s.tagName.toLowerCase()&&(t=s.getAttribute("data-dependencies")),o(t=t?t.split(/\s*,\s*/g):[],function(){m(e,function(){Prism.highlightElement(a)})})}(e.language,e.element)})}function o(e,a,t){"string"==typeof e&&(e=[e]);var s=e.length,i=0,c=!1;function r(){c||++i===s&&a&&a(e)}0!==s?e.forEach(function(e){m(e,r,function(){c||(c=!0,t&&t(e))})}):a&&setTimeout(a,0)}function m(a,t,s){var i=0<=a.indexOf("!");a=a.replace("!",""),a=l[a]||a;var e=function(){var e=n[a];if(e||(e=n[a]={callbacks:[]}),e.callbacks.push({success:t,error:s}),!i&&Prism.languages[a])u(a,"success");else if(!i&&e.error)u(a,"error");else if(i||!e.loading){e.loading=!0,function(e,a,t){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),a&&a()},s.onerror=function(){document.body.removeChild(s),t&&t()},document.body.appendChild(s)}(function(e){return p.languages_path+"prism-"+e+(p.use_minified?".min":"")+".js"}(a),function(){e.loading=!1,u(a,"success")},function(){e.loading=!1,e.error=!0,u(a,"error")})}},c=r[a];c&&c.length?o(c,e,s):e()}function u(e,a){if(n[e]){for(var t=n[e].callbacks,s=0,i=t.length;s<i;s++){var c=t[s][a];c&&setTimeout(c,0)}t.length=0}}}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document&&document.createElement){var c={javascript:"clike",actionscript:"javascript",arduino:"cpp",aspnet:["markup","csharp"],bison:"c",c:"clike",csharp:"clike",cpp:"c",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",glsl:"clike",gml:"clike",go:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike"],"js-extras":"javascript","js-templates":"javascript",jsonp:"json",json5:"json",kotlin:"clike",less:"css",lilypond:"scheme",markdown:"markup","markup-templating":"markup",n4js:"javascript",nginx:"clike",objectivec:"c",opencl:"cpp",parser:"markup",php:["clike","markup-templating"],phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],qore:"clike",jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sas:"sql",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",soy:"markup-templating",swift:"clike",tap:"yaml",textile:"markup",tt2:["clike","markup-templating"],twig:"markup",typescript:"javascript","t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","visual-basic"],vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup",xquery:"markup"},l={html:"markup",xml:"markup",svg:"markup",mathml:"markup",js:"javascript",adoc:"asciidoc",shell:"bash",rbnf:"bnf",cs:"csharp",dotnet:"csharp",coffee:"coffeescript",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gamemakerlanguage:"gml",hs:"haskell",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",n4jsd:"n4js",objectpascal:"pascal",px:"pcaxis",py:"python",rb:"ruby",trig:"turtle",ts:"typescript",t4:"t4-cs",vb:"visual-basic",xeoracube:"xeora",yml:"yaml"},n={},e=document.getElementsByTagName("script"),a=e[e.length-1],t="components/",s=/\bplugins\/autoloader\/prism-autoloader\.(?:min\.)js$/i,i=/[\w-]+\.(?:min\.)js$/i;if(a.hasAttribute("data-autoloader-path"))t=a.getAttribute("data-autoloader-path").trim().replace(/\/?$/,"/");else{var r=a.src;s.test(r)?t=r.replace(s,"components/"):i.test(r)&&(t=r.replace(i,"components/"))}var p=Prism.plugins.autoloader={languages_path:t,use_minified:!0,loadLanguages:o};Prism.hooks.add("complete",function(e){e.element&&e.language&&!e.grammar&&"none"!==e.language&&function(e,a){e in l&&(e=l[e]);var t=a.getAttribute("data-dependencies"),s=a.parentElement;!t&&s&&"pre"===s.tagName.toLowerCase()&&(t=s.getAttribute("data-dependencies")),o(t=t?t.split(/\s*,\s*/g):[],function(){m(e,function(){Prism.highlightElement(a)})})}(e.language,e.element)})}function o(e,a,t){"string"==typeof e&&(e=[e]);var s=e.length,i=0,r=!1;function c(){r||++i===s&&a&&a(e)}0!==s?e.forEach(function(e){m(e,c,function(){r||(r=!0,t&&t(e))})}):a&&setTimeout(a,0)}function m(a,t,s){var i=0<=a.indexOf("!");a=a.replace("!",""),a=l[a]||a;var e=function(){var e=n[a];if(e||(e=n[a]={callbacks:[]}),e.callbacks.push({success:t,error:s}),!i&&Prism.languages[a])u(a,"success");else if(!i&&e.error)u(a,"error");else if(i||!e.loading){e.loading=!0,function(e,a,t){var s=document.createElement("script");s.src=e,s.async=!0,s.onload=function(){document.body.removeChild(s),a&&a()},s.onerror=function(){document.body.removeChild(s),t&&t()},document.body.appendChild(s)}(function(e){return p.languages_path+"prism-"+e+(p.use_minified?".min":"")+".js"}(a),function(){e.loading=!1,u(a,"success")},function(){e.loading=!1,e.error=!0,u(a,"error")})}},r=c[a];r&&r.length?o(r,e,s):e()}function u(e,a){if(n[e]){for(var t=n[e].callbacks,s=0,i=t.length;s<i;s++){var r=t[s][a];r&&setTimeout(r,0)}t.length=0}}}();

View File

@ -52,6 +52,7 @@
"ejs": "EJS",
"erb": "ERB",
"fsharp": "F#",
"firestore-security-rules": "Firestore security rules",
"gcode": "G-code",
"gdscript": "GDScript",
"gedcom": "GEDCOM",

View File

@ -1 +1 @@
!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var i={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",js:"JavaScript",abap:"ABAP",abnf:"Augmented BackusNaur form",apacheconf:"Apache Configuration",apl:"APL",arff:"ARFF",asciidoc:"AsciiDoc",adoc:"AsciiDoc",asm6502:"6502 Assembly",aspnet:"ASP.NET (C#)",autohotkey:"AutoHotkey",autoit:"AutoIt",shell:"Bash",basic:"BASIC",bnf:"BackusNaur form",rbnf:"Routing BackusNaur form",csharp:"C#",cs:"C#",dotnet:"C#",cpp:"C++",cil:"CIL",coffee:"CoffeeScript",cmake:"CMake",csp:"Content-Security-Policy","css-extras":"CSS Extras",django:"Django/Jinja2",jinja2:"Django/Jinja2","dns-zone-file":"DNS zone file","dns-zone":"DNS zone file",dockerfile:"Docker",ebnf:"Extended BackusNaur form",ejs:"EJS",erb:"ERB",fsharp:"F#",gcode:"G-code",gdscript:"GDScript",gedcom:"GEDCOM",glsl:"GLSL",gml:"GameMaker Language",gamemakerlanguage:"GameMaker Language",graphql:"GraphQL",hs:"Haskell",hcl:"HCL",http:"HTTP",hpkp:"HTTP Public-Key-Pins",hsts:"HTTP Strict-Transport-Security",ichigojam:"IchigoJam",inform7:"Inform 7",javadoc:"JavaDoc",javadoclike:"JavaDoc-like",javastacktrace:"Java stack trace",jq:"JQ",jsdoc:"JSDoc","js-extras":"JS Extras","js-templates":"JS Templates",json:"JSON",jsonp:"JSONP",json5:"JSON5",latex:"LaTeX",tex:"TeX",context:"ConTeXt",lilypond:"LilyPond",ly:"LilyPond",emacs:"Lisp",elisp:"Lisp","emacs-lisp":"Lisp",lolcode:"LOLCODE",md:"Markdown","markup-templating":"Markup templating",matlab:"MATLAB",mel:"MEL",n1ql:"N1QL",n4js:"N4JS",n4jsd:"N4JS","nand2tetris-hdl":"Nand To Tetris HDL",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",objectpascal:"Object Pascal",pcaxis:"PC-Axis",px:"PC-Axis",php:"PHP",phpdoc:"PHPDoc","php-extras":"PHP Extras",plsql:"PL/SQL",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",py:"Python",q:"Q (kdb+ database)",jsx:"React JSX",tsx:"React TSX",renpy:"Ren'py",rest:"reST (reStructuredText)",rb:"Ruby",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)","shell-session":"Shell session",soy:"Soy (Closure Template)","splunk-spl":"Splunk SPL",sql:"SQL",tap:"TAP",toml:"TOML",tt2:"Template Toolkit 2",trig:"TriG",ts:"TypeScript","t4-cs":"T4 Text Templates (C#)",t4:"T4 Text Templates (C#)","t4-vb":"T4 Text Templates (VB)","t4-templating":"T4 templating",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim","visual-basic":"Visual Basic",vb:"Visual Basic",wasm:"WebAssembly",wiki:"Wiki markup",xeoracube:"XeoraCube",xojo:"Xojo (REALbasic)",xquery:"XQuery",yaml:"YAML",yml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(e){var a=e.element.parentNode;if(a&&/pre/i.test(a.nodeName)){var s,t=a.getAttribute("data-language")||i[e.language]||((s=e.language)?(s.substring(0,1).toUpperCase()+s.substring(1)).replace(/s(?=cript)/,"S"):s);if(t){var o=document.createElement("span");return o.textContent=t,o}}})}else console.warn("Show Languages plugin loaded before Toolbar plugin.")}();
!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var i={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",js:"JavaScript",abap:"ABAP",abnf:"Augmented BackusNaur form",apacheconf:"Apache Configuration",apl:"APL",arff:"ARFF",asciidoc:"AsciiDoc",adoc:"AsciiDoc",asm6502:"6502 Assembly",aspnet:"ASP.NET (C#)",autohotkey:"AutoHotkey",autoit:"AutoIt",shell:"Bash",basic:"BASIC",bnf:"BackusNaur form",rbnf:"Routing BackusNaur form",csharp:"C#",cs:"C#",dotnet:"C#",cpp:"C++",cil:"CIL",coffee:"CoffeeScript",cmake:"CMake",csp:"Content-Security-Policy","css-extras":"CSS Extras",django:"Django/Jinja2",jinja2:"Django/Jinja2","dns-zone-file":"DNS zone file","dns-zone":"DNS zone file",dockerfile:"Docker",ebnf:"Extended BackusNaur form",ejs:"EJS",erb:"ERB",fsharp:"F#","firestore-security-rules":"Firestore security rules",gcode:"G-code",gdscript:"GDScript",gedcom:"GEDCOM",glsl:"GLSL",gml:"GameMaker Language",gamemakerlanguage:"GameMaker Language",graphql:"GraphQL",hs:"Haskell",hcl:"HCL",http:"HTTP",hpkp:"HTTP Public-Key-Pins",hsts:"HTTP Strict-Transport-Security",ichigojam:"IchigoJam",inform7:"Inform 7",javadoc:"JavaDoc",javadoclike:"JavaDoc-like",javastacktrace:"Java stack trace",jq:"JQ",jsdoc:"JSDoc","js-extras":"JS Extras","js-templates":"JS Templates",json:"JSON",jsonp:"JSONP",json5:"JSON5",latex:"LaTeX",tex:"TeX",context:"ConTeXt",lilypond:"LilyPond",ly:"LilyPond",emacs:"Lisp",elisp:"Lisp","emacs-lisp":"Lisp",lolcode:"LOLCODE",md:"Markdown","markup-templating":"Markup templating",matlab:"MATLAB",mel:"MEL",n1ql:"N1QL",n4js:"N4JS",n4jsd:"N4JS","nand2tetris-hdl":"Nand To Tetris HDL",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",objectpascal:"Object Pascal",pcaxis:"PC-Axis",px:"PC-Axis",php:"PHP",phpdoc:"PHPDoc","php-extras":"PHP Extras",plsql:"PL/SQL",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",py:"Python",q:"Q (kdb+ database)",jsx:"React JSX",tsx:"React TSX",renpy:"Ren'py",rest:"reST (reStructuredText)",rb:"Ruby",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)","shell-session":"Shell session",soy:"Soy (Closure Template)","splunk-spl":"Splunk SPL",sql:"SQL",tap:"TAP",toml:"TOML",tt2:"Template Toolkit 2",trig:"TriG",ts:"TypeScript","t4-cs":"T4 Text Templates (C#)",t4:"T4 Text Templates (C#)","t4-vb":"T4 Text Templates (VB)","t4-templating":"T4 templating",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim","visual-basic":"Visual Basic",vb:"Visual Basic",wasm:"WebAssembly",wiki:"Wiki markup",xeoracube:"XeoraCube",xojo:"Xojo (REALbasic)",xquery:"XQuery",yaml:"YAML",yml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(e){var a=e.element.parentNode;if(a&&/pre/i.test(a.nodeName)){var s,t=a.getAttribute("data-language")||i[e.language]||((s=e.language)?(s.substring(0,1).toUpperCase()+s.substring(1)).replace(/s(?=cript)/,"S"):s);if(t){var o=document.createElement("span");return o.textContent=t,o}}})}else console.warn("Show Languages plugin loaded before Toolbar plugin.")}();

View File

@ -9,9 +9,9 @@ foo@_bar
["atom", "foo"],
["atom", "foo@_bar"],
["quoted-atom", "'foo bar'"],
["quoted-atom", "'\\'\\\\'"]
["quoted-atom", "'\\'\\\\'"]
]
----------------------------------------------------
Checks for atoms and quoted atoms.
Checks for atoms and quoted atoms.

View File

@ -0,0 +1,11 @@
// comment
----------------------------------------------------
[
["comment", "// comment"]
]
----------------------------------------------------
Checks for comments.

View File

@ -0,0 +1,25 @@
allow
function
if
match
null
return
rules_version
service
----------------------------------------------------
[
["keyword", "allow"],
["keyword", "function"],
["keyword", "if"],
["keyword", "match"],
["keyword", "null"],
["keyword", "return"],
["keyword", "rules_version"],
["keyword", "service"]
]
----------------------------------------------------
Checks for keywords.

View File

@ -0,0 +1,38 @@
allow read;
allow read, write: if false;
allow get, list, update;
----------------------------------------------------
[
["keyword", "allow"],
["method", [
"read"
]],
["punctuation", ";"],
["keyword", "allow"],
["method", [
"read",
["punctuation", ","],
" write"
]],
["punctuation", ":"],
["keyword", "if"],
["boolean", "false"],
["punctuation", ";"],
["keyword", "allow"],
["method", [
"get",
["punctuation", ","],
" list",
["punctuation", ","],
" update"
]],
["punctuation", ";"]
]
----------------------------------------------------
Checks for methods.

View File

@ -0,0 +1,13 @@
123
1.23
----------------------------------------------------
[
["number", "123"],
["number", "1.23"]
]
----------------------------------------------------
Checks for numbers.

View File

@ -0,0 +1,31 @@
+ - * / %
< > <= >= != ==
! && ||
in is
----------------------------------------------------
[
["operator", "+"],
["operator", "-"],
["operator", "*"],
["operator", "/"],
["operator", "%"],
["operator", "<"],
["operator", ">"],
["operator", "<="],
["operator", ">="],
["operator", "!="],
["operator", "=="],
["operator", "!"],
["operator", "&&"],
["operator", "||"],
["operator", "in"],
["operator", "is"]
]
----------------------------------------------------
Checks for operators.

View File

@ -0,0 +1,99 @@
/databases/foo
/foo/{wildcard}
/foo/{wildcard}/bar
/foo/{x}/{y}/{z}/bar
/foo/$(x)/$(y)/bar/$(request.auth.uid)
----------------------------------------------------
[
["path", [
["punctuation", "/"],
"databases",
["punctuation", "/"],
"foo"
]],
["path", [
["punctuation", "/"],
"foo",
["punctuation", "/"],
["variable", [
["punctuation", "{"],
"wildcard",
["punctuation", "}"]
]]
]],
["path", [
["punctuation", "/"],
"foo",
["punctuation", "/"],
["variable", [
["punctuation", "{"],
"wildcard",
["punctuation", "}"]
]],
["punctuation", "/"],
"bar"
]],
["path", [
["punctuation", "/"],
"foo",
["punctuation", "/"],
["variable", [
["punctuation", "{"],
"x",
["punctuation", "}"]
]],
["punctuation", "/"],
["variable", [
["punctuation", "{"],
"y",
["punctuation", "}"]
]],
["punctuation", "/"],
["variable", [
["punctuation", "{"],
"z",
["punctuation", "}"]
]],
["punctuation", "/"],
"bar"
]],
["path", [
["punctuation", "/"],
"foo",
["punctuation", "/"],
["variable", [
["punctuation", "$"],
["punctuation", "("],
"x",
["punctuation", ")"]
]],
["punctuation", "/"],
["variable", [
["punctuation", "$"],
["punctuation", "("],
"y",
["punctuation", ")"]
]],
["punctuation", "/"],
"bar",
["punctuation", "/"],
["variable", [
["punctuation", "$"],
["punctuation", "("],
"request",
["punctuation", "."],
"auth",
["punctuation", "."],
"uid",
["punctuation", ")"]
]]
]]
]
----------------------------------------------------
Checks for paths.

View File

@ -0,0 +1,29 @@
. : , ;
[ ] ( ) { }
[0:2]
----------------------------------------------------
[
["punctuation", "."],
["punctuation", ":"],
["punctuation", ","],
["punctuation", ";"],
["punctuation", "["],
["punctuation", "]"],
["punctuation", "("],
["punctuation", ")"],
["punctuation", "{"],
["punctuation", "}"],
["punctuation", "["],
["number", "0"],
["punctuation", ":"],
["number", "2"],
["punctuation", "]"]
]
----------------------------------------------------
Checks for punctuation.

View File

@ -0,0 +1,17 @@
''
'foo'
""
"foo"
----------------------------------------------------
[
["string", "''"],
["string", "'foo'"],
["string", "\"\""],
["string", "\"foo\""]
]
----------------------------------------------------
Checks for strings.