1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use crate::{
    ast::{self, WithName, WithSpan},
    DatamodelError, Diagnostics,
};

/// Is this a valid type name for the Prisma Client API?
pub fn is_reserved_type_name(name: &str) -> bool {
    RESERVED_NAMES.contains(&name)
}

pub(crate) fn validate_model_name(ast_model: &ast::Model, block_type: &'static str, diagnostics: &mut Diagnostics) {
    if !is_reserved_type_name(ast_model.name()) {
        return;
    }

    diagnostics.push_error(DatamodelError::new_model_validation_error(
        &format!(
            "The {block_type} name `{}` is invalid. It is a reserved name. Please change it. Read more at https://pris.ly/d/naming-models",
            ast_model.name()
        ),
        "model",
        ast_model.name(),
        ast_model.span(),
    ))
}

pub(crate) fn validate_enum_name(ast_enum: &ast::Enum, diagnostics: &mut Diagnostics) {
    if !is_reserved_type_name(&ast_enum.name.name) {
        return;
    }

    diagnostics.push_error(DatamodelError::new_enum_validation_error(
        &format!(
          "The enum name `{}` is invalid. It is a reserved name. Please change it. Read more at https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/data-model#naming-enums",
          ast_enum.name()
        ),
        ast_enum.name(),
        ast_enum.span(),
));
}

// The source of the following list is from prisma-client-js. Any edit should be done in both places.
// https://github.com/prisma/prisma/blob/master/src/packages/client/src/generation/generateClient.ts#L443
const RESERVED_NAMES: &[&str] = &[
    "PrismaClient",
    // JavaScript keywords
    "break",
    "case",
    "catch",
    "class",
    "const",
    "continue",
    "debugger",
    "default",
    "delete",
    "do",
    "else",
    "enum",
    "export",
    "extends",
    "false",
    "finally",
    "for",
    "function",
    "if",
    "implements",
    "import",
    "in",
    "instanceof",
    "interface",
    "let",
    "new",
    "null",
    "package",
    "private",
    "protected",
    "public",
    "return",
    "super",
    "switch",
    "this",
    "throw",
    "true",
    "try",
    "typeof",
    "var",
    "void",
    "while",
    "with",
    "yield",
];