@baseplate-dev/project-builder-lib 0.6.3 → 0.6.5
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.
- package/CHANGELOG.md +54 -0
- package/dist/compiler/admin-crud-action-compiler.js +1 -1
- package/dist/compiler/admin-crud-action-compiler.js.map +1 -1
- package/dist/compiler/admin-crud-column-compiler-spec.js +1 -1
- package/dist/compiler/admin-crud-column-compiler-spec.js.map +1 -1
- package/dist/compiler/admin-crud-input-spec.js +1 -1
- package/dist/compiler/admin-crud-input-spec.js.map +1 -1
- package/dist/compiler/app-compiler-spec.js +1 -1
- package/dist/compiler/app-compiler-spec.js.map +1 -1
- package/dist/compiler/index.d.ts +1 -0
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/model-transformer-compiler-spec.js +1 -1
- package/dist/compiler/model-transformer-compiler-spec.js.map +1 -1
- package/dist/compiler/root-compiler-spec.d.ts +25 -0
- package/dist/compiler/root-compiler-spec.d.ts.map +1 -0
- package/dist/compiler/root-compiler-spec.js +23 -0
- package/dist/compiler/root-compiler-spec.js.map +1 -0
- package/dist/constants/theme-colors.d.ts +0 -48
- package/dist/constants/theme-colors.d.ts.map +1 -1
- package/dist/constants/theme-colors.js +0 -32
- package/dist/constants/theme-colors.js.map +1 -1
- package/dist/definition/feature/feature-utils.d.ts +9 -3
- package/dist/definition/feature/feature-utils.d.ts.map +1 -1
- package/dist/definition/feature/feature-utils.js +30 -2
- package/dist/definition/feature/feature-utils.js.map +1 -1
- package/dist/definition/plugins/plugin-utils.d.ts +15 -0
- package/dist/definition/plugins/plugin-utils.d.ts.map +1 -1
- package/dist/definition/plugins/plugin-utils.js +50 -1
- package/dist/definition/plugins/plugin-utils.js.map +1 -1
- package/dist/definition/project-definition-container.d.ts.map +1 -1
- package/dist/definition/project-definition-container.js +3 -1
- package/dist/definition/project-definition-container.js.map +1 -1
- package/dist/{schema/models → expression-parsers}/authorizer/authorizer-expression-acorn-parser.d.ts +2 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-acorn-parser.d.ts.map +1 -0
- package/dist/{schema/models → expression-parsers}/authorizer/authorizer-expression-acorn-parser.js +107 -52
- package/dist/expression-parsers/authorizer/authorizer-expression-acorn-parser.js.map +1 -0
- package/dist/{schema/models → expression-parsers}/authorizer/authorizer-expression-ast.d.ts +69 -1
- package/dist/expression-parsers/authorizer/authorizer-expression-ast.d.ts.map +1 -0
- package/dist/{schema/models → expression-parsers}/authorizer/authorizer-expression-ast.js +2 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-ast.js.map +1 -0
- package/dist/{schema/models → expression-parsers}/authorizer/authorizer-expression-parser.d.ts +13 -14
- package/dist/expression-parsers/authorizer/authorizer-expression-parser.d.ts.map +1 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-parser.js +292 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-parser.js.map +1 -0
- package/dist/{schema/models → expression-parsers}/authorizer/authorizer-expression-validator.d.ts +37 -17
- package/dist/expression-parsers/authorizer/authorizer-expression-validator.d.ts.map +1 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-validator.js +379 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-validator.js.map +1 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-visitor.d.ts +54 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-visitor.d.ts.map +1 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-visitor.js +52 -0
- package/dist/expression-parsers/authorizer/authorizer-expression-visitor.js.map +1 -0
- package/dist/expression-parsers/authorizer/index.d.ts +6 -0
- package/dist/expression-parsers/authorizer/index.d.ts.map +1 -0
- package/dist/expression-parsers/authorizer/index.js +6 -0
- package/dist/expression-parsers/authorizer/index.js.map +1 -0
- package/dist/expression-parsers/register-core-module.d.ts +6 -0
- package/dist/expression-parsers/register-core-module.d.ts.map +1 -0
- package/dist/expression-parsers/register-core-module.js +29 -0
- package/dist/expression-parsers/register-core-module.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +6 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/migration-029-admin-role-and-auto-assigned.d.ts +25 -0
- package/dist/migrations/migration-029-admin-role-and-auto-assigned.d.ts.map +1 -0
- package/dist/migrations/migration-029-admin-role-and-auto-assigned.js +72 -0
- package/dist/migrations/migration-029-admin-role-and-auto-assigned.js.map +1 -0
- package/dist/migrations/migration-030-remove-theme-hover-colors.d.ts +17 -0
- package/dist/migrations/migration-030-remove-theme-hover-colors.d.ts.map +1 -0
- package/dist/migrations/migration-030-remove-theme-hover-colors.js +41 -0
- package/dist/migrations/migration-030-remove-theme-hover-colors.js.map +1 -0
- package/dist/migrations/migration-031-uuid-default-generation.d.ts +24 -0
- package/dist/migrations/migration-031-uuid-default-generation.d.ts.map +1 -0
- package/dist/migrations/migration-031-uuid-default-generation.js +40 -0
- package/dist/migrations/migration-031-uuid-default-generation.js.map +1 -0
- package/dist/migrations/transform-json-path.d.ts.map +1 -1
- package/dist/migrations/transform-json-path.js +2 -3
- package/dist/migrations/transform-json-path.js.map +1 -1
- package/dist/parser/collect-definition-issues.d.ts.map +1 -1
- package/dist/parser/collect-definition-issues.js +10 -2
- package/dist/parser/collect-definition-issues.js.map +1 -1
- package/dist/parser/collect-expression-issues.d.ts +17 -9
- package/dist/parser/collect-expression-issues.d.ts.map +1 -1
- package/dist/parser/collect-expression-issues.js +21 -15
- package/dist/parser/collect-expression-issues.js.map +1 -1
- package/dist/parser/definition-issue-checkers/plugin-dependency-checker.d.ts +11 -0
- package/dist/parser/definition-issue-checkers/plugin-dependency-checker.d.ts.map +1 -0
- package/dist/parser/definition-issue-checkers/plugin-dependency-checker.js +41 -0
- package/dist/parser/definition-issue-checkers/plugin-dependency-checker.js.map +1 -0
- package/dist/parser/definition-issue-checkers/plugin-implementation-checker.d.ts +16 -0
- package/dist/parser/definition-issue-checkers/plugin-implementation-checker.d.ts.map +1 -0
- package/dist/parser/definition-issue-checkers/plugin-implementation-checker.js +69 -0
- package/dist/parser/definition-issue-checkers/plugin-implementation-checker.js.map +1 -0
- package/dist/parser/definition-issue-utils.d.ts +28 -1
- package/dist/parser/definition-issue-utils.d.ts.map +1 -1
- package/dist/parser/definition-issue-utils.js +59 -0
- package/dist/parser/definition-issue-utils.js.map +1 -1
- package/dist/parser/find-orphaned-union-items.d.ts +30 -0
- package/dist/parser/find-orphaned-union-items.d.ts.map +1 -0
- package/dist/parser/find-orphaned-union-items.js +47 -0
- package/dist/parser/find-orphaned-union-items.js.map +1 -0
- package/dist/parser/index.d.ts +3 -1
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +3 -1
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +3 -0
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/transform-data-with-schema.js +1 -1
- package/dist/parser/transform-data-with-schema.js.map +1 -1
- package/dist/plugins/imports/index.d.ts +1 -0
- package/dist/plugins/imports/index.d.ts.map +1 -1
- package/dist/plugins/imports/index.js +1 -0
- package/dist/plugins/imports/index.js.map +1 -1
- package/dist/plugins/imports/validate-plugin-dependencies.d.ts +42 -0
- package/dist/plugins/imports/validate-plugin-dependencies.d.ts.map +1 -0
- package/dist/plugins/imports/validate-plugin-dependencies.js +80 -0
- package/dist/plugins/imports/validate-plugin-dependencies.js.map +1 -0
- package/dist/plugins/metadata/types.d.ts +13 -0
- package/dist/plugins/metadata/types.d.ts.map +1 -1
- package/dist/plugins/metadata/types.js +15 -0
- package/dist/plugins/metadata/types.js.map +1 -1
- package/dist/plugins/spec/auth-config-spec.d.ts +1 -0
- package/dist/plugins/spec/auth-config-spec.d.ts.map +1 -1
- package/dist/plugins/spec/auth-config-spec.js.map +1 -1
- package/dist/references/definition-ref-builder.d.ts +2 -0
- package/dist/references/definition-ref-builder.d.ts.map +1 -1
- package/dist/references/definition-ref-registry.d.ts +2 -0
- package/dist/references/definition-ref-registry.d.ts.map +1 -1
- package/dist/references/definition-ref-registry.js.map +1 -1
- package/dist/references/expression-parser-ref.d.ts +51 -0
- package/dist/references/expression-parser-ref.d.ts.map +1 -0
- package/dist/references/expression-parser-ref.js +14 -0
- package/dist/references/expression-parser-ref.js.map +1 -0
- package/dist/references/expression-parser-spec.d.ts +29 -0
- package/dist/references/expression-parser-spec.d.ts.map +1 -0
- package/dist/references/expression-parser-spec.js +29 -0
- package/dist/references/expression-parser-spec.js.map +1 -0
- package/dist/references/expression-types.d.ts +20 -22
- package/dist/references/expression-types.d.ts.map +1 -1
- package/dist/references/expression-types.js +1 -2
- package/dist/references/expression-types.js.map +1 -1
- package/dist/references/extend-parser-context-with-refs.d.ts +7 -2
- package/dist/references/extend-parser-context-with-refs.d.ts.map +1 -1
- package/dist/references/extend-parser-context-with-refs.js +42 -12
- package/dist/references/extend-parser-context-with-refs.js.map +1 -1
- package/dist/references/extract-definition-refs.js +1 -1
- package/dist/references/extract-definition-refs.js.map +1 -1
- package/dist/references/fix-definition-refs.d.ts +22 -0
- package/dist/references/fix-definition-refs.d.ts.map +1 -0
- package/dist/references/fix-definition-refs.js +29 -0
- package/dist/references/fix-definition-refs.js.map +1 -0
- package/dist/references/fix-expression-renames.d.ts +20 -0
- package/dist/references/fix-expression-renames.d.ts.map +1 -0
- package/dist/references/fix-expression-renames.js +87 -0
- package/dist/references/fix-expression-renames.js.map +1 -0
- package/dist/references/index.d.ts +4 -0
- package/dist/references/index.d.ts.map +1 -1
- package/dist/references/index.js +4 -0
- package/dist/references/index.js.map +1 -1
- package/dist/references/parse-schema-with-references.d.ts +2 -1
- package/dist/references/parse-schema-with-references.d.ts.map +1 -1
- package/dist/references/parse-schema-with-references.js.map +1 -1
- package/dist/schema/apps/web/admin/sections/crud.d.ts.map +1 -1
- package/dist/schema/apps/web/admin/sections/crud.js +3 -2
- package/dist/schema/apps/web/admin/sections/crud.js.map +1 -1
- package/dist/schema/creator/definition-issue-checkers.d.ts +15 -0
- package/dist/schema/creator/definition-issue-checkers.d.ts.map +1 -1
- package/dist/schema/creator/definition-issue-checkers.js +33 -0
- package/dist/schema/creator/definition-issue-checkers.js.map +1 -1
- package/dist/schema/creator/schema-creator.js +1 -1
- package/dist/schema/creator/schema-creator.js.map +1 -1
- package/dist/schema/features/feature.js +1 -1
- package/dist/schema/features/feature.js.map +1 -1
- package/dist/schema/libraries/library.d.ts.map +1 -1
- package/dist/schema/libraries/library.js +1 -0
- package/dist/schema/libraries/library.js.map +1 -1
- package/dist/schema/models/authorizer/authorizer-expression-ref.d.ts +11 -0
- package/dist/schema/models/authorizer/authorizer-expression-ref.d.ts.map +1 -0
- package/dist/schema/models/authorizer/authorizer-expression-ref.js +10 -0
- package/dist/schema/models/authorizer/authorizer-expression-ref.js.map +1 -0
- package/dist/schema/models/authorizer/authorizer.js +2 -2
- package/dist/schema/models/authorizer/authorizer.js.map +1 -1
- package/dist/schema/models/authorizer/index.d.ts +1 -4
- package/dist/schema/models/authorizer/index.d.ts.map +1 -1
- package/dist/schema/models/authorizer/index.js +1 -4
- package/dist/schema/models/authorizer/index.js.map +1 -1
- package/dist/schema/models/enums.d.ts +12 -0
- package/dist/schema/models/enums.d.ts.map +1 -1
- package/dist/schema/models/enums.js +5 -2
- package/dist/schema/models/enums.js.map +1 -1
- package/dist/schema/models/graphql.js +3 -3
- package/dist/schema/models/graphql.js.map +1 -1
- package/dist/schema/models/models.d.ts +24 -36
- package/dist/schema/models/models.d.ts.map +1 -1
- package/dist/schema/models/models.js +7 -5
- package/dist/schema/models/models.js.map +1 -1
- package/dist/schema/plugins/definition.d.ts.map +1 -1
- package/dist/schema/plugins/definition.js +2 -0
- package/dist/schema/plugins/definition.js.map +1 -1
- package/dist/schema/project-definition.d.ts +14 -22
- package/dist/schema/project-definition.d.ts.map +1 -1
- package/dist/schema/project-definition.js +5 -1
- package/dist/schema/project-definition.js.map +1 -1
- package/dist/schema/settings/settings.d.ts +2 -10
- package/dist/schema/settings/settings.d.ts.map +1 -1
- package/dist/schema/settings/theme.d.ts +3 -15
- package/dist/schema/settings/theme.d.ts.map +1 -1
- package/dist/schema/utils/validation.d.ts.map +1 -1
- package/dist/schema/utils/validation.js +16 -3
- package/dist/schema/utils/validation.js.map +1 -1
- package/dist/specs/packages/library-type-spec.d.ts +4 -0
- package/dist/specs/packages/library-type-spec.d.ts.map +1 -1
- package/dist/specs/packages/library-type-spec.js +2 -2
- package/dist/specs/packages/library-type-spec.js.map +1 -1
- package/dist/testing/definition-helpers.test-helper.js +2 -2
- package/dist/testing/definition-helpers.test-helper.js.map +1 -1
- package/dist/testing/expression-stub-parser.test-helper.d.ts +2 -4
- package/dist/testing/expression-stub-parser.test-helper.d.ts.map +1 -1
- package/dist/testing/expression-stub-parser.test-helper.js +2 -10
- package/dist/testing/expression-stub-parser.test-helper.js.map +1 -1
- package/dist/testing/expression-warning-parser.test-helper.d.ts +2 -4
- package/dist/testing/expression-warning-parser.test-helper.d.ts.map +1 -1
- package/dist/testing/expression-warning-parser.test-helper.js +2 -8
- package/dist/testing/expression-warning-parser.test-helper.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/parser-context.test-helper.d.ts.map +1 -1
- package/dist/testing/parser-context.test-helper.js +2 -1
- package/dist/testing/parser-context.test-helper.js.map +1 -1
- package/dist/testing/plugin-store.test-helper.d.ts +11 -0
- package/dist/testing/plugin-store.test-helper.d.ts.map +1 -0
- package/dist/testing/plugin-store.test-helper.js +32 -0
- package/dist/testing/plugin-store.test-helper.js.map +1 -0
- package/dist/testing/project-definition-container.test-helper.d.ts.map +1 -1
- package/dist/testing/project-definition-container.test-helper.js +2 -1
- package/dist/testing/project-definition-container.test-helper.js.map +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/sort-entity-arrays.d.ts +15 -0
- package/dist/tools/sort-entity-arrays.d.ts.map +1 -0
- package/dist/tools/sort-entity-arrays.js +31 -0
- package/dist/tools/sort-entity-arrays.js.map +1 -0
- package/dist/utils/color-conversions.d.ts +12 -0
- package/dist/utils/color-conversions.d.ts.map +1 -1
- package/dist/utils/color-conversions.js +17 -1
- package/dist/utils/color-conversions.js.map +1 -1
- package/dist/utils/color-names.d.ts.map +1 -1
- package/dist/utils/color-names.js +6 -5
- package/dist/utils/color-names.js.map +1 -1
- package/dist/utils/definition-diff/definition-diff.js +2 -2
- package/dist/utils/definition-diff/definition-diff.js.map +1 -1
- package/dist/utils/theme.d.ts +1 -0
- package/dist/utils/theme.d.ts.map +1 -1
- package/dist/utils/theme.js +18 -10
- package/dist/utils/theme.js.map +1 -1
- package/dist/web/components/definition-diff-alert.js +2 -2
- package/dist/web/components/definition-diff-alert.js.map +1 -1
- package/dist/web/components/feature-combobox-field.d.ts.map +1 -1
- package/dist/web/components/feature-combobox-field.js +5 -3
- package/dist/web/components/feature-combobox-field.js.map +1 -1
- package/dist/web/specs/admin-crud-action-web-spec.js +1 -1
- package/dist/web/specs/admin-crud-action-web-spec.js.map +1 -1
- package/dist/web/specs/admin-crud-column-web-spec.js +1 -1
- package/dist/web/specs/admin-crud-column-web-spec.js.map +1 -1
- package/dist/web/specs/admin-crud-input-web-spec.js +1 -1
- package/dist/web/specs/admin-crud-input-web-spec.js.map +1 -1
- package/dist/web/specs/model-transformer-web-spec.d.ts +19 -2
- package/dist/web/specs/model-transformer-web-spec.d.ts.map +1 -1
- package/dist/web/specs/model-transformer-web-spec.js +1 -1
- package/dist/web/specs/model-transformer-web-spec.js.map +1 -1
- package/package.json +8 -8
- package/dist/schema/models/authorizer/authorizer-expression-acorn-parser.d.ts.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-acorn-parser.js.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-ast.d.ts.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-ast.js.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-parser.d.ts.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-parser.js +0 -145
- package/dist/schema/models/authorizer/authorizer-expression-parser.js.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-validator.d.ts.map +0 -1
- package/dist/schema/models/authorizer/authorizer-expression-validator.js +0 -284
- package/dist/schema/models/authorizer/authorizer-expression-validator.js.map +0 -1
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { RefExpressionParser } from '#src/references/expression-types.js';
|
|
3
|
-
import { parseAuthorizerExpression } from './authorizer-expression-acorn-parser.js';
|
|
4
|
-
import { AuthorizerExpressionParseError } from './authorizer-expression-ast.js';
|
|
5
|
-
import { buildRelationValidationInfo, validateAuthorizerExpression, } from './authorizer-expression-validator.js';
|
|
6
|
-
/**
|
|
7
|
-
* Expression parser for model authorizer role expressions.
|
|
8
|
-
*
|
|
9
|
-
* Parses expressions like:
|
|
10
|
-
* - `model.id === auth.userId` (ownership check)
|
|
11
|
-
* - `auth.hasRole('admin')` (global role check)
|
|
12
|
-
* - `model.id === auth.userId || auth.hasRole('admin')` (combined)
|
|
13
|
-
*
|
|
14
|
-
* Uses Acorn to parse JavaScript expressions and validates
|
|
15
|
-
* that only supported constructs are used.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* const schema = z.object({
|
|
20
|
-
* expression: ctx.withExpression(authorizerExpressionParser, { model: modelSlot }),
|
|
21
|
-
* });
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export class AuthorizerExpressionParser extends RefExpressionParser {
|
|
25
|
-
name = 'authorizer-expression';
|
|
26
|
-
/**
|
|
27
|
-
* Creates a Zod schema for validating expression strings.
|
|
28
|
-
* Requires a non-empty string value.
|
|
29
|
-
*/
|
|
30
|
-
createSchema() {
|
|
31
|
-
return z.string().min(1, 'Expression is required');
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Parse the expression string into an AST.
|
|
35
|
-
*
|
|
36
|
-
* @param value - The expression string
|
|
37
|
-
* @returns Success with parsed expression info, or failure with error message
|
|
38
|
-
*/
|
|
39
|
-
parse(value) {
|
|
40
|
-
try {
|
|
41
|
-
return { success: true, value: parseAuthorizerExpression(value) };
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
if (error instanceof AuthorizerExpressionParseError) {
|
|
45
|
-
return { success: false, error: error.message };
|
|
46
|
-
}
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Get validation warnings for the expression.
|
|
52
|
-
*
|
|
53
|
-
* Validates:
|
|
54
|
-
* - Syntax errors from parsing
|
|
55
|
-
* - Model field references exist
|
|
56
|
-
* - Auth field references are valid
|
|
57
|
-
* - Role names exist in project config (warning only)
|
|
58
|
-
*/
|
|
59
|
-
getWarnings(parseResult, context, resolvedSlots) {
|
|
60
|
-
// Get model context from resolved slots
|
|
61
|
-
const modelContext = this.getModelContext(context.definition, resolvedSlots);
|
|
62
|
-
if (!modelContext) {
|
|
63
|
-
// Can't validate without model context
|
|
64
|
-
return [];
|
|
65
|
-
}
|
|
66
|
-
// Validate the expression against model fields and roles
|
|
67
|
-
return validateAuthorizerExpression(parseResult.ast, modelContext, context.pluginStore, context.definition);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Get entity/field dependencies from the expression.
|
|
71
|
-
*
|
|
72
|
-
* Currently returns empty array as we don't yet track
|
|
73
|
-
* entity-level dependencies (just field names).
|
|
74
|
-
* Future: could track model field entity references for renames.
|
|
75
|
-
*/
|
|
76
|
-
getDependencies() {
|
|
77
|
-
// TODO: Track model field entities for rename support
|
|
78
|
-
return [];
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Update the expression when dependencies are renamed.
|
|
82
|
-
*
|
|
83
|
-
* Currently returns value unchanged as we don't yet
|
|
84
|
-
* support field renames in expressions.
|
|
85
|
-
*/
|
|
86
|
-
updateForRename(value) {
|
|
87
|
-
// TODO: Implement rename support using AST position info
|
|
88
|
-
return value;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Extract model context from the project definition using resolved slots.
|
|
92
|
-
*/
|
|
93
|
-
getModelContext(definition, resolvedSlots) {
|
|
94
|
-
const modelPath = resolvedSlots.model;
|
|
95
|
-
if (modelPath.length === 0) {
|
|
96
|
-
return undefined;
|
|
97
|
-
}
|
|
98
|
-
// Navigate to the model in the project definition
|
|
99
|
-
// The path is like ['models', 0] for models[0]
|
|
100
|
-
let current = definition;
|
|
101
|
-
for (const segment of modelPath) {
|
|
102
|
-
if (current === null || current === undefined) {
|
|
103
|
-
return undefined;
|
|
104
|
-
}
|
|
105
|
-
current = current[segment];
|
|
106
|
-
}
|
|
107
|
-
const model = current;
|
|
108
|
-
if (!model || typeof model.name !== 'string') {
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
// Model fields are nested under model.model.fields in the definition
|
|
112
|
-
const scalarFieldNames = new Set();
|
|
113
|
-
const fieldTypes = new Map();
|
|
114
|
-
for (const field of model.model?.fields ?? []) {
|
|
115
|
-
if (typeof field.name === 'string') {
|
|
116
|
-
scalarFieldNames.add(field.name);
|
|
117
|
-
if (typeof field.type === 'string') {
|
|
118
|
-
fieldTypes.set(field.name, field.type);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Build relation info for nested authorizer validation
|
|
123
|
-
const relations = (model.model?.relations ?? []).filter((r) => typeof r.name === 'string' && typeof r.modelRef === 'string');
|
|
124
|
-
const allModels = (definition.models ?? []).filter((m) => typeof m.name === 'string');
|
|
125
|
-
const relationInfo = buildRelationValidationInfo(relations.map((r) => ({
|
|
126
|
-
name: r.name,
|
|
127
|
-
modelRef: r.modelRef,
|
|
128
|
-
references: r.references ?? [],
|
|
129
|
-
})), allModels.map((m) => ({
|
|
130
|
-
name: m.name,
|
|
131
|
-
authorizer: m.authorizer,
|
|
132
|
-
})));
|
|
133
|
-
return {
|
|
134
|
-
modelName: model.name,
|
|
135
|
-
scalarFieldNames,
|
|
136
|
-
fieldTypes,
|
|
137
|
-
relationInfo,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Singleton instance of AuthorizerExpressionParser.
|
|
143
|
-
*/
|
|
144
|
-
export const authorizerExpressionParser = new AuthorizerExpressionParser();
|
|
145
|
-
//# sourceMappingURL=authorizer-expression-parser.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authorizer-expression-parser.js","sourceRoot":"","sources":["../../../../src/schema/models/authorizer/authorizer-expression-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAM1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,sCAAsC,CAAC;AAqB9C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,0BAA2B,SAAQ,mBAI/C;IACU,IAAI,GAAG,uBAAuB,CAAC;IAExC;;;OAGG;IACH,YAAY;QACV,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QACpE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,8BAA8B,EAAE,CAAC;gBACpD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAClD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,WAAW,CACT,WAAqC,EACrC,OAAoC,EACpC,aAAyE;QAEzE,wCAAwC;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CACvC,OAAO,CAAC,UAAU,EAClB,aAAa,CACd,CAAC;QACF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,uCAAuC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,yDAAyD;QACzD,OAAO,4BAA4B,CACjC,WAAW,CAAC,GAAG,EACf,YAAY,EACZ,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,UAAU,CACnB,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,eAAe;QACb,sDAAsD;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,KAAa;QAC3B,yDAAyD;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACK,eAAe,CACrB,UAAmB,EACnB,aAAyE;QAMzE,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC;QACtC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,kDAAkD;QAClD,+CAA+C;QAC/C,IAAI,OAAO,GAAY,UAAU,CAAC;QAClC,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;YAChC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC9C,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,GAAI,OAA4C,CAAC,OAAO,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,KAAK,GAAG,OAAoC,CAAC;QAEnD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7C,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,qEAAqE;QACrE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC3C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;YAC9C,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACnC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;QACH,CAAC;QAED,uDAAuD;QACvD,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CACrD,CACE,CAAC,EAKD,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAClE,CAAC;QAEF,MAAM,SAAS,GAAG,CACf,UAAgD,CAAC,MAAM,IAAI,EAAE,CAC/D,CAAC,MAAM,CACN,CAAC,CAAC,EAA8C,EAAE,CAChD,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAC7B,CAAC;QAEF,MAAM,YAAY,GAAG,2BAA2B,CAC9C,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;SAC/B,CAAC,CAAC,EACH,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC,CACJ,CAAC;QAEF,OAAO;YACL,SAAS,EAAE,KAAK,CAAC,IAAI;YACrB,gBAAgB;YAChB,UAAU;YACV,YAAY;SACb,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,0BAA0B,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authorizer-expression-validator.d.ts","sourceRoot":"","sources":["../../../../src/schema/models/authorizer/authorizer-expression-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAKhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EACV,wBAAwB,EAGzB,MAAM,gCAAgC,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,iFAAiF;IACjF,cAAc,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,0BAA0B,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,iEAAiE;IACjE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,qFAAqF;IACrF,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CACpD;AAyCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,wBAAwB,EAC7B,YAAY,EAAE,sBAAsB,EACpC,WAAW,EAAE,eAAe,EAC5B,UAAU,EAAE,OAAO,GAClB,oBAAoB,EAAE,CA2OxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,SAAS;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC;CAChC,EAAE,EACH,SAAS,EAAE,SAAS;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,SAAS;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;CACtD,EAAE,GACF,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CA8BrC;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,WAAW,GACvB,sBAAsB,CAcxB"}
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validator for authorizer expressions.
|
|
3
|
-
*
|
|
4
|
-
* Validates that:
|
|
5
|
-
* - Model field references exist on the parent model
|
|
6
|
-
* - Auth field references are valid AuthContext properties
|
|
7
|
-
* - Role names exist in project config (warning only)
|
|
8
|
-
*/
|
|
9
|
-
import { authConfigSpec } from '#src/plugins/spec/auth-config-spec.js';
|
|
10
|
-
/**
|
|
11
|
-
* Valid auth context field names that can be accessed.
|
|
12
|
-
*/
|
|
13
|
-
const VALID_AUTH_FIELDS = new Set(['userId']);
|
|
14
|
-
/**
|
|
15
|
-
* Get role info from the project definition using the auth config spec.
|
|
16
|
-
*
|
|
17
|
-
* @param pluginStore - The plugin spec store
|
|
18
|
-
* @param definition - The raw project definition data
|
|
19
|
-
* @returns Role information including built-in status
|
|
20
|
-
*/
|
|
21
|
-
function getAuthRoleInfo(pluginStore, definition) {
|
|
22
|
-
const authConfig = pluginStore.use(authConfigSpec);
|
|
23
|
-
const roles = authConfig.getAuthConfig(definition)?.roles;
|
|
24
|
-
return {
|
|
25
|
-
allRoleNames: new Set(roles?.map((role) => role.name)),
|
|
26
|
-
builtInRoleNames: new Set(roles?.filter((role) => role.builtIn).map((role) => role.name)),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Validate an authorizer expression AST against model and project context.
|
|
31
|
-
*
|
|
32
|
-
* @param ast - The parsed expression AST
|
|
33
|
-
* @param modelContext - Information about the parent model
|
|
34
|
-
* @param pluginStore - The plugin spec store for accessing auth config
|
|
35
|
-
* @param definition - The raw project definition data
|
|
36
|
-
* @returns Array of warnings (errors are thrown, warnings are returned)
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* const warnings = validateAuthorizerExpression(
|
|
41
|
-
* ast,
|
|
42
|
-
* { modelName: 'User', scalarFieldNames: new Set(['id', 'email']) },
|
|
43
|
-
* pluginStore,
|
|
44
|
-
* definition,
|
|
45
|
-
* );
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
export function validateAuthorizerExpression(ast, modelContext, pluginStore, definition) {
|
|
49
|
-
const warnings = [];
|
|
50
|
-
const { allRoleNames, builtInRoleNames } = getAuthRoleInfo(pluginStore, definition);
|
|
51
|
-
const nonBuiltInRoleNames = [...allRoleNames].filter((name) => !builtInRoleNames.has(name));
|
|
52
|
-
function warnIfBuiltInRole(role, start, end) {
|
|
53
|
-
if (builtInRoleNames.has(role)) {
|
|
54
|
-
const message = role === 'user'
|
|
55
|
-
? `Role 'user' is a built-in role. Use 'isAuthenticated' instead to check if the user is authenticated.`
|
|
56
|
-
: `Role '${role}' is a built-in role and should not be used in authorizer expressions. Use non-built-in roles: ${nonBuiltInRoleNames.join(', ')}.`;
|
|
57
|
-
warnings.push({ message, start, end });
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function walk(node) {
|
|
61
|
-
switch (node.type) {
|
|
62
|
-
case 'fieldComparison': {
|
|
63
|
-
if (node.left.type === 'fieldRef') {
|
|
64
|
-
validateFieldRef(node.left);
|
|
65
|
-
}
|
|
66
|
-
if (node.right.type === 'fieldRef') {
|
|
67
|
-
validateFieldRef(node.right);
|
|
68
|
-
}
|
|
69
|
-
// Type-check: warn if a model field is compared to an incompatible literal
|
|
70
|
-
const fieldRef = node.left.type === 'fieldRef' ? node.left : node.right;
|
|
71
|
-
const literalNode = node.left.type === 'literalValue'
|
|
72
|
-
? node.left
|
|
73
|
-
: node.right.type === 'literalValue'
|
|
74
|
-
? node.right
|
|
75
|
-
: null;
|
|
76
|
-
if (fieldRef.type === 'fieldRef' &&
|
|
77
|
-
fieldRef.source === 'model' &&
|
|
78
|
-
literalNode !== null) {
|
|
79
|
-
validateLiteralTypeCompatibility(fieldRef, literalNode);
|
|
80
|
-
}
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
case 'hasRole': {
|
|
84
|
-
// Warn if role doesn't exist (but allow - plugins may define roles)
|
|
85
|
-
if (allRoleNames.has(node.role)) {
|
|
86
|
-
warnIfBuiltInRole(node.role, node.roleStart, node.roleEnd);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
warnings.push({
|
|
90
|
-
message: `Role '${node.role}' is not defined in the project configuration. Available roles: ${[...allRoleNames].join(', ')}.`,
|
|
91
|
-
start: node.roleStart,
|
|
92
|
-
end: node.roleEnd,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
case 'hasSomeRole': {
|
|
98
|
-
for (let i = 0; i < node.roles.length; i++) {
|
|
99
|
-
const role = node.roles[i];
|
|
100
|
-
const start = node.rolesStart[i];
|
|
101
|
-
const end = node.rolesEnd[i];
|
|
102
|
-
if (allRoleNames.has(role)) {
|
|
103
|
-
warnIfBuiltInRole(role, start, end);
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
warnings.push({
|
|
107
|
-
message: `Role '${role}' is not defined in the project configuration. Available roles: ${[...allRoleNames].join(', ')}.`,
|
|
108
|
-
start,
|
|
109
|
-
end,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
case 'nestedHasRole': {
|
|
116
|
-
validateNestedRelation(node.relationName, node.relationStart, node.relationEnd, [node.role], [node.roleStart], [node.roleEnd]);
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
case 'nestedHasSomeRole': {
|
|
120
|
-
validateNestedRelation(node.relationName, node.relationStart, node.relationEnd, node.roles, node.rolesStart, node.rolesEnd);
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
case 'isAuthenticated': {
|
|
124
|
-
// No validation needed
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
case 'binaryLogical': {
|
|
128
|
-
walk(node.left);
|
|
129
|
-
walk(node.right);
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function validateNestedRelation(relationName, relationStart, relationEnd, roles, rolesStart, rolesEnd) {
|
|
135
|
-
const { relationInfo } = modelContext;
|
|
136
|
-
if (!relationInfo) {
|
|
137
|
-
// Can't validate without relation info
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const relation = relationInfo.get(relationName);
|
|
141
|
-
if (!relation) {
|
|
142
|
-
const availableRelations = [...relationInfo.keys()].join(', ');
|
|
143
|
-
warnings.push({
|
|
144
|
-
message: `Relation '${relationName}' does not exist on model '${modelContext.modelName}'.${availableRelations ? ` Available relations: ${availableRelations}.` : ''}`,
|
|
145
|
-
start: relationStart,
|
|
146
|
-
end: relationEnd,
|
|
147
|
-
});
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
if (relation.referenceCount !== 1) {
|
|
151
|
-
warnings.push({
|
|
152
|
-
message: `Relation '${relationName}' has ${relation.referenceCount} foreign key references. Nested authorizer checks only support single-key relations.`,
|
|
153
|
-
start: relationStart,
|
|
154
|
-
end: relationEnd,
|
|
155
|
-
});
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
// Validate each role exists on the foreign model's authorizer
|
|
159
|
-
for (const [i, role] of roles.entries()) {
|
|
160
|
-
if (!relation.foreignAuthorizerRoleNames.has(role)) {
|
|
161
|
-
const availableRoles = [...relation.foreignAuthorizerRoleNames].join(', ');
|
|
162
|
-
warnings.push({
|
|
163
|
-
message: `Role '${role}' is not defined on model '${relation.foreignModelName}' authorizer.${availableRoles ? ` Available roles: ${availableRoles}.` : ''}`,
|
|
164
|
-
start: rolesStart[i],
|
|
165
|
-
end: rolesEnd[i],
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
function validateLiteralTypeCompatibility(fieldRefNode, literalNode) {
|
|
171
|
-
const { fieldTypes } = modelContext;
|
|
172
|
-
const fieldType = fieldTypes.get(fieldRefNode.field);
|
|
173
|
-
if (!fieldType)
|
|
174
|
-
return;
|
|
175
|
-
const literalJsType = typeof literalNode.value;
|
|
176
|
-
// Determine which JS types are compatible with each field type
|
|
177
|
-
const isCompatible = (() => {
|
|
178
|
-
switch (fieldType) {
|
|
179
|
-
case 'boolean': {
|
|
180
|
-
return literalJsType === 'boolean';
|
|
181
|
-
}
|
|
182
|
-
case 'int': {
|
|
183
|
-
return (typeof literalNode.value === 'number' &&
|
|
184
|
-
Number.isInteger(literalNode.value));
|
|
185
|
-
}
|
|
186
|
-
case 'float':
|
|
187
|
-
case 'decimal': {
|
|
188
|
-
return literalJsType === 'number';
|
|
189
|
-
}
|
|
190
|
-
case 'string':
|
|
191
|
-
case 'uuid':
|
|
192
|
-
case 'enum': {
|
|
193
|
-
return literalJsType === 'string';
|
|
194
|
-
}
|
|
195
|
-
default: {
|
|
196
|
-
// Unknown or unsupported field type — no warning
|
|
197
|
-
return true;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
})();
|
|
201
|
-
if (!isCompatible) {
|
|
202
|
-
warnings.push({
|
|
203
|
-
message: `Literal value type '${literalJsType}' is not compatible with field '${fieldRefNode.field}' of type '${fieldType}'.`,
|
|
204
|
-
start: literalNode.start,
|
|
205
|
-
end: literalNode.end,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
function validateFieldRef(node) {
|
|
210
|
-
if (node.source === 'model') {
|
|
211
|
-
// Check if field exists on model
|
|
212
|
-
if (!modelContext.scalarFieldNames.has(node.field)) {
|
|
213
|
-
warnings.push({
|
|
214
|
-
message: `Field '${node.field}' does not exist on model '${modelContext.modelName}'.`,
|
|
215
|
-
start: node.start,
|
|
216
|
-
end: node.end,
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
else if (!VALID_AUTH_FIELDS.has(node.field)) {
|
|
221
|
-
// node.source === 'auth' is implied since source is 'model' | 'auth'
|
|
222
|
-
warnings.push({
|
|
223
|
-
message: `Invalid auth property '${node.field}'. Valid properties are: ${[...VALID_AUTH_FIELDS].join(', ')}.`,
|
|
224
|
-
start: node.start,
|
|
225
|
-
end: node.end,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
walk(ast);
|
|
230
|
-
return warnings;
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Build relation validation info from model relations and the full list of models.
|
|
234
|
-
*
|
|
235
|
-
* Uses structural typing so both raw JSON shapes and typed `ModelConfig` objects
|
|
236
|
-
* can be passed directly.
|
|
237
|
-
*
|
|
238
|
-
* @param modelRelations - The relations on the current model
|
|
239
|
-
* @param allModels - All models in the project (for foreign model lookup)
|
|
240
|
-
* @returns Map of relation name → validation info
|
|
241
|
-
*/
|
|
242
|
-
export function buildRelationValidationInfo(modelRelations, allModels) {
|
|
243
|
-
const relationInfo = new Map();
|
|
244
|
-
// Build lookups by both id and name for flexible matching
|
|
245
|
-
const modelsById = new Map(allModels
|
|
246
|
-
.filter((m) => m.id != null)
|
|
247
|
-
.map((m) => [m.id, m]));
|
|
248
|
-
const modelsByName = new Map(allModels.map((m) => [m.name, m]));
|
|
249
|
-
for (const relation of modelRelations) {
|
|
250
|
-
const foreignModel = modelsById.get(relation.modelRef) ?? modelsByName.get(relation.modelRef);
|
|
251
|
-
const foreignAuthorizerRoleNames = new Set();
|
|
252
|
-
if (foreignModel?.authorizer?.roles) {
|
|
253
|
-
for (const role of foreignModel.authorizer.roles) {
|
|
254
|
-
foreignAuthorizerRoleNames.add(role.name);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
relationInfo.set(relation.name, {
|
|
258
|
-
referenceCount: relation.references.length,
|
|
259
|
-
foreignModelName: foreignModel?.name ?? relation.modelRef,
|
|
260
|
-
foreignAuthorizerRoleNames,
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
return relationInfo;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Extract model validation context from a model configuration.
|
|
267
|
-
*
|
|
268
|
-
* @param modelConfig - The parsed model configuration
|
|
269
|
-
* @returns Model validation context for the validator
|
|
270
|
-
*/
|
|
271
|
-
export function createModelValidationContext(modelConfig) {
|
|
272
|
-
const scalarFieldNames = new Set();
|
|
273
|
-
const fieldTypes = new Map();
|
|
274
|
-
for (const field of modelConfig.model.fields) {
|
|
275
|
-
scalarFieldNames.add(field.name);
|
|
276
|
-
fieldTypes.set(field.name, field.type);
|
|
277
|
-
}
|
|
278
|
-
return {
|
|
279
|
-
modelName: modelConfig.name,
|
|
280
|
-
scalarFieldNames,
|
|
281
|
-
fieldTypes,
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
//# sourceMappingURL=authorizer-expression-validator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authorizer-expression-validator.js","sourceRoot":"","sources":["../../../../src/schema/models/authorizer/authorizer-expression-validator.ts"],"names":[],"mappings":"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"}
|