manifest.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.resolveManifestJson = exports.isCustomResources = exports.hasCustomResources = exports.checkManifest = exports.resolvePluginFiles = exports.genManifestJson = exports.genManifestFile = exports.hash = void 0;
  7. const fs_extra_1 = require("fs-extra");
  8. const path_1 = require("path");
  9. const md5_file_1 = __importDefault(require("md5-file"));
  10. const fast_glob_1 = __importDefault(require("fast-glob"));
  11. const fileCaches = new Map();
  12. const VERSION = '1';
  13. /**
  14. * 计算文件 md5(有缓存)
  15. * @param file
  16. * @returns
  17. */
  18. async function hash(file) {
  19. const cache = fileCaches.get(file);
  20. const stat = (0, fs_extra_1.statSync)(file);
  21. if (cache && cache.mtimeMs === stat.mtimeMs) {
  22. return cache.md5;
  23. }
  24. return (0, md5_file_1.default)(file).then((value) => {
  25. fileCaches.set(file, { mtimeMs: stat.mtimeMs, md5: value });
  26. return value;
  27. });
  28. }
  29. exports.hash = hash;
  30. async function genManifestFile(platform, { files, pluginDir, env, cacheDir, pluginRelativeDir, is_uni_modules, }) {
  31. (0, fs_extra_1.outputFileSync)(resolveManifestFilename(platform, pluginRelativeDir, cacheDir), JSON.stringify(await genManifestJson(platform, {
  32. pluginDir,
  33. files,
  34. env,
  35. is_uni_modules,
  36. }), null, 2));
  37. return true;
  38. }
  39. exports.genManifestFile = genManifestFile;
  40. async function genManifestJson(platform, { pluginDir, files, env, is_uni_modules }) {
  41. if (!files) {
  42. files = await resolvePluginFiles(platform, pluginDir, is_uni_modules);
  43. }
  44. if (!files) {
  45. files = [];
  46. }
  47. return {
  48. version: VERSION,
  49. env,
  50. files: await genManifestFiles(pluginDir, files),
  51. };
  52. }
  53. exports.genManifestJson = genManifestJson;
  54. async function genManifestFiles(dir, files) {
  55. const manifestFiles = {};
  56. // 优先 uts 文件
  57. files = files.sort((a, b) => {
  58. const aUts = a.endsWith('.uts');
  59. const bUts = b.endsWith('.uts');
  60. if (aUts && bUts) {
  61. return a > b ? 1 : -1;
  62. }
  63. if (aUts) {
  64. return -1;
  65. }
  66. return 1;
  67. });
  68. const md5Arr = await Promise.all(files.map((file) => hash((0, path_1.join)(dir, file))));
  69. files.forEach((name, index) => {
  70. manifestFiles[name] = {
  71. md5: md5Arr[index],
  72. };
  73. });
  74. return manifestFiles;
  75. }
  76. async function resolvePluginCommonFiles(pluginDir, is_uni_modules) {
  77. const patterns = ['*'];
  78. if (is_uni_modules) {
  79. patterns.push('utssdk/*.uts');
  80. patterns.push('utssdk/common/**/*');
  81. }
  82. else {
  83. patterns.push('common/**/*');
  84. }
  85. return (0, fast_glob_1.default)(patterns, {
  86. ignore: ['changelog.md', 'readme.md'],
  87. cwd: pluginDir,
  88. });
  89. }
  90. async function resolvePluginFiles(platform, pluginDir, is_uni_modules) {
  91. return Promise.all([
  92. resolvePluginCommonFiles(pluginDir, is_uni_modules),
  93. resolvePluginPlatformFiles(platform, pluginDir, is_uni_modules),
  94. ]).then((files) => files.flat());
  95. }
  96. exports.resolvePluginFiles = resolvePluginFiles;
  97. async function resolvePluginPlatformFiles(platform, pluginDir, is_uni_modules) {
  98. return (0, fast_glob_1.default)((is_uni_modules ? 'utssdk/' : '') + platform + '/**/*', {
  99. cwd: pluginDir,
  100. });
  101. }
  102. async function checkManifest(manifest, { env, files, pluginDir, }) {
  103. if (manifest.version !== VERSION) {
  104. return false;
  105. }
  106. if (isEnvExpired(manifest.env, env)) {
  107. return false;
  108. }
  109. return checkFiles(manifest.files, files, pluginDir);
  110. }
  111. exports.checkManifest = checkManifest;
  112. /**
  113. * 判断 env 是否过期
  114. * @param value
  115. * @param other
  116. * @returns
  117. */
  118. function isEnvExpired(value, other) {
  119. const valueKeys = Object.keys(value);
  120. const otherKeys = Object.keys(other);
  121. if (valueKeys.length !== otherKeys.length) {
  122. return true;
  123. }
  124. if (valueKeys.find((name) => value[name] !== other[name])) {
  125. return true;
  126. }
  127. return false;
  128. }
  129. /**
  130. * 判断文件列表是否过期
  131. * @param files
  132. * @param filenames
  133. * @returns
  134. */
  135. async function checkFiles(files, filenames, pluginDir) {
  136. const oldFilenames = Object.keys(files);
  137. // 第一步:优先判断文件列表长度
  138. if (oldFilenames.length !== filenames.length) {
  139. return false;
  140. }
  141. // 第二步:判断文件列表
  142. if (oldFilenames.find((name) => !filenames.includes(name))) {
  143. return false;
  144. }
  145. // 第三步:判断文件 md5
  146. for (const name of oldFilenames) {
  147. const md5 = await hash((0, path_1.join)(pluginDir, name));
  148. if (files[name].md5 !== md5) {
  149. return name;
  150. }
  151. }
  152. return true;
  153. }
  154. function hasCustomResources(files, resources) {
  155. if (files.some((file) => isCustomResources(file, resources))) {
  156. return true;
  157. }
  158. }
  159. exports.hasCustomResources = hasCustomResources;
  160. function isCustomResources(file, resources) {
  161. return resources.some((res) => file.includes(res));
  162. }
  163. exports.isCustomResources = isCustomResources;
  164. function resolveManifestFilename(platform, pluginRelativeDir, cacheDir) {
  165. return (0, path_1.join)(cacheDir, platform, 'uts', pluginRelativeDir, 'manifest.json');
  166. }
  167. function resolveManifestJson(platform, pluginRelativeDir, cacheDir) {
  168. const file = resolveManifestFilename(platform, pluginRelativeDir, cacheDir);
  169. if ((0, fs_extra_1.existsSync)(file)) {
  170. try {
  171. return JSON.parse((0, fs_extra_1.readFileSync)(file, 'utf8'));
  172. }
  173. catch (e) { }
  174. }
  175. }
  176. exports.resolveManifestJson = resolveManifestJson;