Coverage for src / npm_mcp / models.py: 100%

129 statements  

« prev     ^ index     » next       coverage.py v7.13.2, created at 2026-02-21 06:26 +0400

1"""Data models for NPM entities.""" 

2 

3from typing import List, Literal, Optional 

4from pydantic import BaseModel, ConfigDict, Field, SecretStr 

5 

6 

7class ProxyHostLocation(BaseModel): 

8 path: str = Field("/", max_length=1024) 

9 forward_scheme: Literal["http", "https"] = "http" 

10 forward_host: str = Field(..., max_length=255) 

11 forward_port: int = Field(..., ge=1, le=65535) 

12 

13 

14class ProxyHost(BaseModel): 

15 model_config = ConfigDict(extra="ignore") 

16 

17 id: Optional[int] = None 

18 created_on: Optional[str] = None 

19 modified_on: Optional[str] = None 

20 owner_user_id: Optional[int] = None 

21 domain_names: List[str] = Field(..., max_length=100) 

22 forward_scheme: Literal["http", "https"] = "http" 

23 forward_host: str = Field(..., max_length=255) 

24 forward_port: int = Field(..., ge=1, le=65535) 

25 access_list_id: Optional[int] = None 

26 certificate_id: Optional[int] = None 

27 ssl_forced: bool = False 

28 caching_enabled: bool = False 

29 block_exploits: bool = True 

30 advanced_config: str = Field("", max_length=16384) 

31 meta: dict = Field(default_factory=dict) 

32 allow_websocket_upgrade: bool = False 

33 http2_support: bool = False 

34 hsts_enabled: bool = False 

35 hsts_subdomains: bool = False 

36 enabled: bool = True 

37 locations: List[ProxyHostLocation] = Field(default_factory=list) 

38 

39 

40class Certificate(BaseModel): 

41 model_config = ConfigDict(extra="ignore") 

42 

43 id: Optional[int] = None 

44 created_on: Optional[str] = None 

45 modified_on: Optional[str] = None 

46 provider: Literal["letsencrypt", "other"] = "letsencrypt" 

47 nice_name: str = Field(..., max_length=255) 

48 domain_names: List[str] = Field(..., max_length=100) 

49 expires_on: Optional[str] = None 

50 meta: dict = Field(default_factory=dict) 

51 

52 

53class AccessList(BaseModel): 

54 model_config = ConfigDict(extra="ignore") 

55 

56 id: Optional[int] = None 

57 created_on: Optional[str] = None 

58 modified_on: Optional[str] = None 

59 name: str = Field(..., max_length=255) 

60 satisfy_any: bool = False 

61 pass_auth: bool = True 

62 meta: dict = Field(default_factory=dict) 

63 items: List[dict] = Field(default_factory=list) 

64 

65 

66class RedirectionHost(BaseModel): 

67 model_config = ConfigDict(extra="ignore") 

68 

69 id: Optional[int] = None 

70 created_on: Optional[str] = None 

71 modified_on: Optional[str] = None 

72 owner_user_id: Optional[int] = None 

73 domain_names: List[str] = Field(..., max_length=100) 

74 forward_scheme: Literal["auto", "http", "https"] = "auto" 

75 forward_http_code: int = Field(302, ge=300, le=308) 

76 forward_domain_name: str = Field(..., max_length=255) 

77 preserve_path: bool = False 

78 certificate_id: Optional[int] = None 

79 ssl_forced: bool = False 

80 hsts_enabled: bool = False 

81 hsts_subdomains: bool = False 

82 http2_support: bool = False 

83 block_exploits: bool = True 

84 advanced_config: str = Field("", max_length=16384) 

85 meta: dict = Field(default_factory=dict) 

86 enabled: bool = True 

87 

88 

89class Stream(BaseModel): 

90 model_config = ConfigDict(extra="ignore") 

91 

92 id: Optional[int] = None 

93 created_on: Optional[str] = None 

94 modified_on: Optional[str] = None 

95 owner_user_id: Optional[int] = None 

96 incoming_port: int = Field(..., ge=1, le=65535) 

97 forwarding_host: str = Field(..., max_length=255) 

98 forwarding_port: int = Field(..., ge=1, le=65535) 

99 tcp_forwarding: bool = True 

100 udp_forwarding: bool = False 

101 certificate_id: Optional[int] = None 

102 meta: dict = Field(default_factory=dict) 

103 enabled: bool = True 

104 

105 

106class DeadHost(BaseModel): 

107 model_config = ConfigDict(extra="ignore") 

108 

109 id: Optional[int] = None 

110 created_on: Optional[str] = None 

111 modified_on: Optional[str] = None 

112 owner_user_id: Optional[int] = None 

113 domain_names: List[str] = Field(..., max_length=100) 

114 certificate_id: Optional[int] = None 

115 ssl_forced: bool = False 

116 hsts_enabled: bool = False 

117 hsts_subdomains: bool = False 

118 http2_support: bool = False 

119 advanced_config: str = Field("", max_length=16384) 

120 meta: dict = Field(default_factory=dict) 

121 enabled: bool = True 

122 

123 

124class User(BaseModel): 

125 model_config = ConfigDict(extra="ignore") 

126 

127 id: Optional[int] = None 

128 created_on: Optional[str] = None 

129 modified_on: Optional[str] = None 

130 name: str = Field(..., max_length=255) 

131 nickname: str = Field("", max_length=255) 

132 email: str = Field(..., max_length=255) 

133 avatar: str = "" 

134 roles: List[str] = Field(default_factory=list) 

135 is_disabled: bool = False 

136 

137 

138class Setting(BaseModel): 

139 model_config = ConfigDict(extra="ignore") 

140 

141 id: Optional[str] = None 

142 name: Optional[str] = None 

143 description: Optional[str] = None 

144 value: str = "" 

145 meta: dict = Field(default_factory=dict) 

146 

147 

148class AuditLogEntry(BaseModel): 

149 model_config = ConfigDict(extra="ignore") 

150 

151 id: Optional[int] = None 

152 created_on: Optional[str] = None 

153 modified_on: Optional[str] = None 

154 user_id: Optional[int] = None 

155 object_type: Optional[str] = None 

156 object_id: Optional[int] = None 

157 action: Optional[str] = None 

158 meta: dict = Field(default_factory=dict) 

159 

160 

161class NPMToken(BaseModel): 

162 token: str 

163 expires: str 

164 

165 

166class NPMConfig(BaseModel): 

167 url: str 

168 email: str 

169 password: SecretStr