@zenstackhq/language 3.7.0-beta.1 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { Et as isExpression, Ft as isLiteralExpr, Ht as isObjectExpr, It as isMemberAccessExpr, Jt as isReferenceExpr, Pt as isInvocationExpr, Qt as isStringLiteral, Rt as isModel, Tt as isEnumField, Ut as isPlugin, ct as isBinaryExpr, pt as isConfigArrayExpr, rt as isArrayExpr, tn as isTypeDef, vt as isDataField, xt as isDataModel } from "./ast-DEfhnj8j.mjs";
1
+ import { Ct as isDataSource, Et as isExpression, Ft as isLiteralExpr, Ht as isObjectExpr, It as isMemberAccessExpr, Jt as isReferenceExpr, Pt as isInvocationExpr, Qt as isStringLiteral, Rt as isModel, Tt as isEnumField, Ut as isPlugin, ct as isBinaryExpr, pt as isConfigArrayExpr, rt as isArrayExpr, tn as isTypeDef, vt as isDataField, xt as isDataModel } from "./ast-DEfhnj8j.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { AstUtils, URI } from "langium";
4
4
  import fs from "node:fs";
@@ -150,6 +150,17 @@ function isDelegateModel(node) {
150
150
  return isDataModel(node) && hasAttribute(node, "@@delegate");
151
151
  }
152
152
  /**
153
+ * Returns the datasource provider literal (e.g. `'postgresql'`) declared in the schema, or undefined
154
+ * if no datasource is found or its provider is not a literal.
155
+ */
156
+ function getDataSourceProvider(model) {
157
+ const dataSource = model.declarations.find(isDataSource);
158
+ if (!dataSource) return;
159
+ const providerField = dataSource.fields.find((f) => f.name === "provider");
160
+ if (!providerField) return;
161
+ return getLiteral(providerField.value);
162
+ }
163
+ /**
153
164
  * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.
154
165
  */
