Skip to content

models

package.json validation models.

PackageAuthor

Bases: BaseModel

Package author model.

Source code in src/somesy/package_json/models.py
15
16
17
18
19
20
21
22
class PackageAuthor(BaseModel):
    """Package author model."""

    name: Annotated[Optional[str], Field(description="Author name")]
    email: Annotated[Optional[EmailStr], Field(description="Author email")] = None
    url: Annotated[
        Optional[HttpUrlStr], Field(description="Author website or orcid page")
    ] = None

PackageRepository

Bases: BaseModel

Package repository model.

Source code in src/somesy/package_json/models.py
25
26
27
28
29
class PackageRepository(BaseModel):
    """Package repository model."""

    type: Annotated[Optional[str], Field(description="Repository type")] = None
    url: Annotated[str, Field(description="Repository url")]

PackageLicense

Bases: BaseModel

Package license model.

Source code in src/somesy/package_json/models.py
32
33
34
35
36
class PackageLicense(BaseModel):
    """Package license model."""

    type: Annotated[Optional[str], Field(description="License type")] = None
    url: Annotated[str, Field(description="License url")]

PackageJsonConfig

Bases: BaseModel

Package.json config model.

Source code in src/somesy/package_json/models.py
 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
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
class PackageJsonConfig(BaseModel):
    """Package.json config model."""

    model_config = dict(populate_by_name=True)

    name: Annotated[str, Field(description="Package name")]
    version: Annotated[str, Field(description="Package version")]
    description: Annotated[Optional[str], Field(description="Package description")] = (
        None
    )
    author: Annotated[
        Optional[Union[str, PackageAuthor]], Field(description="Package author")
    ] = None
    maintainers: Annotated[
        Optional[List[Union[str, PackageAuthor]]],
        Field(description="Package maintainers"),
    ] = None
    contributors: Annotated[
        Optional[List[Union[str, PackageAuthor]]],
        Field(description="Package contributors"),
    ] = None
    license: Annotated[
        Optional[Union[str, PackageLicense]], Field(description="Package license")
    ] = None
    repository: Annotated[
        Optional[Union[PackageRepository, str]], Field(description="Package repository")
    ] = None
    homepage: Annotated[Optional[HttpUrlStr], Field(description="Package homepage")] = (
        None
    )
    keywords: Annotated[
        Optional[List[str]], Field(description="Keywords that describe the package")
    ] = None

    # convert package author to dict if it is a string
    @classmethod
    def convert_author(cls, author: str) -> PackageAuthor:
        """Convert author string to PackageAuthor model."""
        # parse author string to "name <email> (url)" format with regex
        author_match = re.match(NPM_PKG_AUTHOR, author)
        if not author_match:
            raise ValueError(f"Invalid author format: {author}")
        author_name = author_match[1]
        author_email = author_match[2]
        author_url = author_match[3]

        return PackageAuthor(name=author_name, email=author_email, url=author_url)

    @field_validator("name")
    @classmethod
    def validate_name(cls, v):
        """Validate package name."""
        if re.match(NPM_PKG_NAME, v) is None:
            raise ValueError("Invalid name")

        return v

    @field_validator("version")
    @classmethod
    def validate_version(cls, v):
        """Validate package version."""
        if re.match(NPM_PKG_VERSION, v) is None:
            raise ValueError("Invalid version")
        return v

    @field_validator("author")
    @classmethod
    def validate_author(cls, v):
        """Validate package author."""
        return cls.convert_author(v) if isinstance(v, str) else v

    @field_validator("maintainers", "contributors")
    @classmethod
    def validate_people(cls, v):
        """Validate package maintainers and contributors."""
        people = []
        for p in v:
            if isinstance(p, str):
                author = cls.convert_author(p)
                if author is not None:
                    people.append(cls.convert_author(p))
                else:
                    logger.warning(
                        f"Invalid email format for maintainer/contributor {p}, omitting."
                    )
            elif p.email is not None:
                people.append(p)
            else:
                logger.warning(
                    f"Invalid email format for maintainer/contributor {p}, omitting."
                )
        return people

convert_author classmethod

convert_author(author: str) -> PackageAuthor

Convert author string to PackageAuthor model.

Source code in src/somesy/package_json/models.py
79
80
81
82
83
84
85
86
87
88
89
90
@classmethod
def convert_author(cls, author: str) -> PackageAuthor:
    """Convert author string to PackageAuthor model."""
    # parse author string to "name <email> (url)" format with regex
    author_match = re.match(NPM_PKG_AUTHOR, author)
    if not author_match:
        raise ValueError(f"Invalid author format: {author}")
    author_name = author_match[1]
    author_email = author_match[2]
    author_url = author_match[3]

    return PackageAuthor(name=author_name, email=author_email, url=author_url)

validate_name classmethod

validate_name(v)

Validate package name.

Source code in src/somesy/package_json/models.py
92
93
94
95
96
97
98
99
@field_validator("name")
@classmethod
def validate_name(cls, v):
    """Validate package name."""
    if re.match(NPM_PKG_NAME, v) is None:
        raise ValueError("Invalid name")

    return v

validate_version classmethod

validate_version(v)

Validate package version.

Source code in src/somesy/package_json/models.py
101
102
103
104
105
106
107
@field_validator("version")
@classmethod
def validate_version(cls, v):
    """Validate package version."""
    if re.match(NPM_PKG_VERSION, v) is None:
        raise ValueError("Invalid version")
    return v

validate_author classmethod

validate_author(v)

Validate package author.

Source code in src/somesy/package_json/models.py
109
110
111
112
113
@field_validator("author")
@classmethod
def validate_author(cls, v):
    """Validate package author."""
    return cls.convert_author(v) if isinstance(v, str) else v

validate_people classmethod

validate_people(v)

Validate package maintainers and contributors.

Source code in src/somesy/package_json/models.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
@field_validator("maintainers", "contributors")
@classmethod
def validate_people(cls, v):
    """Validate package maintainers and contributors."""
    people = []
    for p in v:
        if isinstance(p, str):
            author = cls.convert_author(p)
            if author is not None:
                people.append(cls.convert_author(p))
            else:
                logger.warning(
                    f"Invalid email format for maintainer/contributor {p}, omitting."
                )
        elif p.email is not None:
            people.append(p)
        else:
            logger.warning(
                f"Invalid email format for maintainer/contributor {p}, omitting."
            )
    return people