Coverage for src/kwai/frontend/manifest.py: 97%

39 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2024-01-01 00:00 +0000

1"""Module that defines a class for handling the manifest file of Vite.""" 

2 

3import json 

4 

5from dataclasses import dataclass, field 

6from pathlib import Path 

7from typing import Self 

8 

9 

10@dataclass(frozen=True, kw_only=True, slots=True) 

11class Chunk: 

12 """An entry of a manifest file.""" 

13 

14 src: str | None = None 

15 name: str | None = None 

16 entry: bool = False 

17 dynamic_entry: bool = False 

18 file: str 

19 css: list[str] = field(default_factory=list) 

20 assets: list[str] = field(default_factory=list) 

21 imports: list[str] = field(default_factory=list) 

22 dynamic_imports: list[str] = field(default_factory=list) 

23 

24 

25class Manifest: 

26 """Class for handling a manifest file of Vite.""" 

27 

28 def __init__(self, entries: dict[str, Chunk]) -> None: 

29 """Initialize the Manifest class.""" 

30 self._entries = entries 

31 

32 @property 

33 def chunks(self): 

34 """Return the entries.""" 

35 return self._entries.copy() 

36 

37 def has_chunk(self, entry_name: str): 

38 """Check if the entry exists in the manifest file.""" 

39 return entry_name in self._entries 

40 

41 def get_chunk(self, entry_name: str) -> Chunk: 

42 """Return the entry with the given name.""" 

43 return self._entries[entry_name] 

44 

45 @classmethod 

46 def load_from_file(cls, file_path: Path) -> Self: 

47 """Load the manifest from a file.""" 

48 with open(file_path, "r") as manifest_file: 

49 return cls.load_from_string(manifest_file.read()) 

50 

51 @classmethod 

52 def load_from_string(cls, content: str) -> Self: 

53 """Load the manifest from a string.""" 

54 entries: dict[str, Chunk] = {} 

55 json_data = json.loads(content) 

56 for k, v in json_data.items(): 

57 if not isinstance(v, dict): 

58 continue 

59 entry = Chunk( 

60 src=v.get("src", None), 

61 name=v.get("name", None), 

62 entry=v.get("isEntry", False), 

63 dynamic_entry=v.get("isDynamicEntry", False), 

64 file=v.get("file"), 

65 css=v.get("css", []), 

66 assets=v.get("assets", []), 

67 imports=v.get("imports", []), 

68 dynamic_imports=v.get("dynamicImports", []), 

69 ) 

70 entries[k] = entry 

71 

72 return cls(entries=entries)