155
166
  function resolved(ref) {
@@ -524,6 +535,6 @@ function findRootNode(node) {
524
535
  return node;
525
536
  }
526
537
  //#endregion
527
- export { isBeforeInvocation as A, mapBuiltinTypeToExpressionType as B, getPluginDocuments as C, hasAttribute as D, getUniqueFields as E, isDelegateModel as F, typeAssignable as G, resolveImportUri as H, isEnumFieldReference as I, IssueCodes as J, DB_PROVIDERS_SUPPORTING_LIST_TYPE as K, isFromStdlib as L, isCollectionPredicate as M, isComputedField as N, isAuthInvocation as O, isDataFieldReference as P, SUPPORTED_PROVIDERS as Q, isMemberContainer as R, getObjectLiteral as S, getStringLiteral as T, resolveTransitiveImports as U, resolveImport as V, resolved as W, SCALAR_TYPES as X, PLUGIN_MODULE_NAME as Y, STD_LIB_MODULE_NAME as Z, getFunctionExpressionContext as _, getAllDeclarationsIncludingImports as a, getModelIdFields as b, getAllLoadedDataModelsAndTypeDefs as c, getAttributeArgLiteral as d, getAuthDecl as f, getFieldReference as g, getDocument as h, getAllDataModelsIncludingImports as i, isCheckInvocation as j, isAuthOrAuthMemberAccess as k, getAttribute as l, getDataModelAndTypeDefs as m, findUpAst as n, getAllFields as o, getContainingDataModel as p, ExpressionContext as q, getAllAttributes as r, getAllLoadedAndReachableDataModelsAndTypeDefs as s, findRootNode as t, getAttributeArg as u, getLiteral as v, getRecursiveBases as w, getModelUniqueFields as x, getLiteralArray as y, isRelationshipField as z };
538
+ export { SUPPORTED_PROVIDERS as $, isAuthOrAuthMemberAccess as A, isRelationshipField as B, getObjectLiteral as C, getUniqueFields as D, getStringLiteral as E, isDataFieldReference as F, resolved as G, resolveImport as H, isDelegateModel as I, ExpressionContext as J, typeAssignable as K, isEnumFieldReference as L, isCheckInvocation as M, isCollectionPredicate as N, hasAttribute as O, isComputedField as P, STD_LIB_MODULE_NAME as Q, isFromStdlib as R, getModelUniqueFields as S, getRecursiveBases as T, resolveImportUri as U, mapBuiltinTypeToExpressionType as V, resolveTransitiveImports as W, PLUGIN_MODULE_NAME as X, IssueCodes as Y, SCALAR_TYPES as Z, getFieldReference as _, getAllDeclarationsIncludingImports as a, getLiteralArray as b, getAllLoadedDataModelsAndTypeDefs as c, getAttributeArgLiteral as d, getAuthDecl as f, getDocument as g, getDataSourceProvider as h, getAllDataModelsIncludingImports as i, isBeforeInvocation as j, isAuthInvocation as k, getAttribute as l, getDataModelAndTypeDefs as m, findUpAst as n, getAllFields as o, getContainingDataModel as p, DB_PROVIDERS_SUPPORTING_LIST_TYPE as q, getAllAttributes as r, getAllLoadedAndReachableDataModelsAndTypeDefs as s, findRootNode as t, getAttributeArg as u, getFunctionExpressionContext as v, getPluginDocuments as w, getModelIdFields as x, getLiteral as y, isMemberContainer as z };
528
539
 
529
- //# sourceMappingURL=utils-BB6L7ug2.mjs.map
540
+ //# sourceMappingURL=utils-CCU55PfR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-CCU55PfR.mjs","names":[],"sources":["../src/constants.ts","../src/utils.ts"],"sourcesContent":["/**\n * Supported db providers\n */\nexport const SUPPORTED_PROVIDERS = ['sqlite', 'postgresql', 'mysql'];\n\n/**\n * All scalar types\n */\nexport const SCALAR_TYPES = ['String', 'Int', 'Float', 'Decimal', 'BigInt', 'Boolean', 'Bytes', 'DateTime'];\n\n/**\n * Name of standard library module\n */\nexport const STD_LIB_MODULE_NAME = 'stdlib.zmodel';\n\n/**\n * Name of module contributed by plugins\n */\nexport const PLUGIN_MODULE_NAME = 'plugin.zmodel';\n\n/**\n * Validation issues\n */\nexport enum IssueCodes {\n MissingOppositeRelation = 'miss-opposite-relation',\n}\n\n/**\n * Expression context\n */\nexport enum ExpressionContext {\n DefaultValue = 'DefaultValue',\n AccessPolicy = 'AccessPolicy',\n ValidationRule = 'ValidationRule',\n Index = 'Index',\n}\n\n/**\n * Database providers that support list field types.\n */\nexport const DB_PROVIDERS_SUPPORTING_LIST_TYPE = ['postgresql'];\n","import { AstUtils, URI, type AstNode, type LangiumDocument, type LangiumDocuments, type Reference } from 'langium';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { PLUGIN_MODULE_NAME, STD_LIB_MODULE_NAME, type ExpressionContext } from './constants';\nimport {\n InternalAttribute,\n isArrayExpr,\n isBinaryExpr,\n isConfigArrayExpr,\n isDataField,\n isDataModel,\n isDataSource,\n isEnumField,\n isExpression,\n isInvocationExpr,\n isLiteralExpr,\n isMemberAccessExpr,\n isModel,\n isObjectExpr,\n isPlugin,\n isReferenceExpr,\n isStringLiteral,\n isTypeDef,\n type Attribute,\n type AttributeParam,\n type BinaryExpr,\n type BuiltinType,\n type ConfigExpr,\n type DataField,\n type DataFieldAttribute,\n type DataModel,\n type DataModelAttribute,\n type Enum,\n type EnumField,\n type Expression,\n type ExpressionType,\n type FunctionDecl,\n type Model,\n type ModelImport,\n type ReferenceExpr,\n type TypeDef,\n} from './generated/ast';\n\nexport type AttributeTarget =\n | DataModel\n | TypeDef\n | DataField\n | Enum\n | EnumField\n | FunctionDecl\n | Attribute\n | AttributeParam;\n\nexport function hasAttribute(decl: AttributeTarget, name: string) {\n return !!getAttribute(decl, name);\n}\n\nexport function getAttribute(decl: AttributeTarget, name: string) {\n return (decl.attributes as (DataModelAttribute | DataFieldAttribute)[]).find((attr) => attr.decl.$refText === name);\n}\n\nexport function isFromStdlib(node: AstNode) {\n const model = AstUtils.getContainerOfType(node, isModel);\n return !!model && !!model.$document && model.$document.uri.path.endsWith(STD_LIB_MODULE_NAME);\n}\n\nexport function isAuthInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'auth' && isFromStdlib(node.function.ref);\n}\n\n/**\n * Try getting string value from a potential string literal expression\n */\nexport function getStringLiteral(node: AstNode | undefined): string | undefined {\n return isStringLiteral(node) ? node.value : undefined;\n}\n\nconst isoDateTimeRegex = /^\\d{4}(-\\d\\d(-\\d\\d(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?)?)?$/i;\n\n/**\n * Determines if the given sourceType is assignable to a destination of destType\n */\nexport function typeAssignable(destType: ExpressionType, sourceType: ExpressionType, sourceExpr?: Expression): boolean {\n // implicit conversion from ISO datetime string to datetime\n if (destType === 'DateTime' && sourceType === 'String' && sourceExpr && isStringLiteral(sourceExpr)) {\n const literal = getStringLiteral(sourceExpr);\n if (literal && isoDateTimeRegex.test(literal)) {\n // implicitly convert to DateTime\n sourceType = 'DateTime';\n }\n }\n\n switch (destType) {\n case 'Any':\n return true;\n case 'Float':\n return sourceType === 'Any' || sourceType === 'Int' || sourceType === 'Float';\n default:\n return sourceType === 'Any' || sourceType === destType;\n }\n}\n\n/**\n * Maps a ZModel builtin type to expression type\n */\nexport function mapBuiltinTypeToExpressionType(type: BuiltinType | ExpressionType): ExpressionType {\n switch (type) {\n case 'Any':\n case 'Boolean':\n case 'String':\n case 'DateTime':\n case 'Int':\n case 'Float':\n case 'Null':\n case 'Object':\n case 'Unsupported':\n case 'Void':\n case 'Undefined':\n return type;\n case 'BigInt':\n return 'Int';\n case 'Decimal':\n return 'Float';\n case 'Json':\n case 'Bytes':\n return 'Any';\n }\n}\n\n/**\n * Determines if the given expression is an invocation of `auth` or a member access on the result of an `auth` invocation (e.g. `auth().role`).\n */\nexport function isAuthOrAuthMemberAccess(expr: Expression): boolean {\n return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthOrAuthMemberAccess(expr.operand));\n}\n\n/**\n * Determines if the given expression is a reference to an enum field.\n */\nexport function isEnumFieldReference(node: AstNode): node is ReferenceExpr {\n return isReferenceExpr(node) && isEnumField(node.target.ref);\n}\n\n/**\n * Determines if the given expression is a reference to a data field.\n */\nexport function isDataFieldReference(node: AstNode): node is ReferenceExpr {\n return isReferenceExpr(node) && isDataField(node.target.ref);\n}\n\n/**\n * Returns if the given field is a relation field.\n */\nexport function isRelationshipField(field: DataField) {\n return isDataModel(field.type.reference?.ref);\n}\n\n/**\n * Returns if the given field is a computed field.\n */\nexport function isComputedField(field: DataField) {\n return hasAttribute(field, '@computed');\n}\n\n/**\n * Determines if the given data model is a delegate model (i.e. marked with `@@delegate` attribute).\n */\nexport function isDelegateModel(node: AstNode) {\n return isDataModel(node) && hasAttribute(node, '@@delegate');\n}\n\n/**\n * Returns the datasource provider literal (e.g. `'postgresql'`) declared in the schema, or undefined\n * if no datasource is found or its provider is not a literal.\n */\nexport function getDataSourceProvider(model: Model) {\n const dataSource = model.declarations.find(isDataSource);\n if (!dataSource) {\n return undefined;\n }\n const providerField = dataSource.fields.find((f) => f.name === 'provider');\n if (!providerField) {\n return undefined;\n }\n return getLiteral<string>(providerField.value);\n}\n\n/**\n * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.\n */\nexport function resolved<T extends AstNode>(ref: Reference<T>): T {\n if (!ref.ref) {\n throw new Error(`Reference not resolved: ${ref.$refText}`);\n }\n return ref.ref;\n}\n\n/**\n * Gets all base models and mixins of a data model or type def, recursively.\n */\nexport function getRecursiveBases(\n decl: DataModel | TypeDef,\n includeDelegate = true,\n documents?: LangiumDocuments,\n seen = new Set<DataModel | TypeDef>(),\n): (TypeDef | DataModel)[] {\n const result: (TypeDef | DataModel)[] = [];\n if (seen.has(decl)) {\n return result;\n }\n seen.add(decl);\n const bases = [...decl.mixins, ...(isDataModel(decl) && decl.baseModel ? [decl.baseModel] : [])];\n bases.forEach((base) => {\n let baseDecl: TypeDef | DataModel | undefined;\n\n if (base.ref && (isTypeDef(base.ref) || isDataModel(base.ref))) {\n // base is already resolved\n baseDecl = base.ref;\n } else {\n // otherwise, search by name, in all imported documents if provided\n const declarations = documents\n ? getAllDeclarationsIncludingImports(documents, decl.$container)\n : decl.$container.declarations;\n\n baseDecl = declarations.find(\n (d): d is TypeDef | DataModel => (isTypeDef(d) || isDataModel(d)) && d.name === base.$refText,\n );\n }\n\n if (baseDecl) {\n if (!includeDelegate && isDelegateModel(baseDecl)) {\n return;\n }\n result.push(baseDecl);\n result.push(...getRecursiveBases(baseDecl, includeDelegate, documents, seen));\n }\n });\n return result;\n}\n\n/**\n * Gets `@@id` fields declared at the data model level (including search in base models)\n */\nexport function getModelIdFields(model: DataModel) {\n const modelsToCheck = [model, ...getRecursiveBases(model)];\n\n for (const modelToCheck of modelsToCheck) {\n const allAttributes = getAllAttributes(modelToCheck);\n const idAttr = allAttributes.find((attr) => attr.decl.$refText === '@@id');\n if (!idAttr) {\n continue;\n }\n const fieldsArg = idAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n continue;\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n }\n\n return [];\n}\n\n/**\n * Gets `@@unique` fields declared at the data model level (including search in base models)\n */\nexport function getModelUniqueFields(model: DataModel) {\n const modelsToCheck = [model, ...getRecursiveBases(model)];\n\n for (const modelToCheck of modelsToCheck) {\n const allAttributes = getAllAttributes(modelToCheck);\n const uniqueAttr = allAttributes.find((attr) => attr.decl.$refText === '@@unique');\n if (!uniqueAttr) {\n continue;\n }\n const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n continue;\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n }\n\n return [];\n}\n\n/**\n * Gets lists of unique fields declared at the data model level\n *\n * TODO: merge this with {@link getModelUniqueFields}\n */\nexport function getUniqueFields(model: DataModel) {\n const uniqueAttrs = model.attributes.filter(\n (attr) => attr.decl.ref?.name === '@@unique' || attr.decl.ref?.name === '@@id',\n );\n return uniqueAttrs.map((uniqueAttr) => {\n const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n return [];\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n });\n}\n\n/**\n * Finds the first ancestor of the given AST node that satisfies the given predicate function. Returns `undefined` if no such ancestor is found.\n */\nexport function findUpAst(node: AstNode, predicate: (node: AstNode) => boolean): AstNode | undefined {\n let curr: AstNode | undefined = node;\n while (curr) {\n if (predicate(curr)) {\n return curr;\n }\n curr = curr.$container;\n }\n return undefined;\n}\n\n/**\n * Tries to get the literal value from the given expression. Returns `undefined` if the expression is not a literal or if the literal value cannot be determined.\n */\nexport function getLiteral<T extends string | number | boolean | any = any>(\n expr: Expression | ConfigExpr | undefined,\n): T | undefined {\n switch (expr?.$type) {\n case 'ObjectExpr':\n return getObjectLiteral<T>(expr);\n case 'StringLiteral':\n case 'BooleanLiteral':\n return expr.value as T;\n case 'NumberLiteral':\n return parseFloat(expr.value) as T;\n default:\n return undefined;\n }\n}\n\n/**\n * Tries to get an object literal from the given expression. Returns `undefined` if the expression is not an object literal or if any of the field values cannot be determined.\n */\nexport function getObjectLiteral<T>(expr: Expression | ConfigExpr | undefined): T | undefined {\n if (!expr || !isObjectExpr(expr)) {\n return undefined;\n }\n const result: Record<string, unknown> = {};\n for (const field of expr.fields) {\n let fieldValue: unknown;\n if (isLiteralExpr(field.value)) {\n fieldValue = getLiteral(field.value);\n } else if (isArrayExpr(field.value)) {\n fieldValue = getLiteralArray(field.value);\n } else if (isObjectExpr(field.value)) {\n fieldValue = getObjectLiteral(field.value);\n }\n if (fieldValue === undefined) {\n return undefined;\n } else {\n result[field.name] = fieldValue;\n }\n }\n return result as T;\n}\n\nexport function getLiteralArray<T extends string | number | boolean | any = any>(\n expr: Expression | ConfigExpr | undefined,\n): T[] | undefined {\n const arr = getArray(expr);\n if (!arr) {\n return undefined;\n }\n return arr.map((item) => isExpression(item) && getLiteral<T>(item)).filter((v): v is T => v !== undefined);\n}\n\nfunction getArray(expr: Expression | ConfigExpr | undefined) {\n return isArrayExpr(expr) || isConfigArrayExpr(expr) ? expr.items : undefined;\n}\n\n/**\n * Gets the value of the argument with the given name from the given attribute. Returns `undefined` if no such argument is found or if the argument value cannot be determined.\n */\nexport function getAttributeArg(\n attr: DataModelAttribute | DataFieldAttribute | InternalAttribute,\n name: string,\n): Expression | undefined {\n return attr.args.find((arg) => arg.$resolvedParam?.name === name)?.value;\n}\n\n/**\n * Gets the literal value of the argument with the given name from the given attribute. Returns `undefined` if no such argument is found or if the argument value cannot be determined or is not a literal.\n */\nexport function getAttributeArgLiteral<T extends string | number | boolean>(\n attr: DataModelAttribute | DataFieldAttribute | InternalAttribute,\n name: string,\n): T | undefined {\n for (const arg of attr.args) {\n if (arg.$resolvedParam?.name === name) {\n return getLiteral<T>(arg.value);\n }\n }\n return undefined;\n}\n\n/**\n * Gets the allowed expression contexts for the given function declaration by looking for `@@expressionContext` attribute.\n * Returns an empty array if no such attribute is found or if the attribute value cannot be determined.\n */\nexport function getFunctionExpressionContext(funcDecl: FunctionDecl) {\n const funcAllowedContext: ExpressionContext[] = [];\n const funcAttr = funcDecl.attributes.find((attr) => attr.decl.$refText === '@@@expressionContext');\n if (funcAttr) {\n const contextArg = funcAttr.args[0]?.value;\n if (isArrayExpr(contextArg)) {\n contextArg.items.forEach((item) => {\n if (isEnumFieldReference(item)) {\n funcAllowedContext.push(item.target.$refText as ExpressionContext);\n }\n });\n }\n }\n return funcAllowedContext;\n}\n\n/**\n * Gets the data field referenced by the given expression, if any. Returns `undefined` if the expression is not a reference to a data field.\n */\nexport function getFieldReference(expr: Expression): DataField | undefined {\n if (isReferenceExpr(expr) && isDataField(expr.target.ref)) {\n return expr.target.ref;\n } else if (isMemberAccessExpr(expr) && isDataField(expr.member.ref)) {\n return expr.member.ref;\n } else {\n return undefined;\n }\n}\n\n// TODO: move to policy plugin\nexport function isCheckInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'check';\n}\n\n/**\n * Resolves the transitive imports of the given model and returns the list of imported models. The given model itself is not included in the result.\n */\nexport function resolveTransitiveImports(documents: LangiumDocuments, model: Model) {\n return resolveTransitiveImportsInternal(documents, model);\n}\n\nfunction resolveTransitiveImportsInternal(\n documents: LangiumDocuments,\n model: Model,\n initialModel = model,\n visited: Set<string> = new Set(),\n models: Set<Model> = new Set(),\n) {\n const doc = AstUtils.getDocument(model);\n const initialDoc = AstUtils.getDocument(initialModel);\n\n if (initialDoc.uri.fsPath.toLowerCase() !== doc.uri.fsPath.toLowerCase()) {\n models.add(model);\n }\n\n const normalizedPath = doc.uri.fsPath.toLowerCase();\n if (!visited.has(normalizedPath)) {\n visited.add(normalizedPath);\n for (const imp of model.imports) {\n const importedModel = resolveImport(documents, imp);\n if (importedModel) {\n resolveTransitiveImportsInternal(documents, importedModel, initialModel, visited, models);\n }\n }\n }\n return Array.from(models);\n}\n\n/**\n * Resolves the given import and returns the imported model. Returns `undefined`\n * if the import cannot be resolved.\n */\nexport function resolveImport(documents: LangiumDocuments, imp: ModelImport) {\n const resolvedUri = resolveImportUri(imp);\n try {\n if (resolvedUri) {\n let resolvedDocument = documents.getDocument(resolvedUri);\n if (!resolvedDocument) {\n const content = fs.readFileSync(resolvedUri.fsPath, 'utf-8');\n resolvedDocument = documents.createDocument(resolvedUri, content);\n }\n const node = resolvedDocument.parseResult.value;\n if (isModel(node)) {\n return node;\n }\n }\n } catch {\n // NOOP\n }\n return undefined;\n}\n\n/**\n * Resolves the given import and returns the URI of the imported model.\n * Returns `undefined` if the import cannot be resolved.\n */\nexport function resolveImportUri(imp: ModelImport) {\n if (!imp.path) {\n return undefined;\n }\n const doc = AstUtils.getDocument(imp);\n const dir = path.dirname(doc.uri.fsPath);\n const importPath = imp.path.endsWith('.zmodel') ? imp.path : `${imp.path}.zmodel`;\n return URI.file(path.resolve(dir, importPath));\n}\n\n/**\n * Gets data models and type defs in the ZModel schema.\n */\nexport function getDataModelAndTypeDefs(model: Model, includeIgnored = false) {\n const r = model.declarations.filter((d): d is DataModel | TypeDef => isDataModel(d) || isTypeDef(d));\n if (includeIgnored) {\n return r;\n } else {\n return r.filter((model) => !hasAttribute(model, '@@ignore'));\n }\n}\n\n/**\n * Gets all declarations of the given model and its transitive imports.\n */\nexport function getAllDeclarationsIncludingImports(documents: LangiumDocuments, model: Model) {\n const imports = resolveTransitiveImports(documents, model);\n return model.declarations.concat(...imports.map((imp) => imp.declarations));\n}\n\n/**\n * Gets the model used for auth context, by looking for a model with `@@auth` attribute or a model named `User`.\n * Returns `undefined` if no such model is found.\n */\nexport function getAuthDecl(decls: (DataModel | TypeDef)[]) {\n let authModel = decls.find((d) => hasAttribute(d, '@@auth'));\n if (!authModel) {\n authModel = decls.find((d) => d.name === 'User');\n }\n return authModel;\n}\n\n// TODO: move to policy plugin\nexport function isBeforeInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'before';\n}\n\n/**\n * Determines if the given AST node is a collection predicate.\n */\nexport function isCollectionPredicate(node: AstNode): node is BinaryExpr {\n return isBinaryExpr(node) && ['?', '!', '^'].includes(node.operator);\n}\n\n/**\n * Gets all data models and type defs from the given documents registry.\n */\nexport function getAllLoadedDataModelsAndTypeDefs(langiumDocuments: LangiumDocuments) {\n return langiumDocuments.all\n .map((doc) => doc.parseResult.value as Model)\n .flatMap((model) => model.declarations.filter((d): d is DataModel | TypeDef => isDataModel(d) || isTypeDef(d)))\n .toArray();\n}\n\n/**\n * Gets all data models from the given documents registry and the transitive imports of the given model.\n */\nexport function getAllDataModelsIncludingImports(documents: LangiumDocuments, model: Model) {\n return getAllDeclarationsIncludingImports(documents, model).filter(isDataModel);\n}\n\n/**\n * Gets all data models and type defs from the given documents registry and the transitive imports\n * of the given model. If `fromModel` is not provided, returns all loaded data models and type defs.\n */\nexport function getAllLoadedAndReachableDataModelsAndTypeDefs(\n langiumDocuments: LangiumDocuments,\n fromModel?: DataModel,\n) {\n // get all data models from loaded documents\n const allDataModels = getAllLoadedDataModelsAndTypeDefs(langiumDocuments);\n\n if (fromModel) {\n // merge data models transitively reached from the current model\n const model = AstUtils.getContainerOfType(fromModel, isModel);\n if (model) {\n const transitiveDataModels = getAllDataModelsIncludingImports(langiumDocuments, model);\n transitiveDataModels.forEach((dm) => {\n if (!allDataModels.includes(dm)) {\n allDataModels.push(dm);\n }\n });\n }\n }\n\n return allDataModels;\n}\n\n/**\n * Gets the containing data model of the given AST node, if any.\n * Returns `undefined` if the node is not contained in a data model.\n */\nexport function getContainingDataModel(node: AstNode): DataModel | undefined {\n let curr: AstNode | undefined = node.$container;\n while (curr) {\n if (isDataModel(curr)) {\n return curr;\n }\n curr = curr.$container;\n }\n return undefined;\n}\n\n/**\n * Determines if the given AST node can contain members.\n */\nexport function isMemberContainer(node: unknown): node is DataModel | TypeDef {\n return isDataModel(node) || isTypeDef(node);\n}\n\n/**\n * Gets all fields of a data model or type def, including inherited fields from base models and mixins.\n */\nexport function getAllFields(\n decl: DataModel | TypeDef,\n includeIgnored = false,\n seen: Set<DataModel | TypeDef> = new Set(),\n): DataField[] {\n if (seen.has(decl)) {\n return [];\n }\n seen.add(decl);\n\n const fields: DataField[] = [];\n for (const mixin of decl.mixins) {\n if (mixin.ref) {\n fields.push(...getAllFields(mixin.ref, includeIgnored, seen));\n }\n }\n\n if (isDataModel(decl) && decl.baseModel) {\n if (decl.baseModel.ref) {\n fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));\n }\n }\n\n fields.push(...decl.fields.filter((f) => includeIgnored || !hasAttribute(f, '@ignore')));\n return fields;\n}\n\n/**\n * Gets all attributes of a data model or type def, including inherited attributes\n * from base models and mixins.\n */\nexport function getAllAttributes(\n decl: DataModel | TypeDef,\n seen: Set<DataModel | TypeDef> = new Set(),\n): DataModelAttribute[] {\n if (seen.has(decl)) {\n return [];\n }\n seen.add(decl);\n\n const attributes: DataModelAttribute[] = [];\n for (const mixin of decl.mixins) {\n if (mixin.ref) {\n attributes.push(...getAllAttributes(mixin.ref, seen));\n }\n }\n\n if (isDataModel(decl) && decl.baseModel) {\n if (decl.baseModel.ref) {\n const attrs = getAllAttributes(decl.baseModel.ref, seen).filter((attr) => !isNonInheritableAttribute(attr));\n attributes.push(...attrs);\n }\n }\n\n attributes.push(...decl.attributes);\n return attributes;\n}\n\nfunction isNonInheritableAttribute(attr: DataModelAttribute) {\n const attrName = attr.decl.ref?.name ?? attr.decl.$refText;\n return ['@@map', '@@unique', '@@index'].includes(attrName);\n}\n\n/**\n * Retrieve the document in which the given AST node is contained. A reference to the document is\n * usually held by the root node of the AST.\n *\n * @throws an error if the node is not contained in a document.\n */\nexport function getDocument<T extends AstNode = AstNode>(node: AstNode): LangiumDocument<T> {\n const rootNode = findRootNode(node);\n const result = rootNode.$document;\n if (!result) {\n throw new Error('AST node has no document.');\n }\n return result as LangiumDocument<T>;\n}\n\n/**\n * Gets the list of plugin documents from the given model.\n */\nexport function getPluginDocuments(model: Model, schemaPath: string): string[] {\n // traverse plugins and collect \"plugin.zmodel\" documents\n const result: string[] = [];\n for (const decl of model.declarations.filter(isPlugin)) {\n const providerField = decl.fields.find((f) => f.name === 'provider');\n if (!providerField) {\n continue;\n }\n\n const provider = getLiteral<string>(providerField.value);\n if (!provider) {\n continue;\n }\n\n let pluginModelFile: string | undefined;\n\n // first try to treat provider as a path\n let providerPath = path.resolve(path.dirname(schemaPath), provider);\n if (fs.existsSync(providerPath)) {\n if (fs.statSync(providerPath).isDirectory()) {\n providerPath = path.join(providerPath, 'index.js');\n }\n\n // try plugin.zmodel next to the provider file\n pluginModelFile = path.resolve(path.dirname(providerPath), PLUGIN_MODULE_NAME);\n if (!fs.existsSync(pluginModelFile)) {\n // try to find upwards\n pluginModelFile = findUp([PLUGIN_MODULE_NAME], path.dirname(providerPath));\n }\n }\n\n if (!pluginModelFile) {\n if (typeof import.meta.resolve === 'function') {\n try {\n // try loading as a ESM module\n const resolvedUrl = import.meta.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);\n pluginModelFile = fileURLToPath(resolvedUrl);\n } catch {\n // noop\n }\n }\n }\n\n if (!pluginModelFile) {\n // try loading as a CJS module\n try {\n const require = createRequire(pathToFileURL(schemaPath));\n pluginModelFile = require.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);\n } catch {\n // noop\n }\n }\n\n if (pluginModelFile && fs.existsSync(pluginModelFile)) {\n result.push(pluginModelFile);\n }\n }\n return result;\n}\n\ntype FindUpResult<Multiple extends boolean> = Multiple extends true ? string[] | undefined : string | undefined;\n\nfunction findUp<Multiple extends boolean = false>(\n names: string[],\n cwd: string = process.cwd(),\n multiple: Multiple = false as Multiple,\n result: string[] = [],\n): FindUpResult<Multiple> {\n if (!names.some((name) => !!name)) {\n return undefined;\n }\n const target = names.find((name) => fs.existsSync(path.join(cwd, name)));\n if (multiple === false && target) {\n return path.join(cwd, target) as FindUpResult<Multiple>;\n }\n if (target) {\n result.push(path.join(cwd, target));\n }\n const up = path.resolve(cwd, '..');\n if (up === cwd) {\n return (multiple && result.length > 0 ? result : undefined) as FindUpResult<Multiple>;\n }\n return findUp(names, up, multiple, result);\n}\n\n/**\n * Returns the root node of the given AST node by following the `$container` references.\n */\nexport function findRootNode(node: AstNode): AstNode {\n while (node.$container) {\n node = node.$container;\n }\n return node;\n}\n"],"mappings":"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"}
@@ -152,6 +152,17 @@ function isDelegateModel(node) {
152
152
  return require_ast.isDataModel(node) && hasAttribute(node, "@@delegate");
153
153
  }
154
154
  /**
155
+ * Returns the datasource provider literal (e.g. `'postgresql'`) declared in the schema, or undefined
156
+ * if no datasource is found or its provider is not a literal.
157
+ */
158
+ function getDataSourceProvider(model) {
159
+ const dataSource = model.declarations.find(require_ast.isDataSource);
160
+ if (!dataSource) return;
161
+ const providerField = dataSource.fields.find((f) => f.name === "provider");
162
+ if (!providerField) return;
163
+ return getLiteral(providerField.value);
164
+ }
165
+ /**
155
166
  * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.
156
167
  */
157
168
  function resolved(ref) {
@@ -652,6 +663,12 @@ Object.defineProperty(exports, "getDataModelAndTypeDefs", {
652
663
  return getDataModelAndTypeDefs;
653
664
  }
654
665
  });
666
+ Object.defineProperty(exports, "getDataSourceProvider", {
667
+ enumerable: true,
668
+ get: function() {
669
+ return getDataSourceProvider;
670
+ }
671
+ });
655
672
  Object.defineProperty(exports, "getDocument", {
656
673
  enumerable: true,
657
674
  get: function() {
@@ -839,4 +856,4 @@ Object.defineProperty(exports, "typeAssignable", {
839
856
  }
840
857
  });
841
858
 
842
- //# sourceMappingURL=utils-CfXGZkv7.cjs.map
859
+ //# sourceMappingURL=utils-b3dJKmYr.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-b3dJKmYr.cjs","names":["AstUtils","isModel","isInvocationExpr","isStringLiteral","isMemberAccessExpr","isReferenceExpr","isEnumField","isDataField","isDataModel","isDataSource","isTypeDef","isArrayExpr","isObjectExpr","isLiteralExpr","isExpression","isConfigArrayExpr","fs","path","URI","isBinaryExpr","isPlugin"],"sources":["../src/constants.ts","../src/utils.ts"],"sourcesContent":["/**\n * Supported db providers\n */\nexport const SUPPORTED_PROVIDERS = ['sqlite', 'postgresql', 'mysql'];\n\n/**\n * All scalar types\n */\nexport const SCALAR_TYPES = ['String', 'Int', 'Float', 'Decimal', 'BigInt', 'Boolean', 'Bytes', 'DateTime'];\n\n/**\n * Name of standard library module\n */\nexport const STD_LIB_MODULE_NAME = 'stdlib.zmodel';\n\n/**\n * Name of module contributed by plugins\n */\nexport const PLUGIN_MODULE_NAME = 'plugin.zmodel';\n\n/**\n * Validation issues\n */\nexport enum IssueCodes {\n MissingOppositeRelation = 'miss-opposite-relation',\n}\n\n/**\n * Expression context\n */\nexport enum ExpressionContext {\n DefaultValue = 'DefaultValue',\n AccessPolicy = 'AccessPolicy',\n ValidationRule = 'ValidationRule',\n Index = 'Index',\n}\n\n/**\n * Database providers that support list field types.\n */\nexport const DB_PROVIDERS_SUPPORTING_LIST_TYPE = ['postgresql'];\n","import { AstUtils, URI, type AstNode, type LangiumDocument, type LangiumDocuments, type Reference } from 'langium';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { PLUGIN_MODULE_NAME, STD_LIB_MODULE_NAME, type ExpressionContext } from './constants';\nimport {\n InternalAttribute,\n isArrayExpr,\n isBinaryExpr,\n isConfigArrayExpr,\n isDataField,\n isDataModel,\n isDataSource,\n isEnumField,\n isExpression,\n isInvocationExpr,\n isLiteralExpr,\n isMemberAccessExpr,\n isModel,\n isObjectExpr,\n isPlugin,\n isReferenceExpr,\n isStringLiteral,\n isTypeDef,\n type Attribute,\n type AttributeParam,\n type BinaryExpr,\n type BuiltinType,\n type ConfigExpr,\n type DataField,\n type DataFieldAttribute,\n type DataModel,\n type DataModelAttribute,\n type Enum,\n type EnumField,\n type Expression,\n type ExpressionType,\n type FunctionDecl,\n type Model,\n type ModelImport,\n type ReferenceExpr,\n type TypeDef,\n} from './generated/ast';\n\nexport type AttributeTarget =\n | DataModel\n | TypeDef\n | DataField\n | Enum\n | EnumField\n | FunctionDecl\n | Attribute\n | AttributeParam;\n\nexport function hasAttribute(decl: AttributeTarget, name: string) {\n return !!getAttribute(decl, name);\n}\n\nexport function getAttribute(decl: AttributeTarget, name: string) {\n return (decl.attributes as (DataModelAttribute | DataFieldAttribute)[]).find((attr) => attr.decl.$refText === name);\n}\n\nexport function isFromStdlib(node: AstNode) {\n const model = AstUtils.getContainerOfType(node, isModel);\n return !!model && !!model.$document && model.$document.uri.path.endsWith(STD_LIB_MODULE_NAME);\n}\n\nexport function isAuthInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'auth' && isFromStdlib(node.function.ref);\n}\n\n/**\n * Try getting string value from a potential string literal expression\n */\nexport function getStringLiteral(node: AstNode | undefined): string | undefined {\n return isStringLiteral(node) ? node.value : undefined;\n}\n\nconst isoDateTimeRegex = /^\\d{4}(-\\d\\d(-\\d\\d(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?)?)?$/i;\n\n/**\n * Determines if the given sourceType is assignable to a destination of destType\n */\nexport function typeAssignable(destType: ExpressionType, sourceType: ExpressionType, sourceExpr?: Expression): boolean {\n // implicit conversion from ISO datetime string to datetime\n if (destType === 'DateTime' && sourceType === 'String' && sourceExpr && isStringLiteral(sourceExpr)) {\n const literal = getStringLiteral(sourceExpr);\n if (literal && isoDateTimeRegex.test(literal)) {\n // implicitly convert to DateTime\n sourceType = 'DateTime';\n }\n }\n\n switch (destType) {\n case 'Any':\n return true;\n case 'Float':\n return sourceType === 'Any' || sourceType === 'Int' || sourceType === 'Float';\n default:\n return sourceType === 'Any' || sourceType === destType;\n }\n}\n\n/**\n * Maps a ZModel builtin type to expression type\n */\nexport function mapBuiltinTypeToExpressionType(type: BuiltinType | ExpressionType): ExpressionType {\n switch (type) {\n case 'Any':\n case 'Boolean':\n case 'String':\n case 'DateTime':\n case 'Int':\n case 'Float':\n case 'Null':\n case 'Object':\n case 'Unsupported':\n case 'Void':\n case 'Undefined':\n return type;\n case 'BigInt':\n return 'Int';\n case 'Decimal':\n return 'Float';\n case 'Json':\n case 'Bytes':\n return 'Any';\n }\n}\n\n/**\n * Determines if the given expression is an invocation of `auth` or a member access on the result of an `auth` invocation (e.g. `auth().role`).\n */\nexport function isAuthOrAuthMemberAccess(expr: Expression): boolean {\n return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthOrAuthMemberAccess(expr.operand));\n}\n\n/**\n * Determines if the given expression is a reference to an enum field.\n */\nexport function isEnumFieldReference(node: AstNode): node is ReferenceExpr {\n return isReferenceExpr(node) && isEnumField(node.target.ref);\n}\n\n/**\n * Determines if the given expression is a reference to a data field.\n */\nexport function isDataFieldReference(node: AstNode): node is ReferenceExpr {\n return isReferenceExpr(node) && isDataField(node.target.ref);\n}\n\n/**\n * Returns if the given field is a relation field.\n */\nexport function isRelationshipField(field: DataField) {\n return isDataModel(field.type.reference?.ref);\n}\n\n/**\n * Returns if the given field is a computed field.\n */\nexport function isComputedField(field: DataField) {\n return hasAttribute(field, '@computed');\n}\n\n/**\n * Determines if the given data model is a delegate model (i.e. marked with `@@delegate` attribute).\n */\nexport function isDelegateModel(node: AstNode) {\n return isDataModel(node) && hasAttribute(node, '@@delegate');\n}\n\n/**\n * Returns the datasource provider literal (e.g. `'postgresql'`) declared in the schema, or undefined\n * if no datasource is found or its provider is not a literal.\n */\nexport function getDataSourceProvider(model: Model) {\n const dataSource = model.declarations.find(isDataSource);\n if (!dataSource) {\n return undefined;\n }\n const providerField = dataSource.fields.find((f) => f.name === 'provider');\n if (!providerField) {\n return undefined;\n }\n return getLiteral<string>(providerField.value);\n}\n\n/**\n * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.\n */\nexport function resolved<T extends AstNode>(ref: Reference<T>): T {\n if (!ref.ref) {\n throw new Error(`Reference not resolved: ${ref.$refText}`);\n }\n return ref.ref;\n}\n\n/**\n * Gets all base models and mixins of a data model or type def, recursively.\n */\nexport function getRecursiveBases(\n decl: DataModel | TypeDef,\n includeDelegate = true,\n documents?: LangiumDocuments,\n seen = new Set<DataModel | TypeDef>(),\n): (TypeDef | DataModel)[] {\n const result: (TypeDef | DataModel)[] = [];\n if (seen.has(decl)) {\n return result;\n }\n seen.add(decl);\n const bases = [...decl.mixins, ...(isDataModel(decl) && decl.baseModel ? [decl.baseModel] : [])];\n bases.forEach((base) => {\n let baseDecl: TypeDef | DataModel | undefined;\n\n if (base.ref && (isTypeDef(base.ref) || isDataModel(base.ref))) {\n // base is already resolved\n baseDecl = base.ref;\n } else {\n // otherwise, search by name, in all imported documents if provided\n const declarations = documents\n ? getAllDeclarationsIncludingImports(documents, decl.$container)\n : decl.$container.declarations;\n\n baseDecl = declarations.find(\n (d): d is TypeDef | DataModel => (isTypeDef(d) || isDataModel(d)) && d.name === base.$refText,\n );\n }\n\n if (baseDecl) {\n if (!includeDelegate && isDelegateModel(baseDecl)) {\n return;\n }\n result.push(baseDecl);\n result.push(...getRecursiveBases(baseDecl, includeDelegate, documents, seen));\n }\n });\n return result;\n}\n\n/**\n * Gets `@@id` fields declared at the data model level (including search in base models)\n */\nexport function getModelIdFields(model: DataModel) {\n const modelsToCheck = [model, ...getRecursiveBases(model)];\n\n for (const modelToCheck of modelsToCheck) {\n const allAttributes = getAllAttributes(modelToCheck);\n const idAttr = allAttributes.find((attr) => attr.decl.$refText === '@@id');\n if (!idAttr) {\n continue;\n }\n const fieldsArg = idAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n continue;\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n }\n\n return [];\n}\n\n/**\n * Gets `@@unique` fields declared at the data model level (including search in base models)\n */\nexport function getModelUniqueFields(model: DataModel) {\n const modelsToCheck = [model, ...getRecursiveBases(model)];\n\n for (const modelToCheck of modelsToCheck) {\n const allAttributes = getAllAttributes(modelToCheck);\n const uniqueAttr = allAttributes.find((attr) => attr.decl.$refText === '@@unique');\n if (!uniqueAttr) {\n continue;\n }\n const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n continue;\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n }\n\n return [];\n}\n\n/**\n * Gets lists of unique fields declared at the data model level\n *\n * TODO: merge this with {@link getModelUniqueFields}\n */\nexport function getUniqueFields(model: DataModel) {\n const uniqueAttrs = model.attributes.filter(\n (attr) => attr.decl.ref?.name === '@@unique' || attr.decl.ref?.name === '@@id',\n );\n return uniqueAttrs.map((uniqueAttr) => {\n const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n return [];\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n });\n}\n\n/**\n * Finds the first ancestor of the given AST node that satisfies the given predicate function. Returns `undefined` if no such ancestor is found.\n */\nexport function findUpAst(node: AstNode, predicate: (node: AstNode) => boolean): AstNode | undefined {\n let curr: AstNode | undefined = node;\n while (curr) {\n if (predicate(curr)) {\n return curr;\n }\n curr = curr.$container;\n }\n return undefined;\n}\n\n/**\n * Tries to get the literal value from the given expression. Returns `undefined` if the expression is not a literal or if the literal value cannot be determined.\n */\nexport function getLiteral<T extends string | number | boolean | any = any>(\n expr: Expression | ConfigExpr | undefined,\n): T | undefined {\n switch (expr?.$type) {\n case 'ObjectExpr':\n return getObjectLiteral<T>(expr);\n case 'StringLiteral':\n case 'BooleanLiteral':\n return expr.value as T;\n case 'NumberLiteral':\n return parseFloat(expr.value) as T;\n default:\n return undefined;\n }\n}\n\n/**\n * Tries to get an object literal from the given expression. Returns `undefined` if the expression is not an object literal or if any of the field values cannot be determined.\n */\nexport function getObjectLiteral<T>(expr: Expression | ConfigExpr | undefined): T | undefined {\n if (!expr || !isObjectExpr(expr)) {\n return undefined;\n }\n const result: Record<string, unknown> = {};\n for (const field of expr.fields) {\n let fieldValue: unknown;\n if (isLiteralExpr(field.value)) {\n fieldValue = getLiteral(field.value);\n } else if (isArrayExpr(field.value)) {\n fieldValue = getLiteralArray(field.value);\n } else if (isObjectExpr(field.value)) {\n fieldValue = getObjectLiteral(field.value);\n }\n if (fieldValue === undefined) {\n return undefined;\n } else {\n result[field.name] = fieldValue;\n }\n }\n return result as T;\n}\n\nexport function getLiteralArray<T extends string | number | boolean | any = any>(\n expr: Expression | ConfigExpr | undefined,\n): T[] | undefined {\n const arr = getArray(expr);\n if (!arr) {\n return undefined;\n }\n return arr.map((item) => isExpression(item) && getLiteral<T>(item)).filter((v): v is T => v !== undefined);\n}\n\nfunction getArray(expr: Expression | ConfigExpr | undefined) {\n return isArrayExpr(expr) || isConfigArrayExpr(expr) ? expr.items : undefined;\n}\n\n/**\n * Gets the value of the argument with the given name from the given attribute. Returns `undefined` if no such argument is found or if the argument value cannot be determined.\n */\nexport function getAttributeArg(\n attr: DataModelAttribute | DataFieldAttribute | InternalAttribute,\n name: string,\n): Expression | undefined {\n return attr.args.find((arg) => arg.$resolvedParam?.name === name)?.value;\n}\n\n/**\n * Gets the literal value of the argument with the given name from the given attribute. Returns `undefined` if no such argument is found or if the argument value cannot be determined or is not a literal.\n */\nexport function getAttributeArgLiteral<T extends string | number | boolean>(\n attr: DataModelAttribute | DataFieldAttribute | InternalAttribute,\n name: string,\n): T | undefined {\n for (const arg of attr.args) {\n if (arg.$resolvedParam?.name === name) {\n return getLiteral<T>(arg.value);\n }\n }\n return undefined;\n}\n\n/**\n * Gets the allowed expression contexts for the given function declaration by looking for `@@expressionContext` attribute.\n * Returns an empty array if no such attribute is found or if the attribute value cannot be determined.\n */\nexport function getFunctionExpressionContext(funcDecl: FunctionDecl) {\n const funcAllowedContext: ExpressionContext[] = [];\n const funcAttr = funcDecl.attributes.find((attr) => attr.decl.$refText === '@@@expressionContext');\n if (funcAttr) {\n const contextArg = funcAttr.args[0]?.value;\n if (isArrayExpr(contextArg)) {\n contextArg.items.forEach((item) => {\n if (isEnumFieldReference(item)) {\n funcAllowedContext.push(item.target.$refText as ExpressionContext);\n }\n });\n }\n }\n return funcAllowedContext;\n}\n\n/**\n * Gets the data field referenced by the given expression, if any. Returns `undefined` if the expression is not a reference to a data field.\n */\nexport function getFieldReference(expr: Expression): DataField | undefined {\n if (isReferenceExpr(expr) && isDataField(expr.target.ref)) {\n return expr.target.ref;\n } else if (isMemberAccessExpr(expr) && isDataField(expr.member.ref)) {\n return expr.member.ref;\n } else {\n return undefined;\n }\n}\n\n// TODO: move to policy plugin\nexport function isCheckInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'check';\n}\n\n/**\n * Resolves the transitive imports of the given model and returns the list of imported models. The given model itself is not included in the result.\n */\nexport function resolveTransitiveImports(documents: LangiumDocuments, model: Model) {\n return resolveTransitiveImportsInternal(documents, model);\n}\n\nfunction resolveTransitiveImportsInternal(\n documents: LangiumDocuments,\n model: Model,\n initialModel = model,\n visited: Set<string> = new Set(),\n models: Set<Model> = new Set(),\n) {\n const doc = AstUtils.getDocument(model);\n const initialDoc = AstUtils.getDocument(initialModel);\n\n if (initialDoc.uri.fsPath.toLowerCase() !== doc.uri.fsPath.toLowerCase()) {\n models.add(model);\n }\n\n const normalizedPath = doc.uri.fsPath.toLowerCase();\n if (!visited.has(normalizedPath)) {\n visited.add(normalizedPath);\n for (const imp of model.imports) {\n const importedModel = resolveImport(documents, imp);\n if (importedModel) {\n resolveTransitiveImportsInternal(documents, importedModel, initialModel, visited, models);\n }\n }\n }\n return Array.from(models);\n}\n\n/**\n * Resolves the given import and returns the imported model. Returns `undefined`\n * if the import cannot be resolved.\n */\nexport function resolveImport(documents: LangiumDocuments, imp: ModelImport) {\n const resolvedUri = resolveImportUri(imp);\n try {\n if (resolvedUri) {\n let resolvedDocument = documents.getDocument(resolvedUri);\n if (!resolvedDocument) {\n const content = fs.readFileSync(resolvedUri.fsPath, 'utf-8');\n resolvedDocument = documents.createDocument(resolvedUri, content);\n }\n const node = resolvedDocument.parseResult.value;\n if (isModel(node)) {\n return node;\n }\n }\n } catch {\n // NOOP\n }\n return undefined;\n}\n\n/**\n * Resolves the given import and returns the URI of the imported model.\n * Returns `undefined` if the import cannot be resolved.\n */\nexport function resolveImportUri(imp: ModelImport) {\n if (!imp.path) {\n return undefined;\n }\n const doc = AstUtils.getDocument(imp);\n const dir = path.dirname(doc.uri.fsPath);\n const importPath = imp.path.endsWith('.zmodel') ? imp.path : `${imp.path}.zmodel`;\n return URI.file(path.resolve(dir, importPath));\n}\n\n/**\n * Gets data models and type defs in the ZModel schema.\n */\nexport function getDataModelAndTypeDefs(model: Model, includeIgnored = false) {\n const r = model.declarations.filter((d): d is DataModel | TypeDef => isDataModel(d) || isTypeDef(d));\n if (includeIgnored) {\n return r;\n } else {\n return r.filter((model) => !hasAttribute(model, '@@ignore'));\n }\n}\n\n/**\n * Gets all declarations of the given model and its transitive imports.\n */\nexport function getAllDeclarationsIncludingImports(documents: LangiumDocuments, model: Model) {\n const imports = resolveTransitiveImports(documents, model);\n return model.declarations.concat(...imports.map((imp) => imp.declarations));\n}\n\n/**\n * Gets the model used for auth context, by looking for a model with `@@auth` attribute or a model named `User`.\n * Returns `undefined` if no such model is found.\n */\nexport function getAuthDecl(decls: (DataModel | TypeDef)[]) {\n let authModel = decls.find((d) => hasAttribute(d, '@@auth'));\n if (!authModel) {\n authModel = decls.find((d) => d.name === 'User');\n }\n return authModel;\n}\n\n// TODO: move to policy plugin\nexport function isBeforeInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'before';\n}\n\n/**\n * Determines if the given AST node is a collection predicate.\n */\nexport function isCollectionPredicate(node: AstNode): node is BinaryExpr {\n return isBinaryExpr(node) && ['?', '!', '^'].includes(node.operator);\n}\n\n/**\n * Gets all data models and type defs from the given documents registry.\n */\nexport function getAllLoadedDataModelsAndTypeDefs(langiumDocuments: LangiumDocuments) {\n return langiumDocuments.all\n .map((doc) => doc.parseResult.value as Model)\n .flatMap((model) => model.declarations.filter((d): d is DataModel | TypeDef => isDataModel(d) || isTypeDef(d)))\n .toArray();\n}\n\n/**\n * Gets all data models from the given documents registry and the transitive imports of the given model.\n */\nexport function getAllDataModelsIncludingImports(documents: LangiumDocuments, model: Model) {\n return getAllDeclarationsIncludingImports(documents, model).filter(isDataModel);\n}\n\n/**\n * Gets all data models and type defs from the given documents registry and the transitive imports\n * of the given model. If `fromModel` is not provided, returns all loaded data models and type defs.\n */\nexport function getAllLoadedAndReachableDataModelsAndTypeDefs(\n langiumDocuments: LangiumDocuments,\n fromModel?: DataModel,\n) {\n // get all data models from loaded documents\n const allDataModels = getAllLoadedDataModelsAndTypeDefs(langiumDocuments);\n\n if (fromModel) {\n // merge data models transitively reached from the current model\n const model = AstUtils.getContainerOfType(fromModel, isModel);\n if (model) {\n const transitiveDataModels = getAllDataModelsIncludingImports(langiumDocuments, model);\n transitiveDataModels.forEach((dm) => {\n if (!allDataModels.includes(dm)) {\n allDataModels.push(dm);\n }\n });\n }\n }\n\n return allDataModels;\n}\n\n/**\n * Gets the containing data model of the given AST node, if any.\n * Returns `undefined` if the node is not contained in a data model.\n */\nexport function getContainingDataModel(node: AstNode): DataModel | undefined {\n let curr: AstNode | undefined = node.$container;\n while (curr) {\n if (isDataModel(curr)) {\n return curr;\n }\n curr = curr.$container;\n }\n return undefined;\n}\n\n/**\n * Determines if the given AST node can contain members.\n */\nexport function isMemberContainer(node: unknown): node is DataModel | TypeDef {\n return isDataModel(node) || isTypeDef(node);\n}\n\n/**\n * Gets all fields of a data model or type def, including inherited fields from base models and mixins.\n */\nexport function getAllFields(\n decl: DataModel | TypeDef,\n includeIgnored = false,\n seen: Set<DataModel | TypeDef> = new Set(),\n): DataField[] {\n if (seen.has(decl)) {\n return [];\n }\n seen.add(decl);\n\n const fields: DataField[] = [];\n for (const mixin of decl.mixins) {\n if (mixin.ref) {\n fields.push(...getAllFields(mixin.ref, includeIgnored, seen));\n }\n }\n\n if (isDataModel(decl) && decl.baseModel) {\n if (decl.baseModel.ref) {\n fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));\n }\n }\n\n fields.push(...decl.fields.filter((f) => includeIgnored || !hasAttribute(f, '@ignore')));\n return fields;\n}\n\n/**\n * Gets all attributes of a data model or type def, including inherited attributes\n * from base models and mixins.\n */\nexport function getAllAttributes(\n decl: DataModel | TypeDef,\n seen: Set<DataModel | TypeDef> = new Set(),\n): DataModelAttribute[] {\n if (seen.has(decl)) {\n return [];\n }\n seen.add(decl);\n\n const attributes: DataModelAttribute[] = [];\n for (const mixin of decl.mixins) {\n if (mixin.ref) {\n attributes.push(...getAllAttributes(mixin.ref, seen));\n }\n }\n\n if (isDataModel(decl) && decl.baseModel) {\n if (decl.baseModel.ref) {\n const attrs = getAllAttributes(decl.baseModel.ref, seen).filter((attr) => !isNonInheritableAttribute(attr));\n attributes.push(...attrs);\n }\n }\n\n attributes.push(...decl.attributes);\n return attributes;\n}\n\nfunction isNonInheritableAttribute(attr: DataModelAttribute) {\n const attrName = attr.decl.ref?.name ?? attr.decl.$refText;\n return ['@@map', '@@unique', '@@index'].includes(attrName);\n}\n\n/**\n * Retrieve the document in which the given AST node is contained. A reference to the document is\n * usually held by the root node of the AST.\n *\n * @throws an error if the node is not contained in a document.\n */\nexport function getDocument<T extends AstNode = AstNode>(node: AstNode): LangiumDocument<T> {\n const rootNode = findRootNode(node);\n const result = rootNode.$document;\n if (!result) {\n throw new Error('AST node has no document.');\n }\n return result as LangiumDocument<T>;\n}\n\n/**\n * Gets the list of plugin documents from the given model.\n */\nexport function getPluginDocuments(model: Model, schemaPath: string): string[] {\n // traverse plugins and collect \"plugin.zmodel\" documents\n const result: string[] = [];\n for (const decl of model.declarations.filter(isPlugin)) {\n const providerField = decl.fields.find((f) => f.name === 'provider');\n if (!providerField) {\n continue;\n }\n\n const provider = getLiteral<string>(providerField.value);\n if (!provider) {\n continue;\n }\n\n let pluginModelFile: string | undefined;\n\n // first try to treat provider as a path\n let providerPath = path.resolve(path.dirname(schemaPath), provider);\n if (fs.existsSync(providerPath)) {\n if (fs.statSync(providerPath).isDirectory()) {\n providerPath = path.join(providerPath, 'index.js');\n }\n\n // try plugin.zmodel next to the provider file\n pluginModelFile = path.resolve(path.dirname(providerPath), PLUGIN_MODULE_NAME);\n if (!fs.existsSync(pluginModelFile)) {\n // try to find upwards\n pluginModelFile = findUp([PLUGIN_MODULE_NAME], path.dirname(providerPath));\n }\n }\n\n if (!pluginModelFile) {\n if (typeof import.meta.resolve === 'function') {\n try {\n // try loading as a ESM module\n const resolvedUrl = import.meta.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);\n pluginModelFile = fileURLToPath(resolvedUrl);\n } catch {\n // noop\n }\n }\n }\n\n if (!pluginModelFile) {\n // try loading as a CJS module\n try {\n const require = createRequire(pathToFileURL(schemaPath));\n pluginModelFile = require.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);\n } catch {\n // noop\n }\n }\n\n if (pluginModelFile && fs.existsSync(pluginModelFile)) {\n result.push(pluginModelFile);\n }\n }\n return result;\n}\n\ntype FindUpResult<Multiple extends boolean> = Multiple extends true ? string[] | undefined : string | undefined;\n\nfunction findUp<Multiple extends boolean = false>(\n names: string[],\n cwd: string = process.cwd(),\n multiple: Multiple = false as Multiple,\n result: string[] = [],\n): FindUpResult<Multiple> {\n if (!names.some((name) => !!name)) {\n return undefined;\n }\n const target = names.find((name) => fs.existsSync(path.join(cwd, name)));\n if (multiple === false && target) {\n return path.join(cwd, target) as FindUpResult<Multiple>;\n }\n if (target) {\n result.push(path.join(cwd, target));\n }\n const up = path.resolve(cwd, '..');\n if (up === cwd) {\n return (multiple && result.length > 0 ? result : undefined) as FindUpResult<Multiple>;\n }\n return findUp(names, up, multiple, result);\n}\n\n/**\n * Returns the root node of the given AST node by following the `$container` references.\n */\nexport function findRootNode(node: AstNode): AstNode {\n while (node.$container) {\n node = node.$container;\n }\n return node;\n}\n"],"mappings":"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"}
package/dist/utils.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_utils = require("./utils-CfXGZkv7.cjs");
2
+ const require_utils = require("./utils-b3dJKmYr.cjs");
3
3
  exports.findRootNode = require_utils.findRootNode;
4
4
  exports.findUpAst = require_utils.findUpAst;
5
5
  exports.getAllAttributes = require_utils.getAllAttributes;
@@ -14,6 +14,7 @@ exports.getAttributeArgLiteral = require_utils.getAttributeArgLiteral;
14
14
  exports.getAuthDecl = require_utils.getAuthDecl;
15
15
  exports.getContainingDataModel = require_utils.getContainingDataModel;
16
16
  exports.getDataModelAndTypeDefs = require_utils.getDataModelAndTypeDefs;
17
+ exports.getDataSourceProvider = require_utils.getDataSourceProvider;
17
18
  exports.getDocument = require_utils.getDocument;
18
19
  exports.getFieldReference = require_utils.getFieldReference;
19
20
  exports.getFunctionExpressionContext = require_utils.getFunctionExpressionContext;
package/dist/utils.d.cts CHANGED
@@ -54,6 +54,11 @@ declare function isComputedField(field: DataField): boolean;
54
54
  * Determines if the given data model is a delegate model (i.e. marked with `@@delegate` attribute).
55
55
  */
56
56
  declare function isDelegateModel(node: AstNode): boolean;
57
+ /**
58
+ * Returns the datasource provider literal (e.g. `'postgresql'`) declared in the schema, or undefined
59
+ * if no datasource is found or its provider is not a literal.
60
+ */
61
+ declare function getDataSourceProvider(model: Model): string | undefined;
57
62
  /**
58
63
  * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.
59
64
  */
@@ -186,5 +191,5 @@ declare function getPluginDocuments(model: Model, schemaPath: string): string[];
186
191
  */
187
192
  declare function findRootNode(node: AstNode): AstNode;
188
193
  //#endregion
189
- export { AttributeTarget, findRootNode, findUpAst, getAllAttributes, getAllDataModelsIncludingImports, getAllDeclarationsIncludingImports, getAllFields, getAllLoadedAndReachableDataModelsAndTypeDefs, getAllLoadedDataModelsAndTypeDefs, getAttribute, getAttributeArg, getAttributeArgLiteral, getAuthDecl, getContainingDataModel, getDataModelAndTypeDefs, getDocument, getFieldReference, getFunctionExpressionContext, getLiteral, getLiteralArray, getModelIdFields, getModelUniqueFields, getObjectLiteral, getPluginDocuments, getRecursiveBases, getStringLiteral, getUniqueFields, hasAttribute, isAuthInvocation, isAuthOrAuthMemberAccess, isBeforeInvocation, isCheckInvocation, isCollectionPredicate, isComputedField, isDataFieldReference, isDelegateModel, isEnumFieldReference, isFromStdlib, isMemberContainer, isRelationshipField, mapBuiltinTypeToExpressionType, resolveImport, resolveImportUri, resolveTransitiveImports, resolved, typeAssignable };
194
+ export { AttributeTarget, findRootNode, findUpAst, getAllAttributes, getAllDataModelsIncludingImports, getAllDeclarationsIncludingImports, getAllFields, getAllLoadedAndReachableDataModelsAndTypeDefs, getAllLoadedDataModelsAndTypeDefs, getAttribute, getAttributeArg, getAttributeArgLiteral, getAuthDecl, getContainingDataModel, getDataModelAndTypeDefs, getDataSourceProvider, getDocument, getFieldReference, getFunctionExpressionContext, getLiteral, getLiteralArray, getModelIdFields, getModelUniqueFields, getObjectLiteral, getPluginDocuments, getRecursiveBases, getStringLiteral, getUniqueFields, hasAttribute, isAuthInvocation, isAuthOrAuthMemberAccess, isBeforeInvocation, isCheckInvocation, isCollectionPredicate, isComputedField, isDataFieldReference, isDelegateModel, isEnumFieldReference, isFromStdlib, isMemberContainer, isRelationshipField, mapBuiltinTypeToExpressionType, resolveImport, resolveImportUri, resolveTransitiveImports, resolved, typeAssignable };
190
195
  //# sourceMappingURL=utils.d.cts.map
package/dist/utils.d.mts CHANGED
@@ -54,6 +54,11 @@ declare function isComputedField(field: DataField): boolean;
54
54
  * Determines if the given data model is a delegate model (i.e. marked with `@@delegate` attribute).
55
55
  */
56
56
  declare function isDelegateModel(node: AstNode): boolean;
57
+ /**
58
+ * Returns the datasource provider literal (e.g. `'postgresql'`) declared in the schema, or undefined
59
+ * if no datasource is found or its provider is not a literal.
60
+ */
61
+ declare function getDataSourceProvider(model: Model): string | undefined;
57
62
  /**
58
63
  * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.
59
64
  */
@@ -186,5 +191,5 @@ declare function getPluginDocuments(model: Model, schemaPath: string): string[];
186
191
  */
187
192
  declare function findRootNode(node: AstNode): AstNode;
188
193
  //#endregion
189
- export { AttributeTarget, findRootNode, findUpAst, getAllAttributes, getAllDataModelsIncludingImports, getAllDeclarationsIncludingImports, getAllFields, getAllLoadedAndReachableDataModelsAndTypeDefs, getAllLoadedDataModelsAndTypeDefs, getAttribute, getAttributeArg, getAttributeArgLiteral, getAuthDecl, getContainingDataModel, getDataModelAndTypeDefs, getDocument, getFieldReference, getFunctionExpressionContext, getLiteral, getLiteralArray, getModelIdFields, getModelUniqueFields, getObjectLiteral, getPluginDocuments, getRecursiveBases, getStringLiteral, getUniqueFields, hasAttribute, isAuthInvocation, isAuthOrAuthMemberAccess, isBeforeInvocation, isCheckInvocation, isCollectionPredicate, isComputedField, isDataFieldReference, isDelegateModel, isEnumFieldReference, isFromStdlib, isMemberContainer, isRelationshipField, mapBuiltinTypeToExpressionType, resolveImport, resolveImportUri, resolveTransitiveImports, resolved, typeAssignable };
194
+ export { AttributeTarget, findRootNode, findUpAst, getAllAttributes, getAllDataModelsIncludingImports, getAllDeclarationsIncludingImports, getAllFields, getAllLoadedAndReachableDataModelsAndTypeDefs, getAllLoadedDataModelsAndTypeDefs, getAttribute, getAttributeArg, getAttributeArgLiteral, getAuthDecl, getContainingDataModel, getDataModelAndTypeDefs, getDataSourceProvider, getDocument, getFieldReference, getFunctionExpressionContext, getLiteral, getLiteralArray, getModelIdFields, getModelUniqueFields, getObjectLiteral, getPluginDocuments, getRecursiveBases, getStringLiteral, getUniqueFields, hasAttribute, isAuthInvocation, isAuthOrAuthMemberAccess, isBeforeInvocation, isCheckInvocation, isCollectionPredicate, isComputedField, isDataFieldReference, isDelegateModel, isEnumFieldReference, isFromStdlib, isMemberContainer, isRelationshipField, mapBuiltinTypeToExpressionType, resolveImport, resolveImportUri, resolveTransitiveImports, resolved, typeAssignable };
190
195
  //# sourceMappingURL=utils.d.mts.map
package/dist/utils.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { A as isBeforeInvocation, B as mapBuiltinTypeToExpressionType, C as getPluginDocuments, D as hasAttribute, E as getUniqueFields, F as isDelegateModel, G as typeAssignable, H as resolveImportUri, I as isEnumFieldReference, L as isFromStdlib, M as isCollectionPredicate, N as isComputedField, O as isAuthInvocation, P as isDataFieldReference, R as isMemberContainer, S as getObjectLiteral, T as getStringLiteral, U as resolveTransitiveImports, V as resolveImport, W as resolved, _ as getFunctionExpressionContext, a as getAllDeclarationsIncludingImports, b as getModelIdFields, c as getAllLoadedDataModelsAndTypeDefs, d as getAttributeArgLiteral, f as getAuthDecl, g as getFieldReference, h as getDocument, i as getAllDataModelsIncludingImports, j as isCheckInvocation, k as isAuthOrAuthMemberAccess, l as getAttribute, m as getDataModelAndTypeDefs, n as findUpAst, o as getAllFields, p as getContainingDataModel, r as getAllAttributes, s as getAllLoadedAndReachableDataModelsAndTypeDefs, t as findRootNode, u as getAttributeArg, v as getLiteral, w as getRecursiveBases, x as getModelUniqueFields, y as getLiteralArray, z as isRelationshipField } from "./utils-BB6L7ug2.mjs";
2
- export { findRootNode, findUpAst, getAllAttributes, getAllDataModelsIncludingImports, getAllDeclarationsIncludingImports, getAllFields, getAllLoadedAndReachableDataModelsAndTypeDefs, getAllLoadedDataModelsAndTypeDefs, getAttribute, getAttributeArg, getAttributeArgLiteral, getAuthDecl, getContainingDataModel, getDataModelAndTypeDefs, getDocument, getFieldReference, getFunctionExpressionContext, getLiteral, getLiteralArray, getModelIdFields, getModelUniqueFields, getObjectLiteral, getPluginDocuments, getRecursiveBases, getStringLiteral, getUniqueFields, hasAttribute, isAuthInvocation, isAuthOrAuthMemberAccess, isBeforeInvocation, isCheckInvocation, isCollectionPredicate, isComputedField, isDataFieldReference, isDelegateModel, isEnumFieldReference, isFromStdlib, isMemberContainer, isRelationshipField, mapBuiltinTypeToExpressionType, resolveImport, resolveImportUri, resolveTransitiveImports, resolved, typeAssignable };
1
+ import { A as isAuthOrAuthMemberAccess, B as isRelationshipField, C as getObjectLiteral, D as getUniqueFields, E as getStringLiteral, F as isDataFieldReference, G as resolved, H as resolveImport, I as isDelegateModel, K as typeAssignable, L as isEnumFieldReference, M as isCheckInvocation, N as isCollectionPredicate, O as hasAttribute, P as isComputedField, R as isFromStdlib, S as getModelUniqueFields, T as getRecursiveBases, U as resolveImportUri, V as mapBuiltinTypeToExpressionType, W as resolveTransitiveImports, _ as getFieldReference, a as getAllDeclarationsIncludingImports, b as getLiteralArray, c as getAllLoadedDataModelsAndTypeDefs, d as getAttributeArgLiteral, f as getAuthDecl, g as getDocument, h as getDataSourceProvider, i as getAllDataModelsIncludingImports, j as isBeforeInvocation, k as isAuthInvocation, l as getAttribute, m as getDataModelAndTypeDefs, n as findUpAst, o as getAllFields, p as getContainingDataModel, r as getAllAttributes, s as getAllLoadedAndReachableDataModelsAndTypeDefs, t as findRootNode, u as getAttributeArg, v as getFunctionExpressionContext, w as getPluginDocuments, x as getModelIdFields, y as getLiteral, z as isMemberContainer } from "./utils-CCU55PfR.mjs";
2
+ export { findRootNode, findUpAst, getAllAttributes, getAllDataModelsIncludingImports, getAllDeclarationsIncludingImports, getAllFields, getAllLoadedAndReachableDataModelsAndTypeDefs, getAllLoadedDataModelsAndTypeDefs, getAttribute, getAttributeArg, getAttributeArgLiteral, getAuthDecl, getContainingDataModel, getDataModelAndTypeDefs, getDataSourceProvider, getDocument, getFieldReference, getFunctionExpressionContext, getLiteral, getLiteralArray, getModelIdFields, getModelUniqueFields, getObjectLiteral, getPluginDocuments, getRecursiveBases, getStringLiteral, getUniqueFields, hasAttribute, isAuthInvocation, isAuthOrAuthMemberAccess, isBeforeInvocation, isCheckInvocation, isCollectionPredicate, isComputedField, isDataFieldReference, isDelegateModel, isEnumFieldReference, isFromStdlib, isMemberContainer, isRelationshipField, mapBuiltinTypeToExpressionType, resolveImport, resolveImportUri, resolveTransitiveImports, resolved, typeAssignable };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@zenstackhq/language",
3
3
  "displayName": "ZenStack Language Tooling",
4
4
  "description": "ZenStack ZModel language specification",
5
- "version": "3.7.0-beta.1",
5
+ "version": "3.7.1",
6
6
  "type": "module",
7
7
  "author": {
8
8
  "name": "ZenStack Team",
@@ -69,7 +69,7 @@
69
69
  "pluralize": "^8.0.0",
70
70
  "ts-pattern": "^5.7.1",
71
71
  "vscode-languageserver": "^9.0.1",
72
- "@zenstackhq/common-helpers": "3.7.0-beta.1"
72
+ "@zenstackhq/common-helpers": "3.7.1"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@types/pluralize": "^0.0.33",
@@ -77,10 +77,10 @@
77
77
  "glob": "^11.1.0",
78
78
  "langium-cli": "3.5.0",
79
79
  "tmp": "^0.2.4",
80
- "@zenstackhq/typescript-config": "3.7.0-beta.1",
81
- "@zenstackhq/eslint-config": "3.7.0-beta.1",
82
- "@zenstackhq/tsdown-config": "3.7.0-beta.1",
83
- "@zenstackhq/vitest-config": "3.7.0-beta.1"
80
+ "@zenstackhq/eslint-config": "3.7.1",
81
+ "@zenstackhq/tsdown-config": "3.7.1",
82
+ "@zenstackhq/vitest-config": "3.7.1",
83
+ "@zenstackhq/typescript-config": "3.7.1"
84
84
  },
85
85
  "funding": "https://github.com/sponsors/zenstackhq",
86
86
  "scripts": {
package/res/stdlib.zmodel CHANGED
@@ -394,12 +394,26 @@ attribute @ignore() @@@prisma
394
394
  attribute @@ignore() @@@prisma
395
395
 
396
396
  /**
397
- * Indicates that the field should be omitted by default when read with an ORM client. The omission can be
397
+ * Indicates that the field should be omitted by default when read with an ORM client. The omission can be
398
398
  * overridden in options passed to create `ZenStackClient`, or at query time by explicitly passing in an
399
399
  * `omit` clause. The attribute is only effective for ORM query APIs, not for query-builder APIs.
400
400
  */
401
401
  attribute @omit()
402
402
 
403
+ /**
404
+ * Marks a `String` field as fuzzy-searchable. Fields with this attribute can be used with the
405
+ * `fuzzy` filter operator and the `_fuzzyRelevance` orderBy. Fuzzy search is currently
406
+ * supported only on the `postgresql` provider (requires `pg_trgm` extension).
407
+ */
408
+ attribute @fuzzy() @@@targetField([StringField]) @@@once
409
+
410
+ /**
411
+ * Marks a `String` field as full-text-searchable. Fields with this attribute can be used with the
412
+ * `fts` filter operator and the `_ftsRelevance` orderBy. Full-text search is currently
413
+ * supported only on the `postgresql` provider (uses `to_tsvector` / `to_tsquery` / `ts_rank`).
414
+ */
415
+ attribute @fullText() @@@targetField([StringField]) @@@once
416
+
403
417
  /**
404
418
  * Automatically stores the time when a record was last updated.
405
419
  *
@@ -627,6 +641,13 @@ attribute @@prisma.passthrough(_ text: String)
627
641
  */
628
642
  attribute @@delegate(_ discriminator: FieldReference)
629
643
 
644
+ /**
645
+ * Maps a delegate sub-model to a specific discriminator value. If not set the sub-model name is used as the discriminator value by default.
646
+ *
647
+ * @param value: A string literal or enum member used as the discriminator.
648
+ */
649
+ attribute @@delegateMap(_ value: Any)
650
+
630
651
  /**
631
652
  * Used for specifying operator classes for GIN index.
632
653
  */
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-BB6L7ug2.mjs","names":[],"sources":["../src/constants.ts","../src/utils.ts"],"sourcesContent":["/**\n * Supported db providers\n */\nexport const SUPPORTED_PROVIDERS = ['sqlite', 'postgresql', 'mysql'];\n\n/**\n * All scalar types\n */\nexport const SCALAR_TYPES = ['String', 'Int', 'Float', 'Decimal', 'BigInt', 'Boolean', 'Bytes', 'DateTime'];\n\n/**\n * Name of standard library module\n */\nexport const STD_LIB_MODULE_NAME = 'stdlib.zmodel';\n\n/**\n * Name of module contributed by plugins\n */\nexport const PLUGIN_MODULE_NAME = 'plugin.zmodel';\n\n/**\n * Validation issues\n */\nexport enum IssueCodes {\n MissingOppositeRelation = 'miss-opposite-relation',\n}\n\n/**\n * Expression context\n */\nexport enum ExpressionContext {\n DefaultValue = 'DefaultValue',\n AccessPolicy = 'AccessPolicy',\n ValidationRule = 'ValidationRule',\n Index = 'Index',\n}\n\n/**\n * Database providers that support list field types.\n */\nexport const DB_PROVIDERS_SUPPORTING_LIST_TYPE = ['postgresql'];\n","import { AstUtils, URI, type AstNode, type LangiumDocument, type LangiumDocuments, type Reference } from 'langium';\nimport fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport { PLUGIN_MODULE_NAME, STD_LIB_MODULE_NAME, type ExpressionContext } from './constants';\nimport {\n InternalAttribute,\n isArrayExpr,\n isBinaryExpr,\n isConfigArrayExpr,\n isDataField,\n isDataModel,\n isEnumField,\n isExpression,\n isInvocationExpr,\n isLiteralExpr,\n isMemberAccessExpr,\n isModel,\n isObjectExpr,\n isPlugin,\n isReferenceExpr,\n isStringLiteral,\n isTypeDef,\n type Attribute,\n type AttributeParam,\n type BinaryExpr,\n type BuiltinType,\n type ConfigExpr,\n type DataField,\n type DataFieldAttribute,\n type DataModel,\n type DataModelAttribute,\n type Enum,\n type EnumField,\n type Expression,\n type ExpressionType,\n type FunctionDecl,\n type Model,\n type ModelImport,\n type ReferenceExpr,\n type TypeDef,\n} from './generated/ast';\n\nexport type AttributeTarget =\n | DataModel\n | TypeDef\n | DataField\n | Enum\n | EnumField\n | FunctionDecl\n | Attribute\n | AttributeParam;\n\nexport function hasAttribute(decl: AttributeTarget, name: string) {\n return !!getAttribute(decl, name);\n}\n\nexport function getAttribute(decl: AttributeTarget, name: string) {\n return (decl.attributes as (DataModelAttribute | DataFieldAttribute)[]).find((attr) => attr.decl.$refText === name);\n}\n\nexport function isFromStdlib(node: AstNode) {\n const model = AstUtils.getContainerOfType(node, isModel);\n return !!model && !!model.$document && model.$document.uri.path.endsWith(STD_LIB_MODULE_NAME);\n}\n\nexport function isAuthInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'auth' && isFromStdlib(node.function.ref);\n}\n\n/**\n * Try getting string value from a potential string literal expression\n */\nexport function getStringLiteral(node: AstNode | undefined): string | undefined {\n return isStringLiteral(node) ? node.value : undefined;\n}\n\nconst isoDateTimeRegex = /^\\d{4}(-\\d\\d(-\\d\\d(T\\d\\d:\\d\\d(:\\d\\d)?(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?)?)?)?$/i;\n\n/**\n * Determines if the given sourceType is assignable to a destination of destType\n */\nexport function typeAssignable(destType: ExpressionType, sourceType: ExpressionType, sourceExpr?: Expression): boolean {\n // implicit conversion from ISO datetime string to datetime\n if (destType === 'DateTime' && sourceType === 'String' && sourceExpr && isStringLiteral(sourceExpr)) {\n const literal = getStringLiteral(sourceExpr);\n if (literal && isoDateTimeRegex.test(literal)) {\n // implicitly convert to DateTime\n sourceType = 'DateTime';\n }\n }\n\n switch (destType) {\n case 'Any':\n return true;\n case 'Float':\n return sourceType === 'Any' || sourceType === 'Int' || sourceType === 'Float';\n default:\n return sourceType === 'Any' || sourceType === destType;\n }\n}\n\n/**\n * Maps a ZModel builtin type to expression type\n */\nexport function mapBuiltinTypeToExpressionType(type: BuiltinType | ExpressionType): ExpressionType {\n switch (type) {\n case 'Any':\n case 'Boolean':\n case 'String':\n case 'DateTime':\n case 'Int':\n case 'Float':\n case 'Null':\n case 'Object':\n case 'Unsupported':\n case 'Void':\n case 'Undefined':\n return type;\n case 'BigInt':\n return 'Int';\n case 'Decimal':\n return 'Float';\n case 'Json':\n case 'Bytes':\n return 'Any';\n }\n}\n\n/**\n * Determines if the given expression is an invocation of `auth` or a member access on the result of an `auth` invocation (e.g. `auth().role`).\n */\nexport function isAuthOrAuthMemberAccess(expr: Expression): boolean {\n return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthOrAuthMemberAccess(expr.operand));\n}\n\n/**\n * Determines if the given expression is a reference to an enum field.\n */\nexport function isEnumFieldReference(node: AstNode): node is ReferenceExpr {\n return isReferenceExpr(node) && isEnumField(node.target.ref);\n}\n\n/**\n * Determines if the given expression is a reference to a data field.\n */\nexport function isDataFieldReference(node: AstNode): node is ReferenceExpr {\n return isReferenceExpr(node) && isDataField(node.target.ref);\n}\n\n/**\n * Returns if the given field is a relation field.\n */\nexport function isRelationshipField(field: DataField) {\n return isDataModel(field.type.reference?.ref);\n}\n\n/**\n * Returns if the given field is a computed field.\n */\nexport function isComputedField(field: DataField) {\n return hasAttribute(field, '@computed');\n}\n\n/**\n * Determines if the given data model is a delegate model (i.e. marked with `@@delegate` attribute).\n */\nexport function isDelegateModel(node: AstNode) {\n return isDataModel(node) && hasAttribute(node, '@@delegate');\n}\n\n/**\n * Resolves the given reference and returns the target AST node. Throws an error if the reference is not resolved.\n */\nexport function resolved<T extends AstNode>(ref: Reference<T>): T {\n if (!ref.ref) {\n throw new Error(`Reference not resolved: ${ref.$refText}`);\n }\n return ref.ref;\n}\n\n/**\n * Gets all base models and mixins of a data model or type def, recursively.\n */\nexport function getRecursiveBases(\n decl: DataModel | TypeDef,\n includeDelegate = true,\n documents?: LangiumDocuments,\n seen = new Set<DataModel | TypeDef>(),\n): (TypeDef | DataModel)[] {\n const result: (TypeDef | DataModel)[] = [];\n if (seen.has(decl)) {\n return result;\n }\n seen.add(decl);\n const bases = [...decl.mixins, ...(isDataModel(decl) && decl.baseModel ? [decl.baseModel] : [])];\n bases.forEach((base) => {\n let baseDecl: TypeDef | DataModel | undefined;\n\n if (base.ref && (isTypeDef(base.ref) || isDataModel(base.ref))) {\n // base is already resolved\n baseDecl = base.ref;\n } else {\n // otherwise, search by name, in all imported documents if provided\n const declarations = documents\n ? getAllDeclarationsIncludingImports(documents, decl.$container)\n : decl.$container.declarations;\n\n baseDecl = declarations.find(\n (d): d is TypeDef | DataModel => (isTypeDef(d) || isDataModel(d)) && d.name === base.$refText,\n );\n }\n\n if (baseDecl) {\n if (!includeDelegate && isDelegateModel(baseDecl)) {\n return;\n }\n result.push(baseDecl);\n result.push(...getRecursiveBases(baseDecl, includeDelegate, documents, seen));\n }\n });\n return result;\n}\n\n/**\n * Gets `@@id` fields declared at the data model level (including search in base models)\n */\nexport function getModelIdFields(model: DataModel) {\n const modelsToCheck = [model, ...getRecursiveBases(model)];\n\n for (const modelToCheck of modelsToCheck) {\n const allAttributes = getAllAttributes(modelToCheck);\n const idAttr = allAttributes.find((attr) => attr.decl.$refText === '@@id');\n if (!idAttr) {\n continue;\n }\n const fieldsArg = idAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n continue;\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n }\n\n return [];\n}\n\n/**\n * Gets `@@unique` fields declared at the data model level (including search in base models)\n */\nexport function getModelUniqueFields(model: DataModel) {\n const modelsToCheck = [model, ...getRecursiveBases(model)];\n\n for (const modelToCheck of modelsToCheck) {\n const allAttributes = getAllAttributes(modelToCheck);\n const uniqueAttr = allAttributes.find((attr) => attr.decl.$refText === '@@unique');\n if (!uniqueAttr) {\n continue;\n }\n const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n continue;\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n }\n\n return [];\n}\n\n/**\n * Gets lists of unique fields declared at the data model level\n *\n * TODO: merge this with {@link getModelUniqueFields}\n */\nexport function getUniqueFields(model: DataModel) {\n const uniqueAttrs = model.attributes.filter(\n (attr) => attr.decl.ref?.name === '@@unique' || attr.decl.ref?.name === '@@id',\n );\n return uniqueAttrs.map((uniqueAttr) => {\n const fieldsArg = uniqueAttr.args.find((a) => a.$resolvedParam?.name === 'fields');\n if (!fieldsArg || !isArrayExpr(fieldsArg.value)) {\n return [];\n }\n\n return fieldsArg.value.items\n .filter((item): item is ReferenceExpr => isReferenceExpr(item))\n .map((item) => resolved(item.target) as DataField);\n });\n}\n\n/**\n * Finds the first ancestor of the given AST node that satisfies the given predicate function. Returns `undefined` if no such ancestor is found.\n */\nexport function findUpAst(node: AstNode, predicate: (node: AstNode) => boolean): AstNode | undefined {\n let curr: AstNode | undefined = node;\n while (curr) {\n if (predicate(curr)) {\n return curr;\n }\n curr = curr.$container;\n }\n return undefined;\n}\n\n/**\n * Tries to get the literal value from the given expression. Returns `undefined` if the expression is not a literal or if the literal value cannot be determined.\n */\nexport function getLiteral<T extends string | number | boolean | any = any>(\n expr: Expression | ConfigExpr | undefined,\n): T | undefined {\n switch (expr?.$type) {\n case 'ObjectExpr':\n return getObjectLiteral<T>(expr);\n case 'StringLiteral':\n case 'BooleanLiteral':\n return expr.value as T;\n case 'NumberLiteral':\n return parseFloat(expr.value) as T;\n default:\n return undefined;\n }\n}\n\n/**\n * Tries to get an object literal from the given expression. Returns `undefined` if the expression is not an object literal or if any of the field values cannot be determined.\n */\nexport function getObjectLiteral<T>(expr: Expression | ConfigExpr | undefined): T | undefined {\n if (!expr || !isObjectExpr(expr)) {\n return undefined;\n }\n const result: Record<string, unknown> = {};\n for (const field of expr.fields) {\n let fieldValue: unknown;\n if (isLiteralExpr(field.value)) {\n fieldValue = getLiteral(field.value);\n } else if (isArrayExpr(field.value)) {\n fieldValue = getLiteralArray(field.value);\n } else if (isObjectExpr(field.value)) {\n fieldValue = getObjectLiteral(field.value);\n }\n if (fieldValue === undefined) {\n return undefined;\n } else {\n result[field.name] = fieldValue;\n }\n }\n return result as T;\n}\n\nexport function getLiteralArray<T extends string | number | boolean | any = any>(\n expr: Expression | ConfigExpr | undefined,\n): T[] | undefined {\n const arr = getArray(expr);\n if (!arr) {\n return undefined;\n }\n return arr.map((item) => isExpression(item) && getLiteral<T>(item)).filter((v): v is T => v !== undefined);\n}\n\nfunction getArray(expr: Expression | ConfigExpr | undefined) {\n return isArrayExpr(expr) || isConfigArrayExpr(expr) ? expr.items : undefined;\n}\n\n/**\n * Gets the value of the argument with the given name from the given attribute. Returns `undefined` if no such argument is found or if the argument value cannot be determined.\n */\nexport function getAttributeArg(\n attr: DataModelAttribute | DataFieldAttribute | InternalAttribute,\n name: string,\n): Expression | undefined {\n return attr.args.find((arg) => arg.$resolvedParam?.name === name)?.value;\n}\n\n/**\n * Gets the literal value of the argument with the given name from the given attribute. Returns `undefined` if no such argument is found or if the argument value cannot be determined or is not a literal.\n */\nexport function getAttributeArgLiteral<T extends string | number | boolean>(\n attr: DataModelAttribute | DataFieldAttribute | InternalAttribute,\n name: string,\n): T | undefined {\n for (const arg of attr.args) {\n if (arg.$resolvedParam?.name === name) {\n return getLiteral<T>(arg.value);\n }\n }\n return undefined;\n}\n\n/**\n * Gets the allowed expression contexts for the given function declaration by looking for `@@expressionContext` attribute.\n * Returns an empty array if no such attribute is found or if the attribute value cannot be determined.\n */\nexport function getFunctionExpressionContext(funcDecl: FunctionDecl) {\n const funcAllowedContext: ExpressionContext[] = [];\n const funcAttr = funcDecl.attributes.find((attr) => attr.decl.$refText === '@@@expressionContext');\n if (funcAttr) {\n const contextArg = funcAttr.args[0]?.value;\n if (isArrayExpr(contextArg)) {\n contextArg.items.forEach((item) => {\n if (isEnumFieldReference(item)) {\n funcAllowedContext.push(item.target.$refText as ExpressionContext);\n }\n });\n }\n }\n return funcAllowedContext;\n}\n\n/**\n * Gets the data field referenced by the given expression, if any. Returns `undefined` if the expression is not a reference to a data field.\n */\nexport function getFieldReference(expr: Expression): DataField | undefined {\n if (isReferenceExpr(expr) && isDataField(expr.target.ref)) {\n return expr.target.ref;\n } else if (isMemberAccessExpr(expr) && isDataField(expr.member.ref)) {\n return expr.member.ref;\n } else {\n return undefined;\n }\n}\n\n// TODO: move to policy plugin\nexport function isCheckInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'check';\n}\n\n/**\n * Resolves the transitive imports of the given model and returns the list of imported models. The given model itself is not included in the result.\n */\nexport function resolveTransitiveImports(documents: LangiumDocuments, model: Model) {\n return resolveTransitiveImportsInternal(documents, model);\n}\n\nfunction resolveTransitiveImportsInternal(\n documents: LangiumDocuments,\n model: Model,\n initialModel = model,\n visited: Set<string> = new Set(),\n models: Set<Model> = new Set(),\n) {\n const doc = AstUtils.getDocument(model);\n const initialDoc = AstUtils.getDocument(initialModel);\n\n if (initialDoc.uri.fsPath.toLowerCase() !== doc.uri.fsPath.toLowerCase()) {\n models.add(model);\n }\n\n const normalizedPath = doc.uri.fsPath.toLowerCase();\n if (!visited.has(normalizedPath)) {\n visited.add(normalizedPath);\n for (const imp of model.imports) {\n const importedModel = resolveImport(documents, imp);\n if (importedModel) {\n resolveTransitiveImportsInternal(documents, importedModel, initialModel, visited, models);\n }\n }\n }\n return Array.from(models);\n}\n\n/**\n * Resolves the given import and returns the imported model. Returns `undefined`\n * if the import cannot be resolved.\n */\nexport function resolveImport(documents: LangiumDocuments, imp: ModelImport) {\n const resolvedUri = resolveImportUri(imp);\n try {\n if (resolvedUri) {\n let resolvedDocument = documents.getDocument(resolvedUri);\n if (!resolvedDocument) {\n const content = fs.readFileSync(resolvedUri.fsPath, 'utf-8');\n resolvedDocument = documents.createDocument(resolvedUri, content);\n }\n const node = resolvedDocument.parseResult.value;\n if (isModel(node)) {\n return node;\n }\n }\n } catch {\n // NOOP\n }\n return undefined;\n}\n\n/**\n * Resolves the given import and returns the URI of the imported model.\n * Returns `undefined` if the import cannot be resolved.\n */\nexport function resolveImportUri(imp: ModelImport) {\n if (!imp.path) {\n return undefined;\n }\n const doc = AstUtils.getDocument(imp);\n const dir = path.dirname(doc.uri.fsPath);\n const importPath = imp.path.endsWith('.zmodel') ? imp.path : `${imp.path}.zmodel`;\n return URI.file(path.resolve(dir, importPath));\n}\n\n/**\n * Gets data models and type defs in the ZModel schema.\n */\nexport function getDataModelAndTypeDefs(model: Model, includeIgnored = false) {\n const r = model.declarations.filter((d): d is DataModel | TypeDef => isDataModel(d) || isTypeDef(d));\n if (includeIgnored) {\n return r;\n } else {\n return r.filter((model) => !hasAttribute(model, '@@ignore'));\n }\n}\n\n/**\n * Gets all declarations of the given model and its transitive imports.\n */\nexport function getAllDeclarationsIncludingImports(documents: LangiumDocuments, model: Model) {\n const imports = resolveTransitiveImports(documents, model);\n return model.declarations.concat(...imports.map((imp) => imp.declarations));\n}\n\n/**\n * Gets the model used for auth context, by looking for a model with `@@auth` attribute or a model named `User`.\n * Returns `undefined` if no such model is found.\n */\nexport function getAuthDecl(decls: (DataModel | TypeDef)[]) {\n let authModel = decls.find((d) => hasAttribute(d, '@@auth'));\n if (!authModel) {\n authModel = decls.find((d) => d.name === 'User');\n }\n return authModel;\n}\n\n// TODO: move to policy plugin\nexport function isBeforeInvocation(node: AstNode) {\n return isInvocationExpr(node) && node.function.ref?.name === 'before';\n}\n\n/**\n * Determines if the given AST node is a collection predicate.\n */\nexport function isCollectionPredicate(node: AstNode): node is BinaryExpr {\n return isBinaryExpr(node) && ['?', '!', '^'].includes(node.operator);\n}\n\n/**\n * Gets all data models and type defs from the given documents registry.\n */\nexport function getAllLoadedDataModelsAndTypeDefs(langiumDocuments: LangiumDocuments) {\n return langiumDocuments.all\n .map((doc) => doc.parseResult.value as Model)\n .flatMap((model) => model.declarations.filter((d): d is DataModel | TypeDef => isDataModel(d) || isTypeDef(d)))\n .toArray();\n}\n\n/**\n * Gets all data models from the given documents registry and the transitive imports of the given model.\n */\nexport function getAllDataModelsIncludingImports(documents: LangiumDocuments, model: Model) {\n return getAllDeclarationsIncludingImports(documents, model).filter(isDataModel);\n}\n\n/**\n * Gets all data models and type defs from the given documents registry and the transitive imports\n * of the given model. If `fromModel` is not provided, returns all loaded data models and type defs.\n */\nexport function getAllLoadedAndReachableDataModelsAndTypeDefs(\n langiumDocuments: LangiumDocuments,\n fromModel?: DataModel,\n) {\n // get all data models from loaded documents\n const allDataModels = getAllLoadedDataModelsAndTypeDefs(langiumDocuments);\n\n if (fromModel) {\n // merge data models transitively reached from the current model\n const model = AstUtils.getContainerOfType(fromModel, isModel);\n if (model) {\n const transitiveDataModels = getAllDataModelsIncludingImports(langiumDocuments, model);\n transitiveDataModels.forEach((dm) => {\n if (!allDataModels.includes(dm)) {\n allDataModels.push(dm);\n }\n });\n }\n }\n\n return allDataModels;\n}\n\n/**\n * Gets the containing data model of the given AST node, if any.\n * Returns `undefined` if the node is not contained in a data model.\n */\nexport function getContainingDataModel(node: AstNode): DataModel | undefined {\n let curr: AstNode | undefined = node.$container;\n while (curr) {\n if (isDataModel(curr)) {\n return curr;\n }\n curr = curr.$container;\n }\n return undefined;\n}\n\n/**\n * Determines if the given AST node can contain members.\n */\nexport function isMemberContainer(node: unknown): node is DataModel | TypeDef {\n return isDataModel(node) || isTypeDef(node);\n}\n\n/**\n * Gets all fields of a data model or type def, including inherited fields from base models and mixins.\n */\nexport function getAllFields(\n decl: DataModel | TypeDef,\n includeIgnored = false,\n seen: Set<DataModel | TypeDef> = new Set(),\n): DataField[] {\n if (seen.has(decl)) {\n return [];\n }\n seen.add(decl);\n\n const fields: DataField[] = [];\n for (const mixin of decl.mixins) {\n if (mixin.ref) {\n fields.push(...getAllFields(mixin.ref, includeIgnored, seen));\n }\n }\n\n if (isDataModel(decl) && decl.baseModel) {\n if (decl.baseModel.ref) {\n fields.push(...getAllFields(decl.baseModel.ref, includeIgnored, seen));\n }\n }\n\n fields.push(...decl.fields.filter((f) => includeIgnored || !hasAttribute(f, '@ignore')));\n return fields;\n}\n\n/**\n * Gets all attributes of a data model or type def, including inherited attributes\n * from base models and mixins.\n */\nexport function getAllAttributes(\n decl: DataModel | TypeDef,\n seen: Set<DataModel | TypeDef> = new Set(),\n): DataModelAttribute[] {\n if (seen.has(decl)) {\n return [];\n }\n seen.add(decl);\n\n const attributes: DataModelAttribute[] = [];\n for (const mixin of decl.mixins) {\n if (mixin.ref) {\n attributes.push(...getAllAttributes(mixin.ref, seen));\n }\n }\n\n if (isDataModel(decl) && decl.baseModel) {\n if (decl.baseModel.ref) {\n const attrs = getAllAttributes(decl.baseModel.ref, seen).filter((attr) => !isNonInheritableAttribute(attr));\n attributes.push(...attrs);\n }\n }\n\n attributes.push(...decl.attributes);\n return attributes;\n}\n\nfunction isNonInheritableAttribute(attr: DataModelAttribute) {\n const attrName = attr.decl.ref?.name ?? attr.decl.$refText;\n return ['@@map', '@@unique', '@@index'].includes(attrName);\n}\n\n/**\n * Retrieve the document in which the given AST node is contained. A reference to the document is\n * usually held by the root node of the AST.\n *\n * @throws an error if the node is not contained in a document.\n */\nexport function getDocument<T extends AstNode = AstNode>(node: AstNode): LangiumDocument<T> {\n const rootNode = findRootNode(node);\n const result = rootNode.$document;\n if (!result) {\n throw new Error('AST node has no document.');\n }\n return result as LangiumDocument<T>;\n}\n\n/**\n * Gets the list of plugin documents from the given model.\n */\nexport function getPluginDocuments(model: Model, schemaPath: string): string[] {\n // traverse plugins and collect \"plugin.zmodel\" documents\n const result: string[] = [];\n for (const decl of model.declarations.filter(isPlugin)) {\n const providerField = decl.fields.find((f) => f.name === 'provider');\n if (!providerField) {\n continue;\n }\n\n const provider = getLiteral<string>(providerField.value);\n if (!provider) {\n continue;\n }\n\n let pluginModelFile: string | undefined;\n\n // first try to treat provider as a path\n let providerPath = path.resolve(path.dirname(schemaPath), provider);\n if (fs.existsSync(providerPath)) {\n if (fs.statSync(providerPath).isDirectory()) {\n providerPath = path.join(providerPath, 'index.js');\n }\n\n // try plugin.zmodel next to the provider file\n pluginModelFile = path.resolve(path.dirname(providerPath), PLUGIN_MODULE_NAME);\n if (!fs.existsSync(pluginModelFile)) {\n // try to find upwards\n pluginModelFile = findUp([PLUGIN_MODULE_NAME], path.dirname(providerPath));\n }\n }\n\n if (!pluginModelFile) {\n if (typeof import.meta.resolve === 'function') {\n try {\n // try loading as a ESM module\n const resolvedUrl = import.meta.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);\n pluginModelFile = fileURLToPath(resolvedUrl);\n } catch {\n // noop\n }\n }\n }\n\n if (!pluginModelFile) {\n // try loading as a CJS module\n try {\n const require = createRequire(pathToFileURL(schemaPath));\n pluginModelFile = require.resolve(`${provider}/${PLUGIN_MODULE_NAME}`);\n } catch {\n // noop\n }\n }\n\n if (pluginModelFile && fs.existsSync(pluginModelFile)) {\n result.push(pluginModelFile);\n }\n }\n return result;\n}\n\ntype FindUpResult<Multiple extends boolean> = Multiple extends true ? string[] | undefined : string | undefined;\n\nfunction findUp<Multiple extends boolean = false>(\n names: string[],\n cwd: string = process.cwd(),\n multiple: Multiple = false as Multiple,\n result: string[] = [],\n): FindUpResult<Multiple> {\n if (!names.some((name) => !!name)) {\n return undefined;\n }\n const target = names.find((name) => fs.existsSync(path.join(cwd, name)));\n if (multiple === false && target) {\n return path.join(cwd, target) as FindUpResult<Multiple>;\n }\n if (target) {\n result.push(path.join(cwd, target));\n }\n const up = path.resolve(cwd, '..');\n if (up === cwd) {\n return (multiple && result.length > 0 ? result : undefined) as FindUpResult<Multiple>;\n }\n return findUp(names, up, multiple, result);\n}\n\n/**\n * Returns the root node of the given AST node by following the `$container` references.\n */\nexport function findRootNode(node: AstNode): AstNode {\n while (node.$container) {\n node = node.$container;\n }\n return node;\n}\n"],"mappings":"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"}