{"version":3,"file":"index.mjs","names":["singleLineComment","multiLineComment","comment","whitespace","lexeme","identifier","colon","dot","lbrace","rbrace","lparen","rparen","comma","stringLiteral","multiplication: Parser<unknown>","addition: Parser<unknown>","relation: Parser<unknown>","relation","conditionalAnd: Parser<unknown>","conditionalOr: Parser<unknown>","celExpression: Parser<unknown>","expr","withCaveat: Parser<WithCaveat>","withExpiration: Parser<WithExpiration>","typeRef: Parser<TypeRef>","withCaveat","withExpiration","typeExpr: Parser<TypeExpr>","relationReference: Parser<ParsedRelationRefExpression>","arrowExpr: Parser<ParsedArrowExpression>","namedArrowExpr: Parser<ParsedNamedArrowExpression>","nilExpr: Parser<ParsedNilExpression>","operator","annotationTypeRef: Parser<TypeRef>","permissionTypeAnnotation: Parser<TypeExpr>","permission: Parser<ParsedPermission>","relation: Parser<ParsedRelation>","partialReference: Parser<PartialReference>","definitionMember: Parser<DefinitionMember>","useFlag: Parser<ParsedUseFlag>","importExpression: Parser<ParsedImportExpression>","path","member","definition: Parser<ParsedObjectDefinition>","partial: Parser<ParsedPartialDefinition>","caveatParameterTypeExpr: Parser<ParsedCaveatParameterTypeRef>","caveatParameter: Parser<ParsedCaveatParameter>","caveatExpression: Parser<ParsedCaveatExpression>","caveat: Parser<ParsedCaveatDefinition>","permission","relation","typeRef","typeRef","definition","names: Array<string>","emptyRange: TextRange"],"sources":["../src/cel.ts","../src/dsl.ts","../src/resolution.ts"],"sourcesContent":["import type { Parser } from \"parsimmon\";\nimport { optWhitespace, regex, string, seq, lazy } from \"parsimmon\";\n\nconst singleLineComment = regex(/\\/\\/.*/).then(optWhitespace.atMost(1));\nconst multiLineComment = regex(/\\/\\*((((?!\\*\\/).)|\\r|\\n)*)\\*\\//).then(\n  optWhitespace.atMost(1),\n);\n\nconst comment = singleLineComment.or(multiLineComment);\nconst whitespace = optWhitespace.then(comment.atLeast(0));\nconst lexeme = function (p: Parser<string>) {\n  return p.skip(whitespace);\n};\n\n/*\n * These are reserved keywords in CEL, here for documentation.\nconst _reserved = [\n  \"in\",\n  \"as\",\n  \"break\",\n  \"const\",\n  \"continue\",\n  \"else\",\n  \"for\",\n  \"function\",\n  \"if\",\n  \"import\",\n  \"let\",\n  \"loop\",\n  \"package\",\n  \"namespace\",\n  \"return\",\n  \"var\",\n  \"void\",\n  \"while\",\n];\n*/\n\nconst identifier = lexeme(regex(/[a-zA-Z_][0-9a-zA-Z_+]*/));\n\nconst questionMark = lexeme(string(\"?\"));\nconst colon = lexeme(string(\":\"));\nconst orToken = lexeme(string(\"||\"));\nconst andToken = lexeme(string(\"&&\"));\nconst bang = lexeme(string(\"!\"));\nconst dot = lexeme(string(\".\"));\nconst dash = lexeme(string(\"-\"));\nconst lbracket = lexeme(string(\"[\"));\nconst rbracket = lexeme(string(\"]\"));\nconst lbrace = lexeme(string(\"{\"));\nconst rbrace = lexeme(string(\"}\"));\nconst lparen = lexeme(string(\"(\"));\nconst rparen = lexeme(string(\")\"));\nconst comma = lexeme(string(\",\"));\n\n// Based on: https://github.com/google/cel-spec/blob/master/doc/langdef.md#syntax\n\nconst numberLiteral = lexeme(regex(/[+-]?([0-9]*[.])?[0-9]+(u?)(e[0-9]+)?/));\nconst boolLiteral = lexeme(string(\"true\")).or(lexeme(string(\"false\")));\nconst nullLiteral = lexeme(string(\"null\"));\n\n// STRING_LIT     ::= [rR]? ( \"    ~( \" | NEWLINE )*  \"\n// | '    ~( ' | NEWLINE )*  '\n// | \"\"\"  ~\"\"\"*              \"\"\"\n// | '''  ~'''*              '''\n// )\nconst regexPrefix = lexeme(string(\"r\")).or(lexeme(string(\"R\")));\nconst singleQuotedString = lexeme(regex(/'((?:\\\\.|.)*?)'/));\nconst doubleQuotedString = lexeme(regex(/\"((?:\\\\.|.)*?)\"/));\nconst multilineString = lexeme(regex(/\"\"\"((((?!\"\"\").)|\\r|\\n)*)\"\"\"/)).or(\n  lexeme(regex(/'''((((?!''').)|\\r|\\n)*)'''/)),\n);\n\nconst stringLiteral = seq(\n  regexPrefix.atMost(1),\n  multilineString.or(singleQuotedString.or(doubleQuotedString)),\n);\n\n// BYTES_LIT      ::= [bB] STRING_LIT\nconst bytesPrefix = lexeme(string(\"b\")).or(lexeme(string(\"B\")));\nconst bytesLiteral = seq(bytesPrefix, stringLiteral);\n\n// LITERAL        ::= INT_LIT | UINT_LIT | FLOAT_LIT | STRING_LIT | BYTES_LIT | BOOL_LIT | NULL_LIT\nconst literal = numberLiteral\n  .or(stringLiteral)\n  .or(boolLiteral)\n  .or(nullLiteral)\n  .or(bytesLiteral);\n\nconst expression = lazy(() => celExpression);\n\n// MapInits       = Expr \":\" Expr {\",\" Expr \":\" Expr} ;\nconst mapInits = seq(\n  expression,\n  colon,\n  expression,\n  seq(comma, expression, colon, expression).atLeast(0),\n);\n\n// FieldInits     = IDENT \":\" Expr {\",\" IDENT \":\" Expr} ;\nconst fieldInits = seq(\n  identifier,\n  colon,\n  expression,\n  seq(comma, identifier, colon, expression).atLeast(0),\n);\n\n// Primary        = [\".\"] IDENT [\"(\" [ExprList] \")\"]\n// | \"(\" Expr \")\"\n// | \"[\" [ExprList] [\",\"] \"]\"\n// | \"{\" [MapInits] [\",\"] \"}\"\n// | [\".\"] IDENT { \".\" IDENT } \"{\" [FieldInits] [\",\"] \"}\"\n// | LITERAL\n// NOTE: some skipped because not necessary here with the reordering below of member.\nconst primary = literal\n  .or(seq(lparen, expression, rparen))\n  .or(\n    seq(\n      lbracket,\n      lazy(() => exprList),\n      rbracket,\n    ),\n  )\n  .or(seq(lbrace, mapInits, rbrace))\n  .or(identifier);\n\n// ExprList       = Expr {\",\" Expr} ;\nconst exprList = expression.then(seq(comma, expression).atLeast(0));\n\n// Member         = Primary | Member \".\" IDENT [\"(\" [ExprList] \")\"] | Member \"[\" Expr \"]\"\n// NOTE: reordered here to allow for parsing by Parsimmon\nconst member = seq(\n  primary.then(\n    seq(\n      dot,\n      identifier,\n      seq(lparen, exprList.atMost(1), rparen)\n        .or(seq(lbrace, fieldInits, rbrace))\n        .atLeast(0),\n    )\n      .or(seq(lbracket, expression, rbracket))\n      .atLeast(0),\n  ),\n);\n\n// Unary          = Member | \"!\" {\"!\"} Member | \"-\" {\"-\"} Member\nconst unary = seq(\n  member.or(bang.atLeast(1).then(member)).or(dash.atLeast(1).then(member)),\n);\n\n// Multiplication = [Multiplication (\"*\" | \"/\" | \"%\")] Unary ;\n// NOTE: reordered here to allow for parsing by Parsimmon\nconst multiplicationOp = lexeme(string(\"*\"))\n  .or(lexeme(string(\"/\")))\n  .or(lexeme(string(\"%\")));\nconst multiplication: Parser<unknown> = seq(\n  unary,\n  seq(\n    multiplicationOp,\n    lazy(() => multiplication),\n  ).atMost(1),\n);\n\n// Addition       = [Addition (\"+\" | \"-\")] Multiplication ;\n// NOTE: reordered here to allow for parsing by Parsimmon\nconst additionOp = lexeme(string(\"+\")).or(lexeme(string(\"-\")));\nconst addition: Parser<unknown> = seq(\n  multiplication,\n  seq(\n    additionOp,\n    lazy(() => addition),\n  ).atMost(1),\n);\n\n// Relop          = \"<\" | \"<=\" | \">=\" | \">\" | \"==\" | \"!=\" | \"in\" ;\nconst relOp = lexeme(string(\"<\"))\n  .or(lexeme(string(\"<=\")))\n  .or(lexeme(string(\">=\")))\n  .or(lexeme(string(\">\")))\n  .or(lexeme(string(\"==\")))\n  .or(lexeme(string(\"!=\")))\n  .or(lexeme(string(\"in\")));\n\n// Relation       = [Relation Relop] Addition ;\n// NOTE: reordered here to allow for parsing by Parsimmon\nconst relation: Parser<unknown> = seq(\n  addition,\n  seq(\n    relOp,\n    lazy(() => relation),\n  ).atMost(1),\n);\n\n// ConditionalAnd = [ConditionalAnd \"&&\"] Relation ;\n// NOTE: reordered here to allow for parsing by Parsimmon\nconst conditionalAnd: Parser<unknown> = seq(\n  relation,\n  seq(\n    andToken,\n    lazy(() => conditionalAnd),\n  ).atMost(1),\n);\n\n// ConditionalOr  = [ConditionalOr \"||\"] ConditionalAnd ;\n// NOTE: reordered here to allow for parsing by Parsimmon\nconst conditionalOr: Parser<unknown> = seq(\n  conditionalAnd,\n  seq(\n    orToken,\n    lazy(() => conditionalOr),\n  ).atMost(1),\n);\n\n// Expr = ConditionalOr [\"?\" ConditionalOr \":\" Expr] ;\nexport const celExpression: Parser<unknown> = conditionalOr.then(\n  seq(\n    questionMark,\n    conditionalOr,\n    colon,\n    lazy(() => celExpression),\n  ).atMost(1),\n);\n\nexport const parseCELExpression = (value: string) => {\n  const result = whitespace.then(celExpression).parse(value);\n  return result.status;\n};\n","import type { Parser } from \"parsimmon\";\nimport {\n  formatError,\n  index,\n  regex,\n  lazy,\n  optWhitespace,\n  string,\n  seqMap,\n  newline,\n  seq,\n  takeWhile,\n} from \"parsimmon\";\nimport { celExpression } from \"./cel\";\n\n/**\n * ParseResult is the result of a direct parse.\n */\nexport type ParseResult = {\n  /**\n   * error is the parsing error found, if any.\n   */\n  error: ParseError | undefined;\n\n  /**\n   * schema is the fully parsed schema, if no error.\n   */\n  schema: ParsedSchema | undefined;\n};\n\n/**\n * ParseError represents an error raised by the parser.\n */\nexport type ParseError = {\n  /**\n   * message is the human-readable error message.\n   */\n  message: string;\n\n  /**\n   * index is the location of the parse error.\n   */\n  index: Index;\n\n  /**\n   * expected is the set of expected regular expression(s) at the index.\n   */\n  expected: Array<string>;\n};\n\n/**\n * parseSchema parses a DSL schema, returning relevant semantic information\n * or undefined if the parse failed.\n */\nexport const parseSchema = (value: string): ParsedSchema | undefined => {\n  const parsed = parse(value);\n  if (parsed.error) {\n    return undefined;\n  }\n\n  return parsed.schema;\n};\n\n/**\n * TopLevelDefinition are the types of definitions found at the root of a schema.\n */\nexport type TopLevelDefinition =\n  | ParsedObjectDefinition\n  | ParsedCaveatDefinition\n  | ParsedPartialDefinition\n  | ParsedImportExpression\n  | ParsedUseFlag;\n\n/**\n * parse performs a parse on the schema string, returning the full parse result.\n */\nexport function parse(input: string): ParseResult {\n  const result = whitespace.then(topLevel.atLeast(0)).parse(input);\n  return {\n    error: !result.status\n      ? {\n          message: formatError(input, result),\n          index: result.index,\n          expected: result.expected,\n        }\n      : undefined,\n    schema: result.status\n      ? {\n          kind: \"schema\",\n          stringValue: input,\n          definitions: result.value,\n        }\n      : undefined,\n  };\n}\n\n/**\n * getCaveatExpression returns the string form of the caveat expression for a particular parsed\n * caveat expression within a schema.\n */\nexport function getCaveatExpression(\n  expr: ParsedCaveatExpression,\n  parsed: ParsedSchema,\n): string {\n  return parsed.stringValue.substring(\n    expr.range.startIndex.offset,\n    expr.range.endIndex.offset,\n  );\n}\n\n/**\n * flatMapExpression runs a flat mapping operation over an expression tree, returning any found results.\n */\nexport function flatMapExpression<T>(\n  expr: ParsedExpression,\n  walker: ExprWalker<T>,\n): Array<T> {\n  switch (expr.kind) {\n    case \"namedarrow\":\n    // fallthrough\n\n    case \"arrow\": {\n      const arrowResult = walker(expr);\n      const childResults = flatMapExpression<T>(expr.sourceRelation, walker);\n      return arrowResult ? [...childResults, arrowResult] : childResults;\n    }\n\n    case \"nil\": {\n      const nilResult = walker(expr);\n      return nilResult ? [nilResult] : [];\n    }\n\n    case \"relationref\": {\n      const result = walker(expr);\n      return result ? [result] : [];\n    }\n\n    case \"binary\": {\n      const binResult = walker(expr);\n      const leftResults = flatMapExpression<T>(expr.left, walker);\n      const rightResults = flatMapExpression<T>(expr.right, walker);\n      return binResult\n        ? [...leftResults, ...rightResults, binResult]\n        : [...leftResults, ...rightResults];\n    }\n  }\n}\n\n/**\n * ReferenceNode is the node returned by findReferenceNode, along with its parent definition,\n * if any.\n */\nexport type ReferenceNode = {\n  node: ParsedRelationRefExpression | TypeRef | undefined;\n  def: TopLevelDefinition;\n};\n\n/**\n * findReferenceNode walks the parse tree to find the node matching the given line number and\n * column position.\n */\nexport function findReferenceNode(\n  schema: ParsedSchema,\n  lineNumber: number,\n  columnPosition: number,\n): ReferenceNode | undefined {\n  const found = schema.definitions\n    .map((def: TopLevelDefinition) => {\n      if (!rangeContains(def, lineNumber, columnPosition)) {\n        return undefined;\n      }\n\n      if (def.kind === \"objectDef\") {\n        return findReferenceNodeInDef(def, lineNumber, columnPosition);\n      }\n      return undefined;\n    })\n    .filter((f: ReferenceNode | undefined) => !!f);\n  return found.length > 0 ? found[0] : undefined;\n}\n\n/**\n * mapParsedSchema runs the given mapper function on every node in the parse tree (except the\n * contents of a caveat, which are considered \"opaque\").\n */\nexport function mapParsedSchema(\n  schema: ParsedSchema | undefined,\n  mapper: (node: ParsedNode) => void,\n) {\n  if (schema === undefined) {\n    return;\n  }\n\n  schema.definitions.forEach(mapParseNodes(mapper));\n}\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Parser node types\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nexport type ParsedSchema = {\n  kind: \"schema\";\n  stringValue: string;\n  // TODO: it may make sense to split uses and imports out.\n  definitions: Array<TopLevelDefinition>;\n};\n\nexport type ParsedUseFlag = {\n  kind: \"use\";\n  featureName: string;\n  range: TextRange;\n};\n\nexport type ParsedImportExpression = {\n  kind: \"import\";\n  path: string;\n  range: TextRange;\n};\n\nexport type ParsedCaveatDefinition = {\n  kind: \"caveatDef\";\n  name: string;\n  parameters: Array<ParsedCaveatParameter>;\n  expression: ParsedCaveatExpression;\n  range: TextRange;\n};\n\nexport type ParsedCaveatExpression = {\n  kind: \"caveatExpr\";\n  range: TextRange;\n};\n\nexport type ParsedCaveatParameter = {\n  kind: \"caveatParameter\";\n  name: string;\n  type: ParsedCaveatParameterTypeRef;\n  range: TextRange;\n};\n\nexport type ParsedCaveatParameterTypeRef = {\n  kind: \"caveatParameterTypeExpr\";\n  name: string;\n  generics: Array<ParsedCaveatParameterTypeRef>;\n  range: TextRange;\n};\n\nexport type ParsedObjectDefinition = {\n  kind: \"objectDef\";\n  name: string;\n  relations: Array<ParsedRelation>;\n  permissions: Array<ParsedPermission>;\n  partialReferences: Array<PartialReference>;\n  range: TextRange;\n};\n\nexport type ParsedPartialDefinition = {\n  kind: \"partial\";\n  name: string;\n  relations: Array<ParsedRelation>;\n  permissions: Array<ParsedPermission>;\n  partialReferences: Array<PartialReference>;\n  range: TextRange;\n};\n\ntype PartialReference = {\n  kind: \"partialreference\";\n  name: string;\n  range: TextRange;\n};\n\nexport type ParsedRelation = {\n  kind: \"relation\";\n  name: string;\n  allowedTypes: TypeExpr;\n  range: TextRange;\n};\n\nexport type ParsedExpression =\n  | ParsedBinaryExpression\n  | ParsedRelationRefExpression\n  | ParsedArrowExpression\n  | ParsedNamedArrowExpression\n  | ParsedNilExpression;\n\nexport type ParsedArrowExpression = {\n  kind: \"arrow\";\n  sourceRelation: ParsedRelationRefExpression;\n  targetRelationOrPermission: string;\n  range: TextRange;\n};\n\nexport type ParsedNamedArrowExpression = {\n  kind: \"namedarrow\";\n  sourceRelation: ParsedRelationRefExpression;\n  functionName: string;\n  targetRelationOrPermission: string;\n  range: TextRange;\n};\n\nexport type ParsedRelationRefExpression = {\n  kind: \"relationref\";\n  relationName: string;\n  range: TextRange;\n};\n\nexport type ParsedNilExpression = {\n  kind: \"nil\";\n  isNil: true;\n  range: TextRange;\n};\n\nexport type ParsedBinaryExpression = {\n  kind: \"binary\";\n  operator: \"union\" | \"intersection\" | \"exclusion\";\n  left: ParsedExpression;\n  right: ParsedExpression;\n  range: TextRange;\n};\n\nexport type ParsedPermission = {\n  kind: \"permission\";\n  name: string;\n  /**\n   * annotatedTypes is the optional `use typechecking` return-type annotation on the\n   * permission (e.g. `permission view: user | group = ...`), or undefined if none was\n   * written. Each annotated type is a plain type reference to a definition.\n   */\n  annotatedTypes: TypeExpr | undefined;\n  expr: ParsedExpression;\n  range: TextRange;\n};\n\nexport type DefinitionMember =\n  | ParsedRelation\n  | ParsedPermission\n  | PartialReference;\n\nexport type TypeRef = {\n  kind: \"typeref\";\n  path: string;\n  relationName: string | undefined;\n  wildcard: boolean;\n  withCaveat: WithCaveat | undefined;\n  withExpiration: WithExpiration | undefined;\n  range: TextRange;\n};\n\nexport type WithExpiration = {\n  kind: \"withexpiration\";\n  range: TextRange;\n};\n\nexport type WithCaveat = {\n  kind: \"withcaveat\";\n  path: string;\n  range: TextRange;\n};\n\nexport type TypeExpr = {\n  kind: \"typeexpr\";\n  types: Array<TypeRef>;\n  range: TextRange;\n};\n\nexport type ParsedNode =\n  | ParsedUseFlag\n  | ParsedImportExpression\n  | ParsedCaveatDefinition\n  | ParsedCaveatParameter\n  | ParsedCaveatParameterTypeRef\n  | ParsedCaveatExpression\n  | ParsedObjectDefinition\n  | ParsedPartialDefinition\n  | ParsedRelation\n  | ParsedPermission\n  | ParsedExpression\n  | TypeRef\n  | TypeExpr\n  | WithCaveat;\n\nexport type Index = {\n  offset: number;\n  line: number;\n  column: number;\n};\n\nexport type TextRange = {\n  startIndex: Index;\n  endIndex: Index;\n};\n\nexport type ExprWalker<T> = (expr: ParsedExpression) => T | undefined;\n\n////////////////////////////////////////////////////////////////////////////////////////////////////\n// Parser and utility methods below\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\nconst singleLineComment = regex(/\\/\\/.*/).then(optWhitespace.atMost(1));\nconst multiLineComment = regex(/\\/\\*((((?!\\*\\/).)|\\r|\\n)*)\\*\\//).then(\n  optWhitespace.atMost(1),\n);\n\nconst comment = singleLineComment.or(multiLineComment);\nconst whitespace = optWhitespace.then(comment.atLeast(0));\nconst lexeme = function (p: Parser<string>) {\n  return p.skip(whitespace);\n};\n\nconst identifier = lexeme(regex(/[a-zA-Z_][0-9a-zA-Z_+]*/));\nconst path = lexeme(\n  regex(/([a-zA-Z_][0-9a-zA-Z_+-]*\\/)*[a-zA-Z_][0-9a-zA-Z_+-]*/),\n);\nconst colon = lexeme(string(\":\"));\nconst equal = lexeme(string(\"=\"));\nconst semicolon = lexeme(string(\";\"));\nconst pipe = lexeme(string(\"|\"));\n\nconst lbrace = lexeme(string(\"{\"));\nconst rbrace = lexeme(string(\"}\"));\nconst lparen = lexeme(string(\"(\"));\nconst rparen = lexeme(string(\")\"));\nconst lcaret = lexeme(string(\"<\"));\nconst rcaret = lexeme(string(\">\"));\nconst arrow = lexeme(string(\"->\"));\nconst hash = lexeme(string(\"#\"));\nconst comma = lexeme(string(\",\"));\nconst dot = lexeme(string(\".\"));\nconst ellipsis = lexeme(string(\"...\"));\n\nconst terminator = newline.or(semicolon);\n\n// Take a single or a doublequote,\n// consume while the next character isn't that first delimiter,\n// then skip that last delimiter\nexport const stringLiteral = string(\"'\")\n  .or(string('\"'))\n  .chain((delimiter) =>\n    takeWhile((c) => c !== delimiter).skip(string(delimiter)),\n  );\n\n// Type reference and expression.\n\nconst andExpiration = seqMap(\n  index,\n  seq(lexeme(string(\"and\")), lexeme(string(\"expiration\"))),\n  index,\n  function (startIndex, _data, endIndex) {\n    return {\n      kind: \"withexpiration\",\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst withCaveat: Parser<WithCaveat> = seqMap(\n  index,\n  seq(lexeme(string(\"with\")), path, andExpiration.atMost(1)),\n  index,\n  function (startIndex, data, endIndex) {\n    return {\n      kind: \"withcaveat\",\n      path: data[1],\n      withExpiration: data[2],\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst withExpiration: Parser<WithExpiration> = seqMap(\n  index,\n  seq(lexeme(string(\"with\")), lexeme(string(\"expiration\"))),\n  index,\n  function (startIndex, _data, endIndex) {\n    return {\n      kind: \"withexpiration\",\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst typeRef: Parser<TypeRef> = seqMap(\n  index,\n  seq(\n    seq(path, colon, lexeme(string(\"*\"))).or(\n      seq(path, hash.then(identifier).atMost(1)),\n    ),\n    withCaveat.or(withExpiration).atMost(1),\n  ),\n  index,\n  function (startIndex, data, endIndex) {\n    const isWildcard = data[0][2] === \"*\";\n    const withCaveat = data[1].find((trait) => trait.kind === \"withcaveat\");\n    const withExpiration = data[1].find(\n      (trait) => trait.kind === \"withexpiration\",\n    );\n    return {\n      kind: \"typeref\",\n      path: data[0][0],\n      relationName: isWildcard ? undefined : data[0][1][0],\n      wildcard: isWildcard,\n      withCaveat,\n      withExpiration,\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst typeExpr: Parser<TypeExpr> = lazy(() => {\n  return seqMap(\n    index,\n    seq(typeRef, pipedTypeExpr.atLeast(0)),\n    index,\n    function (startIndex, data, endIndex) {\n      const remaining = data[1];\n      return {\n        kind: \"typeexpr\",\n        types: [data[0], ...remaining],\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst pipedTypeExpr = pipe.then(typeRef);\n\n// Permission expression.\n// Based on: https://github.com/jneen/parsimmon/blob/93648e20f40c5c0335ac6506b39b0ca58b87b1d9/examples/math.js#L29\nconst relationReference: Parser<ParsedRelationRefExpression> = lazy(() => {\n  return seqMap(\n    index,\n    seq(identifier),\n    index,\n    function (startIndex, data, endIndex) {\n      return {\n        kind: \"relationref\",\n        relationName: data[0],\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst arrowExpr: Parser<ParsedArrowExpression> = lazy(() => {\n  return seqMap(\n    index,\n    seq(relationReference, arrow, identifier),\n    index,\n    function (startIndex, data, endIndex) {\n      return {\n        kind: \"arrow\",\n        sourceRelation: data[0],\n        targetRelationOrPermission: data[2],\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst namedArrowExpr: Parser<ParsedNamedArrowExpression> = lazy(() => {\n  return seqMap(\n    index,\n    seq(relationReference, dot, identifier, lparen, identifier, rparen),\n    index,\n    function (startIndex, data, endIndex) {\n      return {\n        kind: \"namedarrow\",\n        sourceRelation: data[0],\n        functionName: data[2],\n        targetRelationOrPermission: data[4],\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst nilExpr: Parser<ParsedNilExpression> = lazy(() => {\n  return seqMap(\n    index,\n    string(\"nil\"),\n    index,\n    function (startIndex, _data, endIndex) {\n      return {\n        kind: \"nil\",\n        isNil: true,\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst parensExpr = lazy(() =>\n  string(\"(\")\n    .then(expr)\n    .skip(string(\")\"))\n    .or(arrowExpr)\n    .or(namedArrowExpr)\n    .or(nilExpr)\n    .or(relationReference),\n);\n\nfunction BINARY_LEFT(\n  operatorsParser: Parser<OperatorType>,\n  nextParser: Parser<ParsedExpression>,\n) {\n  return seqMap(\n    nextParser,\n    seq(operatorsParser, nextParser).many(),\n    (first, rest) => {\n      return rest.reduce((acc, ch): ParsedBinaryExpression => {\n        const [operator, another] = ch;\n        return {\n          kind: \"binary\",\n          operator,\n          left: acc,\n          right: another,\n          range: {\n            startIndex: acc.range.startIndex,\n            endIndex: another.range.endIndex,\n          },\n        };\n      }, first);\n    },\n  );\n}\n\ntype OperatorType = \"union\" | \"intersection\" | \"exclusion\";\n\nfunction operator(operation: OperatorType, symbol: string) {\n  return string(symbol).trim(optWhitespace).result(operation);\n}\n\nconst table = [\n  { type: BINARY_LEFT, ops: operator(\"union\", \"+\") },\n  { type: BINARY_LEFT, ops: operator(\"intersection\", \"&\") },\n  { type: BINARY_LEFT, ops: operator(\"exclusion\", \"-\") },\n] as const;\n\nconst tableParser: Parser<ParsedExpression> = table.reduce(\n  (acc, level) => level.type(level.ops, acc),\n  parensExpr,\n);\n\nconst expr = tableParser.trim(whitespace);\n\n// Permission type annotation (the `use typechecking` return-type annotation).\n// Unlike a relation's allowed types, an annotation is a pipe-separated list of plain\n// type identifiers -- no wildcards, subrelations, caveats, or expiration -- matching\n// the SpiceDB grammar `permission foo: user | group = ...`.\nconst annotationTypeRef: Parser<TypeRef> = seqMap(\n  index,\n  identifier,\n  index,\n  function (startIndex, name, endIndex) {\n    return {\n      kind: \"typeref\",\n      path: name,\n      relationName: undefined,\n      wildcard: false,\n      withCaveat: undefined,\n      withExpiration: undefined,\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst pipedAnnotationTypeRef = pipe.then(annotationTypeRef);\n\nconst permissionTypeAnnotation: Parser<TypeExpr> = seqMap(\n  index,\n  seq(annotationTypeRef, pipedAnnotationTypeRef.atLeast(0)),\n  index,\n  function (startIndex, data, endIndex) {\n    const remaining = data[1];\n    return {\n      kind: \"typeexpr\",\n      types: [data[0], ...remaining],\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\n// Definitions members.\nconst permission: Parser<ParsedPermission> = seqMap(\n  index,\n  seq(\n    lexeme(string(\"permission\")),\n    identifier,\n    colon.then(permissionTypeAnnotation).atMost(1),\n    equal.then(expr).skip(terminator.atMost(1)),\n  ),\n  index,\n  function (startIndex, data, endIndex) {\n    return {\n      kind: \"permission\",\n      name: data[1],\n      annotatedTypes: data[2][0],\n      expr: data[3],\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst relation: Parser<ParsedRelation> = seqMap(\n  index,\n  seq(\n    lexeme(string(\"relation\")),\n    identifier,\n    colon.then(typeExpr).skip(terminator.atMost(1)),\n  ),\n  index,\n  function (startIndex, [_, name, allowedTypes], endIndex) {\n    return {\n      kind: \"relation\",\n      name,\n      allowedTypes,\n      range: { startIndex, endIndex },\n    };\n  },\n);\n\nconst partialReference: Parser<PartialReference> = seqMap(\n  index,\n  seq(ellipsis, identifier, terminator.atMost(1)),\n  index,\n  function (startIndex, [_, name, __], endIndex) {\n    return {\n      kind: \"partialreference\",\n      name,\n      range: { startIndex, endIndex },\n    };\n  },\n);\n\nconst definitionMember: Parser<DefinitionMember> = relation\n  .or(permission)\n  .or(partialReference);\n\n// Use flags\nconst useFlag: Parser<ParsedUseFlag> = seqMap(\n  index,\n  seq(lexeme(string(\"use\")), identifier, terminator.atMost(1)),\n  index,\n  function (startIndex, [_, featureName, __], endIndex) {\n    return {\n      kind: \"use\",\n      featureName,\n      range: { startIndex, endIndex },\n    };\n  },\n);\n\n// Import expressions\nconst importExpression: Parser<ParsedImportExpression> = seqMap(\n  index,\n  seq(lexeme(string(\"import\")), stringLiteral, terminator.atMost(1)),\n  index,\n  function (startIndex, [_, path, __], endIndex) {\n    return {\n      kind: \"import\",\n      path,\n      range: { startIndex, endIndex },\n    };\n  },\n);\n\nfunction isRelation(member: DefinitionMember): member is ParsedRelation {\n  return member.kind === \"relation\";\n}\n\nfunction isPermission(member: DefinitionMember): member is ParsedPermission {\n  return member.kind === \"permission\";\n}\n\nfunction isPartialReference(\n  member: DefinitionMember,\n): member is PartialReference {\n  return member.kind === \"partialreference\";\n}\n\n// Object Definitions.\nconst definition: Parser<ParsedObjectDefinition> = seqMap(\n  index,\n  seq(\n    lexeme(string(\"definition\")),\n    path,\n    lbrace.then(definitionMember.atLeast(0)).skip(rbrace),\n  ),\n  index,\n  function (startIndex, data, endIndex) {\n    const members = data[2];\n    return {\n      kind: \"objectDef\",\n      name: data[1],\n      relations: members.filter(isRelation),\n      permissions: members.filter(isPermission),\n      partialReferences: members.filter(isPartialReference),\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\n// Partial Definitions.\n// NOTE: these are parsed the same as definitions.\n// TODO: see if this can be combined with objectDef in a sane way\nconst partial: Parser<ParsedPartialDefinition> = seqMap(\n  index,\n  seq(\n    lexeme(string(\"partial\")),\n    path,\n    lbrace.then(definitionMember.atLeast(0)).skip(rbrace),\n  ),\n  index,\n  function (startIndex, data, endIndex) {\n    const members = data[2];\n    return {\n      kind: \"partial\",\n      name: data[1],\n      relations: members.filter(isRelation),\n      permissions: members.filter(isPermission),\n      partialReferences: members.filter(isPartialReference),\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\n// Caveats.\nconst caveatParameterTypeExpr: Parser<ParsedCaveatParameterTypeRef> = lazy(\n  () => {\n    return seqMap(\n      index,\n      seq(\n        identifier,\n        lcaret.then(caveatParameterTypeExpr).skip(rcaret).atMost(1),\n      ),\n      index,\n      function (startIndex, data, endIndex) {\n        return {\n          kind: \"caveatParameterTypeExpr\",\n          name: data[0],\n          generics: data[1],\n          range: { startIndex: startIndex, endIndex: endIndex },\n        };\n      },\n    );\n  },\n);\n\nconst caveatParameter: Parser<ParsedCaveatParameter> = lazy(() => {\n  return seqMap(\n    index,\n    seq(identifier, caveatParameterTypeExpr),\n    index,\n    function (startIndex, data, endIndex) {\n      return {\n        kind: \"caveatParameter\",\n        name: data[0],\n        type: data[1],\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst caveatParameters = lazy(() => {\n  return seqMap(\n    index,\n    seq(lparen, caveatParameter, commaedParameter.atLeast(0), rparen),\n    index,\n    function (startIndex, data, endIndex) {\n      const remaining = data[2];\n      return {\n        kind: \"caveatParameters\",\n        parameters: [data[1], ...remaining],\n        range: { startIndex: startIndex, endIndex: endIndex },\n      };\n    },\n  );\n});\n\nconst commaedParameter = comma.then(caveatParameter);\n\nconst caveatExpression: Parser<ParsedCaveatExpression> = seqMap(\n  index,\n  seq(celExpression),\n  index,\n  function (startIndex, _data, endIndex) {\n    return {\n      kind: \"caveatExpr\",\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst caveat: Parser<ParsedCaveatDefinition> = seqMap(\n  index,\n  seq(\n    lexeme(string(\"caveat\")),\n    path,\n    caveatParameters,\n    lbrace,\n    caveatExpression,\n    rbrace,\n  ),\n  index,\n  function (startIndex, data, endIndex) {\n    return {\n      kind: \"caveatDef\",\n      name: data[1],\n      parameters: data[2].parameters,\n      expression: data[4],\n      range: { startIndex: startIndex, endIndex: endIndex },\n    };\n  },\n);\n\nconst topLevel = definition\n  .or(partial)\n  .or(caveat)\n  .or(useFlag)\n  .or(importExpression);\n\nfunction findReferenceNodeInDef(\n  def: ParsedObjectDefinition,\n  lineNumber: number,\n  columnPosition: number,\n): ReferenceNode | undefined {\n  const pFound = def.permissions\n    .map((permission: ParsedPermission) => {\n      if (!rangeContains(permission, lineNumber, columnPosition)) {\n        return undefined;\n      }\n\n      return findReferenceNodeInPermission(\n        permission,\n        lineNumber,\n        columnPosition,\n      );\n    })\n    .filter((f: ParsedRelationRefExpression | TypeRef | undefined) => !!f);\n\n  if (pFound.length > 0) {\n    return { node: pFound[0], def: def };\n  }\n\n  const rFound = def.relations\n    .map((relation: ParsedRelation) => {\n      if (!rangeContains(relation, lineNumber, columnPosition)) {\n        return undefined;\n      }\n\n      return findReferenceNodeInRelation(relation, lineNumber, columnPosition);\n    })\n    .filter((f: ParsedRelationRefExpression | TypeRef | undefined) => !!f);\n  if (rFound.length > 0) {\n    return { node: rFound[0], def: def };\n  }\n\n  return undefined;\n}\n\nfunction findReferenceNodeInPermission(\n  permission: ParsedPermission,\n  lineNumber: number,\n  columnPosition: number,\n): ParsedRelationRefExpression | TypeRef | undefined {\n  // A `use typechecking` annotation type (e.g. the `user` in `permission view: user = ...`)\n  // is a type reference, so resolve it like a relation's allowed type for go-to-definition.\n  if (permission.annotatedTypes) {\n    const annotatedType = permission.annotatedTypes.types.find(\n      (typeRef: TypeRef) => rangeContains(typeRef, lineNumber, columnPosition),\n    );\n    if (annotatedType) {\n      return annotatedType;\n    }\n  }\n\n  const found = flatMapExpression(permission.expr, (expr: ParsedExpression) => {\n    if (!rangeContains(expr, lineNumber, columnPosition)) {\n      return undefined;\n    }\n\n    switch (expr.kind) {\n      case \"relationref\":\n        return expr;\n    }\n\n    return undefined;\n  });\n\n  return found.length > 0 ? found[0] : undefined;\n}\n\nfunction findReferenceNodeInRelation(\n  relation: ParsedRelation,\n  lineNumber: number,\n  columnPosition: number,\n): ParsedRelationRefExpression | TypeRef | undefined {\n  const found = relation.allowedTypes.types\n    .map((typeRef: TypeRef) => {\n      if (!rangeContains(typeRef, lineNumber, columnPosition)) {\n        return undefined;\n      }\n\n      return typeRef;\n    })\n    .filter((f: ParsedRelationRefExpression | TypeRef | undefined) => !!f);\n\n  return found.length > 0 ? found[0] : undefined;\n}\n\nconst mapParseNodes =\n  (mapper: (node: ParsedNode) => void) => (node: ParsedNode | undefined) => {\n    if (node === undefined) {\n      return;\n    }\n\n    mapper(node);\n\n    switch (node.kind) {\n      case \"objectDef\":\n        node.relations.forEach(mapParseNodes(mapper));\n        node.permissions.forEach(mapParseNodes(mapper));\n        break;\n\n      case \"partial\":\n        node.relations.forEach(mapParseNodes(mapper));\n        node.permissions.forEach(mapParseNodes(mapper));\n        break;\n\n      case \"caveatDef\":\n        node.parameters.forEach(mapParseNodes(mapper));\n        mapParseNodes(mapper)(node.expression);\n        break;\n\n      case \"caveatParameter\":\n        mapParseNodes(mapper)(node.type);\n        break;\n\n      case \"caveatParameterTypeExpr\":\n        node.generics.forEach(mapParseNodes(mapper));\n        break;\n\n      case \"relation\":\n        mapParseNodes(mapper)(node.allowedTypes);\n        break;\n\n      case \"permission\":\n        if (node.annotatedTypes) {\n          mapParseNodes(mapper)(node.annotatedTypes);\n        }\n        flatMapExpression(node.expr, mapper);\n        break;\n\n      case \"typeexpr\":\n        node.types.forEach(mapParseNodes(mapper));\n        break;\n\n      case \"typeref\":\n        mapParseNodes(mapper)(node.withCaveat);\n        break;\n    }\n  };\n\nfunction rangeContains(\n  withRange: { range: TextRange },\n  lineNumber: number,\n  columnPosition: number,\n): boolean {\n  if (\n    withRange.range.startIndex.line > lineNumber ||\n    withRange.range.endIndex.line < lineNumber\n  ) {\n    return false;\n  }\n\n  if (withRange.range.startIndex.line === lineNumber) {\n    if (withRange.range.startIndex.column > columnPosition) {\n      return false;\n    }\n  }\n\n  if (withRange.range.endIndex.line === lineNumber) {\n    if (withRange.range.endIndex.column < columnPosition) {\n      return false;\n    }\n  }\n\n  return true;\n}\n","import type {\n  ParsedCaveatDefinition,\n  ParsedCaveatParameter,\n  ParsedExpression,\n  ParsedObjectDefinition,\n  ParsedPermission,\n  ParsedRelation,\n  ParsedRelationRefExpression,\n  ParsedSchema,\n  TopLevelDefinition,\n  TypeRef,\n  TextRange,\n} from \"./dsl\";\nimport { flatMapExpression } from \"./dsl\";\n\n/**\n * TypeRefResolution is the result of resolving a type reference.\n */\nexport type TypeRefResolution = {\n  /**\n   * definition is the definition which is referred by this type reference.\n   */\n  definition: ParsedObjectDefinition | undefined;\n\n  /**\n   * relation is the (optional) relation which is referred by this type reference. For refs\n   * without relations, this will be undefined. This will *also* be undefined for unresolvable\n   * refs, so make sure to check the expression to see if it has a relation reference.\n   */\n  relation: ParsedRelation | undefined;\n\n  /**\n   * permission is the (optional) permission which is referred by this type reference. For refs\n   * without relations, this will be undefined. This will *also* be undefined for unresolvable\n   * refs, so make sure to check the expression to see if it has a relation reference.\n   */\n  permission: ParsedPermission | undefined;\n};\n\n/**\n * ExpressionResolution is the resolution of a reference in a permission expression.\n */\nexport type ExpressionResolution = ParsedRelation | ParsedPermission;\n\n/**\n * ResolvedTypeReference is a type reference found in the schema, with resolution attempted.\n */\nexport type ResolvedTypeReference = {\n  kind: \"type\";\n  reference: TypeRef;\n  referencedTypeAndRelation: TypeRefResolution | undefined;\n};\n\n/**\n * ResolvedExprReference is a relation reference expression found in the schema, with resolution attempted.\n */\nexport type ResolvedExprReference = {\n  kind: \"expression\";\n  reference: ParsedRelationRefExpression;\n  resolvedRelationOrPermission: ExpressionResolution | undefined;\n};\n\n/**\n * ResolvedReference is a found and resolution performed type reference or expression.\n */\nexport type ResolvedReference = ResolvedTypeReference | ResolvedExprReference;\n\n/**\n * Resolver is a helper class for easily resolving information in a parsed schema.\n */\nexport class Resolver {\n  private definitionsByName: Record<string, ResolvedDefinition> = {};\n  private caveatsByName: Record<string, ResolvedCaveatDefinition> = {};\n  private populated = false;\n  public schema: ParsedSchema = {\n    kind: \"schema\",\n    stringValue: \"\",\n    definitions: [],\n  };\n\n  constructor(schema: ParsedSchema) {\n    this.schema = schema;\n  }\n\n  private populate() {\n    if (this.populated) {\n      return;\n    }\n\n    this.schema.definitions.forEach((def: TopLevelDefinition) => {\n      if (def.kind === \"objectDef\") {\n        this.definitionsByName[def.name] = new ResolvedDefinition(def);\n        return;\n      }\n\n      if (def.kind === \"caveatDef\") {\n        this.caveatsByName[def.name] = new ResolvedCaveatDefinition(def);\n        return;\n      }\n    });\n    this.populated = true;\n  }\n\n  /**\n   * listDefinitions lists all definitions in the resolver.\n   */\n  public listDefinitions(): Array<ResolvedDefinition> {\n    this.populate();\n    return Object.values(this.definitionsByName);\n  }\n\n  /**\n   * lookupDefinition returns the definition with the given name, if any, or undefined\n   * if none.\n   */\n  public lookupDefinition(name: string): ResolvedDefinition | undefined {\n    this.populate();\n\n    if (!(name in this.definitionsByName)) {\n      return undefined;\n    }\n\n    return this.definitionsByName[name];\n  }\n\n  /**\n   * listCaveats returns all resolved caveat definitions in the schema.\n   */\n  public listCaveats(): Array<ResolvedCaveatDefinition> {\n    this.populate();\n    return Object.values(this.caveatsByName);\n  }\n\n  /**\n   * resolvedReferences returns all the resolved type and expression references in the schema.\n   */\n  public resolvedReferences(): Array<ResolvedReference> {\n    this.populate();\n\n    const refs = [\n      ...this.lookupAndResolveTypeReferences(),\n      ...this.lookupAndResolveExprReferences(),\n    ];\n    refs.sort((a: ResolvedReference, b: ResolvedReference) => {\n      return (\n        a.reference.range.startIndex.offset -\n        b.reference.range.startIndex.offset\n      );\n    });\n    return refs;\n  }\n\n  /**\n   * resolveTypeReference attempts to resolve a type reference.\n   */\n  public resolveTypeReference(typeRef: TypeRef): TypeRefResolution | undefined {\n    this.populate();\n\n    if (!(typeRef.path in this.definitionsByName)) {\n      return undefined;\n    }\n\n    const definition = this.definitionsByName[typeRef.path];\n    if (!definition) {\n      return undefined;\n    }\n    if (!typeRef.relationName) {\n      return {\n        definition: definition.definition,\n        relation: undefined,\n        permission: undefined,\n      };\n    }\n\n    return {\n      definition: definition.definition,\n      relation: definition.lookupRelation(typeRef.relationName),\n      permission: definition.lookupPermission(typeRef.relationName),\n    };\n  }\n\n  /**\n   * resolveRelationOrPermission attempts to resolve a relation reference expression.\n   */\n  public resolveRelationOrPermission(\n    current: ParsedRelationRefExpression,\n    def: TopLevelDefinition,\n  ): ExpressionResolution | undefined {\n    this.populate();\n    if (def.kind === \"use\" || def.kind === \"import\") {\n      return undefined;\n    }\n\n    const definition = this.definitionsByName[def.name];\n    if (!definition) {\n      return undefined;\n    }\n    return definition.lookupRelationOrPermission(current.relationName);\n  }\n\n  private lookupAndResolveTypeReferences(): Array<ResolvedTypeReference> {\n    this.populate();\n    return this.schema.definitions.flatMap((def: TopLevelDefinition) => {\n      if (def.kind !== \"objectDef\") {\n        return [];\n      }\n\n      const asTypeReference = (typeRef: TypeRef): ResolvedTypeReference => {\n        return {\n          kind: \"type\",\n          reference: typeRef,\n          referencedTypeAndRelation: this.resolveTypeReference(typeRef),\n        };\n      };\n\n      const relationRefs = def.relations.flatMap((rel: ParsedRelation) =>\n        rel.allowedTypes.types.map(asTypeReference),\n      );\n\n      // Permission `use typechecking` annotations reference types too, so resolve\n      // them alongside relation types for highlighting and hover.\n      const annotationRefs = def.permissions.flatMap(\n        (perm: ParsedPermission) =>\n          perm.annotatedTypes\n            ? perm.annotatedTypes.types.map(asTypeReference)\n            : [],\n      );\n\n      return [...relationRefs, ...annotationRefs];\n    });\n  }\n\n  private lookupAndResolveExprReferences(): Array<ResolvedExprReference> {\n    this.populate();\n    return this.schema.definitions.flatMap((def: TopLevelDefinition) => {\n      if (def.kind !== \"objectDef\") {\n        return [];\n      }\n\n      return def.permissions.flatMap((perm: ParsedPermission) => {\n        return flatMapExpression<ResolvedExprReference>(\n          perm.expr,\n          (current: ParsedExpression) => {\n            switch (current.kind) {\n              case \"relationref\":\n                return {\n                  kind: \"expression\",\n                  reference: current,\n                  resolvedRelationOrPermission:\n                    this.resolveRelationOrPermission(current, def),\n                };\n\n              default:\n                return undefined;\n            }\n          },\n        );\n      });\n    });\n  }\n}\n\nexport class ResolvedDefinition {\n  private relationsByName: Record<string, ParsedRelation> = {};\n  private permissionByName: Record<string, ParsedPermission> = {};\n  public definition: ParsedObjectDefinition = {\n    kind: \"objectDef\",\n    name: \"\",\n    relations: [],\n    permissions: [],\n    partialReferences: [],\n    range: emptyRange,\n  };\n\n  constructor(definition: ParsedObjectDefinition) {\n    definition.permissions.forEach((perm: ParsedPermission) => {\n      this.permissionByName[perm.name] = perm;\n    });\n    definition.relations.forEach((rel: ParsedRelation) => {\n      this.relationsByName[rel.name] = rel;\n    });\n    this.definition = definition;\n  }\n\n  public listRelationNames(): Array<string> {\n    return Object.keys(this.relationsByName);\n  }\n\n  public listRelations(): Array<ParsedRelation> {\n    return Object.values(this.relationsByName);\n  }\n\n  public listRelationsAndPermissions(): Array<\n    ParsedRelation | ParsedPermission\n  > {\n    return [\n      ...Object.values(this.relationsByName),\n      ...Object.values(this.permissionByName),\n    ];\n  }\n\n  public listRelationsAndPermissionNames(): Array<string> {\n    return Array.from(\n      new Set<string>([\n        ...Object.keys(this.relationsByName),\n        ...Object.keys(this.permissionByName),\n      ]),\n    );\n  }\n\n  public listWithCaveatNames(): Array<string> {\n    const withCaveats = Object.values(this.relationsByName).filter((rel) => {\n      return rel.allowedTypes.types.find((ref) => ref.withCaveat);\n    });\n\n    const names: Array<string> = [];\n    withCaveats.forEach((rel) => {\n      rel.allowedTypes.types.forEach((ref) => {\n        if (ref.withCaveat) {\n          names.push(ref.withCaveat.path);\n        }\n      });\n    });\n    return names;\n  }\n\n  public lookupRelation(name: string): ParsedRelation | undefined {\n    if (!(name in this.relationsByName)) {\n      return undefined;\n    }\n\n    return this.relationsByName[name];\n  }\n\n  public lookupPermission(name: string): ParsedPermission | undefined {\n    if (!(name in this.permissionByName)) {\n      return undefined;\n    }\n\n    return this.permissionByName[name];\n  }\n\n  public lookupRelationOrPermission(\n    name: string,\n  ): ParsedRelation | ParsedPermission | undefined {\n    const rel = this.lookupRelation(name);\n    if (rel) {\n      return rel;\n    }\n\n    return this.lookupPermission(name);\n  }\n}\n\nexport class ResolvedCaveatDefinition {\n  private paramsByName: Record<string, ParsedCaveatParameter> = {};\n  private name: string;\n  public definition: ParsedCaveatDefinition = {\n    kind: \"caveatDef\",\n    name: \"\",\n    parameters: [],\n    expression: {\n      kind: \"caveatExpr\",\n      range: emptyRange,\n    },\n    range: emptyRange,\n  };\n\n  constructor(definition: ParsedCaveatDefinition) {\n    definition.parameters.forEach((param: ParsedCaveatParameter) => {\n      this.paramsByName[param.name] = param;\n    });\n    this.name = definition.name;\n  }\n\n  public getName(): string {\n    return this.name;\n  }\n\n  public listParameterNames(): Array<string> {\n    return Object.keys(this.paramsByName);\n  }\n}\n\nconst emptyRange: TextRange = {\n  startIndex: {\n    offset: 0,\n    line: 0,\n    column: 0,\n  },\n  endIndex: {\n    offset: 0,\n    line: 0,\n    column: 0,\n  },\n};\n"],"mappings":"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"}