提交 b1daddf4 编写于 作者: fxy060608's avatar fxy060608

wip(uts): compiler

上级 01c4c8cb
{"version":3,"sources":["uni_modules/test-uniplugin/utssdk/app-ios/index.uts"],"sourcesContent":["import { UIDevice } from 'UIKit'\nimport { CLLocationManager, CLAuthorizationStatus } from 'CoreLocation'\n\ntype GetBatteryInfoOptions = {\n name: string\n pwd: number\n success?: (res: UTSJSONObject) => void\n fail?: (res: UTSJSONObject) => void\n complete?: (res: UTSJSONObject) => void\n}\n\nexport default function getBatteryInfo(options: GetBatteryInfoOptions) {\n new UIAlertController(\n (title = title),\n (message = message),\n (preferredStyle = UIAlertController.Style.alert)\n )\n const res = {\n errMsg: 'getBatteryInfo:ok',\n level: UIDevice.current.batteryLevel * 100,\n isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,\n }\n if (options.success != null) {\n options.success!(res)\n }\n if (options.complete != null) {\n options.complete!(res)\n }\n}\n\nexport function test1(callback: () => void): string {\n console.log({ \"a\": \"b\" })\n console.log('test1')\n\n\n\n\n console.log('def ios')\n\n\n console.log('ndef android')\n\n\n\n\n\n console.log('def android || def ios')\n\n\n\n\n console.log(CLLocationManager, CLAuthorizationStatus)\n return 'test1'\n}\n\nclass Test1 { }\nexport class Test {\n constructor() {\n new Test1()\n }\n test(): string | null {\n return null\n }\n}\n\nexport async function testAsync() {\n return { a: 1 }\n}\n"],"names":[],"mappings":";AAAA;AACA;AAE6B;;MAAxB;IACH,WAAA,MAAM,MAAM,EAAA;IACZ,WAAA,KAAK,QAAM,EAAA;IACX,WAAA,SAAQ,aAA8B;IACtC,WAAA,MAAK,aAA8B;IACnC,WAAA,UAAS,aAA8B;AACzC;AAEe,KAAS,eAAe,EAAA,SAAS,qBAAqB,EAAE;IACjE,kBACD,OAAQ,OACR,SAAU,SACV,gBAAiB,kBAAkB,KAAK,CAAC,KAAK;IAEjD,IAAM,MAAM;QACV,CAAA,SAAQ;QACR,CAAA,QAAO,SAAS,OAAO,CAAC,YAAY,GAAG,GAAG;QAC1C,CAAA,aAAY,SAAS,OAAO,CAAC,YAAY,IAAI,SAAS,YAAY,CAAC,QAAQ;MAC5E;IACD,IAAI,QAAQ,OAAO,IAAI,GAAI;QACzB,QAAQ,OAAO,EAAE;;IAEnB,IAAI,QAAQ,QAAQ,IAAI,GAAI;QAC1B,QAAQ,QAAQ,EAAE;;AAEtB;AAEO,KAAS,MAAM,EAAA,qBAAoB,KAAG,MAAM,CAAC;IAClD,QAAQ,GAAG,CAAC;QAAE,CAAA,MAAK;MAAK;IACxB,QAAQ,GAAG,CAAC;IAKZ,QAAQ,GAAG,CAAC;IAGZ,QAAQ,GAAG,CAAC;IAMZ,QAAQ,GAAG,CAAC;IAKZ,QAAQ,GAAG,CAAC,mBAAmB;IAC/B,OAAO;AACT;AAEA,MAAM;AAAQ;AACP;;MAAM;IACX,aAAc;QACR;IACN;IACA,YAAA,UAAQ,MAAM,EAAQ;QACpB,OAAO,GAAI;IACb;AACF;AAEO;KAAe,oCAAY;IAChC,OAAO;QAAE,CAAA,IAAG,CAAC;MAAE;AACjB;;;;wCAxDuC,EAAA,SAAS,qBAAqB;eAA7C,eAAe;;+BAmBjB,EAAA,qBAAoB,KAAG,MAAM;eAAnC,MAAM;;;;qBAmCA"}
\ No newline at end of file
{"version":3,"sources":["uni_modules/test-uniplugin/utssdk/app-ios/index.uts"],"sourcesContent":["import { UIDevice } from 'UIKit'\nimport { CLLocationManager, CLAuthorizationStatus } from 'CoreLocation'\n\ntype GetBatteryInfoOptions = {\n name: string\n pwd: number\n success?: (res: UTSJSONObject) => void\n fail?: (res: UTSJSONObject) => void\n complete?: (res: UTSJSONObject) => void\n}\n\nexport default function getBatteryInfo(options: GetBatteryInfoOptions) {\n new UIAlertController(\n (title = title),\n (message = message),\n (preferredStyle = UIAlertController.Style.alert)\n )\n const res = {\n errMsg: 'getBatteryInfo:ok',\n level: UIDevice.current.batteryLevel * 100,\n isCharging: UIDevice.current.batteryState == UIDevice.BatteryState.charging,\n }\n if (options.success != null) {\n options.success!(res)\n }\n if (options.complete != null) {\n options.complete!(res)\n }\n}\n\nexport function test1(callback: () => void): string {\n console.log({ \"a\": \"b\" })\n console.log('test1')\n\n\n\n\n console.log('def ios')\n\n\n console.log('ndef android')\n\n\n\n\n\n console.log('def android || def ios')\n\n\n\n\n console.log(CLLocationManager, CLAuthorizationStatus)\n return 'test1'\n}\n\nclass Test1 { }\nexport class Test {\n constructor() {\n new Test1()\n }\n test(): string | null {\n return null\n }\n}\n\nexport async function testAsync() {\n return { a: 1 }\n}\n"],"names":[],"mappings":";AAAA;AACA;AAE6B;;MAAxB;IACH,WAAA,MAAM,MAAM,EAAA;IACZ,WAAA,KAAK,QAAM,EAAA;IACX,WAAA,SAAQ,aAA8B;IACtC,WAAA,MAAK,aAA8B;IACnC,WAAA,UAAS,aAA8B;AACzC;AAEe,KAAS,eAAe,EAAA,SAAS,qBAAqB,EAAE;IACjE,kBACD,OAAQ,OACR,SAAU,SACV,gBAAiB,kBAAkB,KAAK,CAAC,KAAK;IAEjD,IAAM,MAAM;QACV,CAAA,SAAQ;QACR,CAAA,QAAO,SAAS,OAAO,CAAC,YAAY,GAAG,GAAG;QAC1C,CAAA,aAAY,SAAS,OAAO,CAAC,YAAY,IAAI,SAAS,YAAY,CAAC,QAAQ;MAC5E;IACD,IAAI,QAAQ,OAAO,IAAI,GAAI;QACzB,QAAQ,OAAO,EAAE;;IAEnB,IAAI,QAAQ,QAAQ,IAAI,GAAI;QAC1B,QAAQ,QAAQ,EAAE;;AAEtB;AAEO,KAAS,MAAM,EAAA,qBAAoB,KAAG,MAAM,CAAC;IAClD,QAAQ,GAAG,CAAC;QAAE,KAAK;MAAK;IACxB,QAAQ,GAAG,CAAC;IAKZ,QAAQ,GAAG,CAAC;IAGZ,QAAQ,GAAG,CAAC;IAMZ,QAAQ,GAAG,CAAC;IAKZ,QAAQ,GAAG,CAAC,mBAAmB;IAC/B,OAAO;AACT;AAEA,MAAM;AAAQ;AACP;;MAAM;IACX,aAAc;QACR;IACN;IACA,YAAA,UAAQ,MAAM,EAAQ;QACpB,OAAO,GAAI;IACb;AACF;AAEO;KAAe,oCAAY;IAChC,OAAO;QAAE,CAAA,IAAG,CAAC;MAAE;AACjB;;;;wCAxDuC,EAAA,SAAS,qBAAqB;eAA7C,eAAe;;+BAmBjB,EAAA,qBAAoB,KAAG,MAAM;eAAnC,MAAM;;;;qBAmCA"}
\ No newline at end of file
......@@ -26,7 +26,7 @@ func getBatteryInfo(_ options: GetBatteryInfoOptions) {
}
func test1(_ callback: UTSCallback) -> String {
console.log(UTSJSONObject([
""a"": "b"
"a": "b"
]), " at uni_modules/test-uniplugin/utssdk/app-ios/index.uts:32");
console.log("test1", " at uni_modules/test-uniplugin/utssdk/app-ios/index.uts:33");
console.log("def ios", " at uni_modules/test-uniplugin/utssdk/app-ios/index.uts:38");
......
{
"version": "1",
"env": {
"compilerVersion": "3.6.10"
},
"files": {
"utssdk/app-android/index.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"utssdk/common/utils.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"package.json": {
"md5": "9595031a0d4158abb72060cdf3a200c1"
},
"utssdk/app-android/assets/test.json": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
}
}
}
\ No newline at end of file
{
"version": "1",
"env": {
"compilerVersion": "3.6.10"
},
"files": {
"common/test/test.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"common/utils.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"index.uts": {
"md5": "012e7488376fec3b6d104a0242a63535"
},
"package.json": {
"md5": "9595031a0d4158abb72060cdf3a200c1"
}
}
}
\ No newline at end of file
{
"version": "1",
"env": {
"compilerVersion": "3.6.10"
},
"files": {
"utssdk/app-ios/index.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"utssdk/common/utils.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"package.json": {
"md5": "9595031a0d4158abb72060cdf3a200c1"
},
"utssdk/app-ios/assets/test.json": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
}
}
}
\ No newline at end of file
{
"version": "1",
"env": {
"compilerVersion": "3.6.10"
},
"files": {
"common/test/test.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"common/utils.uts": {
"md5": "d41d8cd98f00b204e9800998ecf8427e"
},
"index.uts": {
"md5": "012e7488376fec3b6d104a0242a63535"
},
"package.json": {
"md5": "9595031a0d4158abb72060cdf3a200c1"
}
}
}
\ No newline at end of file
import { resolve } from 'path'
import {
checkManifest,
resolveManifestJson,
resolvePluginAndroidFiles,
resolvePluginCommonFiles,
resolvePluginIOSFiles,
} from '../src/manifest/manifest'
import { checkKotlinCompile } from '../src/manifest/index'
const pluginModuleDir = resolve(__dirname, 'examples/uts/uni_modules/test-uts')
const pluginDir = resolve(__dirname, 'examples/uts/utssdk/test-uts')
const outputDir = resolve(__dirname, 'examples/uts/unpackage/dist/dev/app-plus')
const cacheDir = resolve(__dirname, 'examples/uts/unpackage/cache')
const env = { compilerVersion: '3.6.10' }
const pluginModuleOptions = {
id: 'test-uts',
env,
cacheDir,
outputDir,
pluginDir: pluginModuleDir,
pluginRelativeDir: 'uni_modules/test-uts',
is_uni_modules: true,
}
const pluginOptions = {
id: 'test-uts',
env,
cacheDir,
outputDir,
pluginDir,
pluginRelativeDir: 'utssdk/test-uts',
is_uni_modules: false,
}
describe('manifest', () => {
test('resolve common files', async () => {
expect(await resolvePluginCommonFiles(pluginDir, false)).toEqual([
test('resolve android files', async () => {
expect(await resolvePluginAndroidFiles(pluginDir, false)).toEqual([
'index.uts',
'package.json',
'common/utils.uts',
'common/test/test.uts',
])
expect(await resolvePluginCommonFiles(pluginModuleDir, true)).toEqual([
expect(await resolvePluginAndroidFiles(pluginModuleDir, true)).toEqual([
'package.json',
'utssdk/common/utils.uts',
])
})
test('resolve android files', async () => {
expect(await resolvePluginAndroidFiles(pluginDir, false)).toEqual([
'app-android/assets/test.json',
])
expect(await resolvePluginAndroidFiles(pluginModuleDir, true)).toEqual([
'utssdk/app-android/index.uts',
'utssdk/app-android/assets/test.json',
])
})
test('resolve ios files', async () => {
expect(await resolvePluginIOSFiles(pluginDir, false)).toEqual([])
expect(await resolvePluginIOSFiles(pluginDir, false)).toEqual([
'index.uts',
'package.json',
'common/utils.uts',
'common/test/test.uts',
])
expect(await resolvePluginIOSFiles(pluginModuleDir, true)).toEqual([
'package.json',
'utssdk/common/utils.uts',
'utssdk/app-ios/index.uts',
'utssdk/app-ios/assets/test.json',
])
})
test('check manifest', async () => {
// await genManifestFile('app-android',pluginModuleOptions)
// await genManifestFile('app-ios',pluginModuleOptions)
// await genManifestFile('app-android',pluginOptions)
// await genManifestFile('app-ios',pluginOptions)
const manifest = resolveManifestJson(
'app-android',
pluginModuleOptions.pluginRelativeDir,
cacheDir
)!
expect(
await checkManifest(manifest, {
env: { compilerVersion: '3.6.11' },
files: [],
pluginDir: pluginModuleDir,
})
).toBe(false)
expect(
await checkManifest(manifest, {
env,
files: Object.keys(manifest.files),
pluginDir: pluginModuleDir,
})
).toBe(true)
const manifest1 = JSON.parse(JSON.stringify(manifest))
const filename = 'utssdk/app-android/assets/test.json'
manifest1.files[filename]['md5'] = ''
expect(
await checkManifest(manifest1, {
env,
files: Object.keys(manifest.files),
pluginDir: pluginModuleDir,
})
).toBe(filename)
})
test('gen android manifest', async () => {
expect(
await (
await checkKotlinCompile('standard', pluginModuleOptions)
).expired
).toBe(true)
const res = await checkKotlinCompile('standard', pluginOptions)
expect(res.expired).toBe(false)
expect(res.cacheFile).toContain('classes.dex')
})
test('gen ios manifest', async () => {
// console.log(await checkCompile('standard', pluginModuleOptions))
})
})
import { existsSync, readFileSync } from 'fs'
import { join } from 'path'
import {
Manifest,
resolvePluginAndroidFiles,
resolvePluginCommonFiles,
} from './manifest'
interface CheckOptions {
pluginDir: string
pluginRelativeDir: string
cacheDir: string
inputDir: string
outputDir: string
is_uni_modules: boolean
}
export function shouldCompile(
playground: typeof process.env.HX_USE_BASE_TYPE,
options: CheckOptions
) {
if (playground === 'standard') {
return checkWithStandardPlayground(options)
}
return checkWithCustomPlayground(options)
}
/**
* 检查标准基座缓存
* @param param0
* @returns
*/
async function checkWithStandardPlayground({
pluginDir,
cacheDir,
outputDir,
pluginRelativeDir,
is_uni_modules,
}: CheckOptions) {
// 第一步:检查 dex 文件是否存在
const dexFile = resolveDexCacheFile(pluginRelativeDir, outputDir)
if (!dexFile) {
return false
}
// 第二步:获取当前插件缓存文件信息
const manifest = resolveManifestJson(pluginRelativeDir, cacheDir)
if (!manifest) {
return false
}
// 第二步:获取当前平台所以的资源文件列表
await resolveManifestFiles(pluginDir, is_uni_modules)
}
function resolveManifestFiles(pluginDir: string, is_uni_modules: boolean) {
return Promise.all([
resolvePluginCommonFiles(pluginDir, is_uni_modules),
resolvePluginAndroidFiles(pluginDir, is_uni_modules),
]).then((files) => files.flat())
}
/**
* 检查自定义基座缓存
* @param param0
*/
async function checkWithCustomPlayground({
pluginDir,
inputDir,
outputDir,
}: CheckOptions) {}
function resolveDexCacheFile(pluginRelativeDir: string, outputDir: string) {
const file = join(outputDir, '../.uts/dex', pluginRelativeDir, 'classes.dex')
return (existsSync(file) && file) || ''
}
function resolveManifestJson(pluginRelativeDir: string, cacheDir: string) {
const file = join(
cacheDir,
'app-android/uts',
pluginRelativeDir,
'manifest.json'
)
if (existsSync(file)) {
try {
return JSON.parse(readFileSync(file, 'utf8')) as Manifest
} catch (e) {}
}
}
import { existsSync } from 'fs'
import { join } from 'path'
import {
checkManifest,
hasCustomResources,
isCustomResources,
resolveManifestJson,
resolvePluginAndroidFiles,
} from './manifest'
import {
APP_PLATFORM,
CheckOptions,
CheckResult,
customResourceChangedTips,
customResourceTips,
} from './utils'
interface PlatformOptions {
customRes: string[]
cacheFile: false | string
}
const ANDROID_CUSTOM_RES = [
'app-android/assets/',
'app-android/libs/',
'app-android/res/',
'app-android/AndroidManifest.xml',
'app-android/config.json',
]
const IOS_CUSTOM_RES = [
'app-ios/Frameworks/',
'app-ios/Resources/',
'app-ios/Info.plist',
'app-ios/config.json',
]
export function checkKotlinCompile(
playground: typeof process.env.HX_USE_BASE_TYPE,
options: CheckOptions
) {
return checkCompile('app-android', playground, options)
}
export function checkSwiftCompile(
playground: typeof process.env.HX_USE_BASE_TYPE,
options: CheckOptions
) {
return checkCompile('app-ios', playground, options)
}
function checkCompile(
platform: APP_PLATFORM,
playground: typeof process.env.HX_USE_BASE_TYPE,
options: CheckOptions
) {
const platformOptions: PlatformOptions = {
customRes: platform === 'app-android' ? ANDROID_CUSTOM_RES : IOS_CUSTOM_RES,
cacheFile:
platform === 'app-android'
? resolveDexCacheFile(options.pluginRelativeDir, options.outputDir)
: false,
}
if (playground === 'standard') {
return checkWithPlayground('standard', options, platformOptions)
}
return checkWithPlayground('custom', options, platformOptions)
}
async function checkWithPlayground(
type: typeof process.env.HX_USE_BASE_TYPE,
{
id,
env,
cacheDir,
pluginDir,
pluginRelativeDir,
is_uni_modules,
}: CheckOptions,
{ customRes, cacheFile }: PlatformOptions
): Promise<CheckResult> {
// 第一步:获取所有文件列表
const files = await resolvePluginAndroidFiles(pluginDir, is_uni_modules)
let tips = ''
// 标准基座检查是否包含原生资源/配置
if (type === 'standard' && hasCustomResources(files, customRes)) {
tips = customResourceTips(id)
}
// 第二步:检查 dex 文件是否存在
if (cacheFile !== false && !cacheFile) {
return { expired: true, tips, cacheFile: '' }
}
// 第三步:获取当前插件缓存文件信息
const manifest = resolveManifestJson(
'app-android',
pluginRelativeDir,
cacheDir
)
if (!manifest) {
return { expired: true, tips, cacheFile: '' }
}
// 第四步:检查文件变更
const res = await checkManifest(manifest, { env, files, pluginDir })
// 自定义基座检查原生资源/配置是否发生变化
if (type === 'custom' && typeof res === 'string') {
if (isCustomResources(res, customRes)) {
tips = customResourceChangedTips(id)
}
}
return {
expired: res !== true,
tips,
cacheFile,
}
}
function resolveDexCacheFile(pluginRelativeDir: string, outputDir: string) {
const file = join(outputDir, '../.uts/dex', pluginRelativeDir, 'classes.dex')
return (existsSync(file) && file) || ''
}
import { statSync } from 'fs'
import { existsSync, readFileSync, statSync, outputFileSync } from 'fs-extra'
import { join } from 'path'
import md5 from 'md5-file'
import glob from 'fast-glob'
type APP_PLATFORM = 'app' | 'app-android' | 'app-ios'
import { APP_PLATFORM } from './utils'
const fileCaches = new Map<
string,
......@@ -14,9 +13,7 @@ const fileCaches = new Map<
>()
interface ManifestFile {
md5: {
'built-in': string
}
md5: string
}
const VERSION = '1'
......@@ -46,69 +43,92 @@ export async function hash(file: string) {
})
}
interface GenManifestJsonBaseOptions {
interface GenManifestJsonOptions {
pluginDir: string
env: Record<string, unknown>
}
interface GenManifestJsonOptions extends GenManifestJsonBaseOptions {
files: {
[file: string]: ManifestFile
}
}
interface GenPlatformManifestJsonOptions extends GenManifestJsonBaseOptions {
files: string[]
commonFiles: {
[file: string]: ManifestFile
}
}
function genManifestJson(options: GenManifestJsonOptions) {
return {
version: VERSION,
...options,
}
files?: string[]
is_uni_modules: boolean
}
export async function genPlatformManifestJson({
pluginDir,
files,
env,
commonFiles,
}: GenPlatformManifestJsonOptions) {
return genManifestJson({
export async function genManifestFile(
platform: APP_PLATFORM,
{
files,
pluginDir,
env,
files: {
...commonFiles,
...(await genManifestFiles(pluginDir, files)),
},
})
}
export async function genManifests(
pluginDir: string,
{
cacheDir,
pluginRelativeDir,
is_uni_modules,
env,
}: {
cacheDir: string
pluginRelativeDir: string
is_uni_modules: boolean
env: Record<string, unknown>
pluginDir: string
files?: string[]
}
) {
outputFileSync(
resolveManifestFilename(platform, pluginRelativeDir, cacheDir),
JSON.stringify(
await genManifestJson(platform, {
pluginDir,
files,
env,
is_uni_modules,
}),
null,
2
)
)
return true
}
export async function genManifestJson(
platform: APP_PLATFORM,
{ pluginDir, files, env, is_uni_modules }: GenManifestJsonOptions
): Promise<Manifest> {
if (!files) {
if (platform === 'app-android') {
files = await resolvePluginAndroidFiles(pluginDir, is_uni_modules)
} else if (platform === 'app-ios') {
files = await resolvePluginIOSFiles(pluginDir, is_uni_modules)
}
}
) {}
if (!files) {
files = []
}
return {
version: VERSION,
env,
files: await genManifestFiles(pluginDir, files),
}
}
async function genManifestFiles(dir: string, files: string[]) {
const manifestFiles: Manifest['files'] = {}
await Promise.all(
files.map((file) =>
hash(join(dir, file)).then((hash) => {
manifestFiles[file] = { md5: { 'built-in': hash } }
})
)
)
// 优先 uts 文件
files = files.sort((a, b) => {
const aUts = a.endsWith('.uts')
const bUts = b.endsWith('.uts')
if (aUts && bUts) {
return a > b ? 1 : -1
}
if (aUts) {
return -1
}
return 1
})
const md5Arr = await Promise.all(files.map((file) => hash(join(dir, file))))
files.forEach((name, index) => {
manifestFiles[name] = {
md5: md5Arr[index],
}
})
return manifestFiles
}
export async function resolvePluginCommonFiles(
async function resolvePluginCommonFiles(
pluginDir: string,
is_uni_modules: boolean
) {
......@@ -121,14 +141,20 @@ export async function resolvePluginAndroidFiles(
pluginDir: string,
is_uni_modules: boolean
) {
return resolvePluginPlatformFiles('app-android', pluginDir, is_uni_modules)
return Promise.all([
resolvePluginCommonFiles(pluginDir, is_uni_modules),
resolvePluginPlatformFiles('app-android', pluginDir, is_uni_modules),
]).then((files) => files.flat())
}
export async function resolvePluginIOSFiles(
pluginDir: string,
is_uni_modules: boolean
) {
return resolvePluginPlatformFiles('app-ios', pluginDir, is_uni_modules)
return Promise.all([
resolvePluginCommonFiles(pluginDir, is_uni_modules),
resolvePluginPlatformFiles('app-ios', pluginDir, is_uni_modules),
]).then((files) => files.flat())
}
async function resolvePluginPlatformFiles(
......@@ -141,8 +167,99 @@ async function resolvePluginPlatformFiles(
})
}
export function checkManifestBase(manifest: Manifest) {
export async function checkManifest(
manifest: Manifest,
{
env,
files,
pluginDir,
}: { pluginDir: string; files: string[]; env: Record<string, unknown> }
) {
if (manifest.version !== VERSION) {
return false
}
if (isEnvExpired(manifest.env, env)) {
return false
}
return checkFiles(manifest.files, files, pluginDir)
}
/**
* 判断 env 是否过期
* @param value
* @param other
* @returns
*/
function isEnvExpired(
value: Record<string, unknown>,
other: Record<string, unknown>
) {
const valueKeys = Object.keys(value)
const otherKeys = Object.keys(other)
if (valueKeys.length !== otherKeys.length) {
return true
}
if (valueKeys.find((name) => value[name] !== other[name])) {
return true
}
return false
}
/**
* 判断文件列表是否过期
* @param files
* @param filenames
* @returns
*/
async function checkFiles(
files: Manifest['files'],
filenames: string[],
pluginDir: string
) {
const oldFilenames = Object.keys(files)
// 第一步:优先判断文件列表长度
if (oldFilenames.length !== filenames.length) {
return false
}
// 第二步:判断文件列表
if (oldFilenames.find((name) => !filenames.includes(name))) {
return false
}
// 第三步:判断文件 md5
for (const name of oldFilenames) {
const md5 = await hash(join(pluginDir, name))
if (files[name].md5 !== md5) {
return name
}
}
return true
}
export function hasCustomResources(files: string[], resources: string[]) {
return files.some((file) => isCustomResources(file, resources))
}
export function isCustomResources(file: string, resources: string[]) {
return resources.some((res) => file.includes(res))
}
function resolveManifestFilename(
platform: APP_PLATFORM,
pluginRelativeDir: string,
cacheDir: string
) {
return join(cacheDir, platform, 'uts', pluginRelativeDir, 'manifest.json')
}
export function resolveManifestJson(
platform: APP_PLATFORM,
pluginRelativeDir: string,
cacheDir: string
) {
const file = resolveManifestFilename(platform, pluginRelativeDir, cacheDir)
if (existsSync(file)) {
try {
return JSON.parse(readFileSync(file, 'utf8')) as Manifest
} catch (e) {}
}
}
export type APP_PLATFORM = 'app-android' | 'app-ios'
export interface CheckOptions {
id: string
env: Record<string, unknown>
pluginDir: string
pluginRelativeDir: string
cacheDir: string
outputDir: string
is_uni_modules: boolean
}
export interface CheckResult {
expired: boolean
tips?: string
cacheFile: string | false
}
export function customResourceTips(id: string) {
return `uts插件[${id}]依赖的原生配置或三方SDK在运行至标准基座时不能生效,如需正常调用请使用自定义基座`
}
export function customResourceChangedTips(id: string) {
return `uts插件[${id}]依赖的原生配置或三方SDK发生变化,需要重新打包自定义基座`
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册