@openfga/frontend-utils
Version:
Exposes helpful utilities for building authoring experiences of OpenFGA Models.
220 lines (219 loc) • 10.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.language = void 0;
exports.getLanguageConfiguration = getLanguageConfiguration;
const keyword_1 = require("../../constants/keyword");
const constants_1 = require("../../constants");
const theme_1 = require("../../theme");
// Source for the code below:
// https://github.com/microsoft/monaco-editor/blob/main/src/basic-languages/python/python.ts
// This is exported as a function so that we can keep referencing monaco as just a type rather than loading it directly,
// thus keeping it as a dev dependency for those who do not want to use it
function getLanguageConfiguration(monaco) {
return {
comments: {
lineComment: "#",
},
brackets: [
["[", "]"],
["(", ")"],
["{", "}"],
],
autoClosingPairs: [
{ open: "[", close: "]" },
{ open: "(", close: ")" },
{ open: "{", close: "}" },
],
surroundingPairs: [
{ open: "[", close: "]" },
{ open: "(", close: ")" },
],
onEnterRules: [
{
beforeText: new RegExp("^\\s*(?:type|relations|model|define).*?:\\s*$"),
action: { indentAction: monaco.languages.IndentAction.Indent },
},
],
folding: {
offSide: true,
markers: {
start: new RegExp("^\\s*#region\\b"),
end: new RegExp("^\\s*#endregion\\b"),
},
},
};
}
exports.language = {
defaultToken: "",
tokenPostfix: `.${constants_1.LANGUAGE_NAME}`,
keywords: [],
operators: [],
identifiers: new RegExp(/(?!self)(?:\w|-[a-zA-Z])*/),
brackets: [
{ open: "[", close: "]", token: theme_1.OpenFgaDslThemeToken.DELIMITER_BRACKET_TYPE_RESTRICTIONS },
{ open: "(", close: ")", token: theme_1.OpenFgaDslThemeToken.DELIMITER_BRACKET_RELATION_DEFINITION },
{ open: "{", close: "}", token: theme_1.OpenFgaDslThemeToken.DELIMITER_BRACKET_CONDITION_EXPRESSION },
],
tokenizer: {
root: [
{ include: "@comment" },
{ include: "@whitespace" },
[new RegExp(/(\[)/), "@brackets", "@restrictions"],
[new RegExp(/(\{)/), "@brackets", "@cel_symbols"],
[new RegExp(/[{}[\]()]/), "@brackets"],
[
new RegExp(/(schema)(\s+)(\d\.\d)/),
[theme_1.OpenFgaDslThemeToken.KEYWORD_SCHEMA, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_SCHEMA],
],
[
new RegExp(/(module)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.KEYWORD_MODULE, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_MODULE],
],
[
new RegExp(/(extend)(\s+)(type)(\s+)(@identifiers)/),
[
theme_1.OpenFgaDslThemeToken.KEYWORD_EXTEND,
"@whitespace",
theme_1.OpenFgaDslThemeToken.KEYWORD_TYPE,
"@whitespace",
theme_1.OpenFgaDslThemeToken.VALUE_TYPE_NAME,
],
],
[
new RegExp(/(type)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.KEYWORD_TYPE, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_TYPE_NAME],
],
[
new RegExp(/(define)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.KEYWORD_DEFINE, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_RELATION_NAME],
],
[
new RegExp(/(or)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.OPERATOR_OR, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_RELATION_COMPUTED],
],
[
new RegExp(/(and)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.OPERATOR_AND, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_RELATION_COMPUTED],
],
[
new RegExp(/(but not)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.OPERATOR_BUT_NOT, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_RELATION_COMPUTED],
],
[
new RegExp(/(as)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.KEYWORD_AS, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_RELATION_COMPUTED],
],
[
new RegExp(/(:)(\s+)(@identifiers)/),
[theme_1.OpenFgaDslThemeToken.DELIMITER_DEFINE_COLON, "@whitespace", theme_1.OpenFgaDslThemeToken.VALUE_RELATION_COMPUTED],
],
[
new RegExp(/(@identifiers)(\s+)(from)(\s+)(@identifiers)/),
[
theme_1.OpenFgaDslThemeToken.VALUE_RELATION_TUPLE_TO_USERSET_COMPUTED,
"@whitespace",
theme_1.OpenFgaDslThemeToken.KEYWORD_FROM,
"@whitespace",
theme_1.OpenFgaDslThemeToken.VALUE_RELATION_TUPLE_TO_USERSET_TUPLESET,
],
],
[
new RegExp(/(@identifiers)(\s*)(:)(\s*)(@identifiers)(<@identifiers>)(,?)(\s*)/),
[
theme_1.OpenFgaDslThemeToken.CONDITION_PARAM,
"@whitespace",
theme_1.OpenFgaDslThemeToken.DELIMITER_COLON_CONDITION_PARAM,
"@whitespace",
theme_1.OpenFgaDslThemeToken.CONDITION_PARAM_TYPE,
theme_1.OpenFgaDslThemeToken.CONDITION_PARAM_TYPE,
theme_1.OpenFgaDslThemeToken.DELIMITER_COMMA_CONDITION_PARAM,
"@whitespace",
],
],
[
new RegExp(/(@identifiers)(\s*)(:)(\s*)(@identifiers)(,?)(\s*)/),
[
theme_1.OpenFgaDslThemeToken.CONDITION_PARAM,
"@whitespace",
theme_1.OpenFgaDslThemeToken.DELIMITER_COLON_CONDITION_PARAM,
"@whitespace",
theme_1.OpenFgaDslThemeToken.CONDITION_PARAM_TYPE,
theme_1.OpenFgaDslThemeToken.DELIMITER_COMMA_CONDITION_PARAM,
"@whitespace",
],
],
[
new RegExp(/(condition)(\s*)(@identifiers)(\s*)(\()/),
[
theme_1.OpenFgaDslThemeToken.KEYWORD_CONDITION,
"@whitespace",
theme_1.OpenFgaDslThemeToken.VALUE_CONDITION,
"@whitespace",
"@brackets",
],
],
[":", theme_1.OpenFgaDslThemeToken.DELIMITER_DEFINE_COLON],
[",", theme_1.OpenFgaDslThemeToken.DELIMITER_COMMA_TYPE_RESTRICTIONS],
[keyword_1.Keyword.BUT_NOT, theme_1.OpenFgaDslThemeToken.OPERATOR_BUT_NOT],
[keyword_1.Keyword.SELF, theme_1.OpenFgaDslThemeToken.KEYWORD_SELF],
[
new RegExp(/@identifiers/),
{
cases: {
[keyword_1.Keyword.AND]: theme_1.OpenFgaDslThemeToken.OPERATOR_AND,
[keyword_1.Keyword.OR]: theme_1.OpenFgaDslThemeToken.OPERATOR_OR,
[keyword_1.Keyword.TYPE]: theme_1.OpenFgaDslThemeToken.KEYWORD_TYPE,
[keyword_1.Keyword.RELATIONS]: theme_1.OpenFgaDslThemeToken.KEYWORD_RELATIONS,
[keyword_1.Keyword.DEFINE]: theme_1.OpenFgaDslThemeToken.KEYWORD_DEFINE,
[keyword_1.Keyword.FROM]: theme_1.OpenFgaDslThemeToken.KEYWORD_FROM,
[keyword_1.Keyword.WITH]: theme_1.OpenFgaDslThemeToken.KEYWORD_WITH,
[keyword_1.Keyword.CONDITION]: theme_1.OpenFgaDslThemeToken.KEYWORD_CONDITION,
[keyword_1.Keyword.AS]: theme_1.OpenFgaDslThemeToken.KEYWORD_AS,
[keyword_1.Keyword.MODEL]: theme_1.OpenFgaDslThemeToken.KEYWORD_MODEL,
[keyword_1.Keyword.SCHEMA]: { token: theme_1.OpenFgaDslThemeToken.KEYWORD_SCHEMA },
// TODO: This should be "identifier", however because tupleset was not properly
// detected with the rules above, this is the quickiest hacky fix we can do to
// get it out there for people to use
"@default": theme_1.OpenFgaDslThemeToken.VALUE_RELATION_TUPLE_TO_USERSET_TUPLESET,
},
},
],
],
cel_symbols: [
[/"/, "string", "@string_double"],
[/'/, "string", "@string_single"],
[/(\w|-[a-zA-Z])+/, theme_1.OpenFgaDslThemeToken.CONDITION_SYMBOL],
[/(<|<=|>=|>|=|!=|&&|\|\||\.|null|in)/, theme_1.OpenFgaDslThemeToken.CONDITION_SYMBOL],
[/\[|\]|\(|\)/, "@brackets"],
[/\}/, "@brackets", "@pop"],
],
string_double: [
[/[^\\"]+/, "string"],
[/\\./, "string.escape.invalid"],
[/"/, "string", "@pop"],
],
string_single: [
[/[^\\']+/, "string"],
[/\\./, "string.escape.invalid"],
[/'/, "string", "@pop"],
],
restrictions: [
{ include: "@whitespace" },
[new RegExp(`${keyword_1.Keyword.WITH}`), theme_1.OpenFgaDslThemeToken.KEYWORD_WITH],
[/(\w|-[a-zA-Z])+/, theme_1.OpenFgaDslThemeToken.VALUE_TYPE_RESTRICTIONS_TYPE],
[
/(:)(\*)/,
[theme_1.OpenFgaDslThemeToken.DELIMITER_COLON_TYPE_RESTRICTIONS, theme_1.OpenFgaDslThemeToken.VALUE_TYPE_RESTRICTIONS_WILDCARD],
],
[/#/, theme_1.OpenFgaDslThemeToken.DELIMITER_HASHTAG_TYPE_RESTRICTIONS],
[/,/, theme_1.OpenFgaDslThemeToken.DELIMITER_COMMA_TYPE_RESTRICTIONS],
[/\]/, "@brackets", "@pop"],
],
// Deal with white space, including comments
whitespace: [[new RegExp(/\s+/), "white"]],
comment: [
[new RegExp(/\s+(#.*)/), theme_1.OpenFgaDslThemeToken.COMMENT],
[new RegExp(/^\s*(#.*)/), theme_1.OpenFgaDslThemeToken.COMMENT],
],
},
};