vxrn 2.13.7 → 2.13.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +3 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/cli.native.js +5 -2
- package/dist/cli.native.js.map +1 -1
- package/dist/config/getBaseViteConfigOnly.mjs +3 -3
- package/dist/config/getBaseViteConfigOnly.mjs.map +1 -1
- package/dist/config/getBaseViteConfigOnly.native.js +3 -3
- package/dist/config/getBaseViteConfigOnly.native.js.map +1 -1
- package/dist/config/getOptionsFilled.mjs +24 -2
- package/dist/config/getOptionsFilled.mjs.map +1 -1
- package/dist/config/getOptionsFilled.native.js +25 -2
- package/dist/config/getOptionsFilled.native.js.map +1 -1
- package/dist/config/getServerOptionsFilled.mjs +119 -1
- package/dist/config/getServerOptionsFilled.mjs.map +1 -1
- package/dist/config/getServerOptionsFilled.native.js +137 -1
- package/dist/config/getServerOptionsFilled.native.js.map +1 -1
- package/dist/exports/build.mjs +6 -9
- package/dist/exports/build.mjs.map +1 -1
- package/dist/exports/build.native.js +6 -9
- package/dist/exports/build.native.js.map +1 -1
- package/dist/exports/dev.mjs +4 -6
- package/dist/exports/dev.mjs.map +1 -1
- package/dist/exports/dev.native.js +6 -6
- package/dist/exports/dev.native.js.map +1 -1
- package/dist/exports/prebuild.mjs +4 -4
- package/dist/exports/prebuild.mjs.map +1 -1
- package/dist/exports/prebuild.native.js +4 -4
- package/dist/exports/prebuild.native.js.map +1 -1
- package/dist/exports/prebuildWithoutExpo.mjs +95 -88
- package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
- package/dist/exports/prebuildWithoutExpo.native.js +95 -88
- package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
- package/dist/plugins/autoDepOptimizePlugin.mjs +3 -3
- package/dist/plugins/autoDepOptimizePlugin.mjs.map +1 -1
- package/dist/plugins/autoDepOptimizePlugin.native.js +3 -3
- package/dist/plugins/autoDepOptimizePlugin.native.js.map +1 -1
- package/dist/plugins/reactNativeDevAssetPlugin.mjs +4 -4
- package/dist/plugins/reactNativeDevAssetPlugin.mjs.map +1 -1
- package/dist/plugins/reactNativeDevAssetPlugin.native.js +4 -4
- package/dist/plugins/reactNativeDevAssetPlugin.native.js.map +1 -1
- package/dist/rn-commands/bundle/buildBundle.mjs +18 -5
- package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
- package/dist/rn-commands/bundle/buildBundle.native.js +18 -5
- package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
- package/dist/user-interface/index.mjs +1 -1
- package/dist/user-interface/index.mjs.map +1 -1
- package/dist/user-interface/index.native.js +1 -1
- package/dist/user-interface/index.native.js.map +1 -1
- package/dist/utils/env-editor.mjs +198 -0
- package/dist/utils/env-editor.mjs.map +1 -0
- package/dist/utils/env-editor.native.js +266 -0
- package/dist/utils/env-editor.native.js.map +1 -0
- package/dist/utils/fs.mjs +48 -0
- package/dist/utils/fs.mjs.map +1 -0
- package/dist/utils/fs.native.js +48 -0
- package/dist/utils/fs.native.js.map +1 -0
- package/dist/utils/getVitePath.mjs +2 -2
- package/dist/utils/getVitePath.mjs.map +1 -1
- package/dist/utils/getVitePath.native.js +2 -2
- package/dist/utils/getVitePath.native.js.map +1 -1
- package/dist/utils/patches.mjs +38 -29
- package/dist/utils/patches.mjs.map +1 -1
- package/dist/utils/patches.native.js +38 -29
- package/dist/utils/patches.native.js.map +1 -1
- package/dist/utils/scanDepsToOptimize.mjs +12 -11
- package/dist/utils/scanDepsToOptimize.mjs.map +1 -1
- package/dist/utils/scanDepsToOptimize.native.js +12 -11
- package/dist/utils/scanDepsToOptimize.native.js.map +1 -1
- package/dist/utils/state.mjs +5 -5
- package/dist/utils/state.mjs.map +1 -1
- package/dist/utils/state.native.js +5 -5
- package/dist/utils/state.native.js.map +1 -1
- package/dist/utils/utils.mjs +4 -3
- package/dist/utils/utils.mjs.map +1 -1
- package/dist/utils/utils.native.js +4 -3
- package/dist/utils/utils.native.js.map +1 -1
- package/package.json +12 -18
- package/src/cli.ts +5 -4
- package/src/config/getBaseViteConfigOnly.ts +3 -3
- package/src/config/getOptionsFilled.ts +35 -2
- package/src/config/getServerOptionsFilled.test.ts +37 -0
- package/src/config/getServerOptionsFilled.ts +57 -1
- package/src/exports/build.ts +5 -12
- package/src/exports/clean.test.ts +1 -1
- package/src/exports/dev.ts +5 -6
- package/src/exports/prebuild.ts +4 -4
- package/src/exports/prebuildWithoutExpo.ts +102 -89
- package/src/plugins/autoDepOptimizePlugin.ts +3 -3
- package/src/plugins/reactNativeDevAssetPlugin.ts +4 -4
- package/src/rn-commands/bundle/buildBundle.ts +15 -5
- package/src/user-interface/index.ts +1 -1
- package/src/utils/env-editor.LICENSE +9 -0
- package/src/utils/env-editor.ts +214 -0
- package/src/utils/fs.ts +59 -0
- package/src/utils/getVitePath.ts +2 -2
- package/src/utils/patches.test.ts +36 -36
- package/src/utils/patches.ts +39 -27
- package/src/utils/scanDepsToOptimize.test.ts +2 -2
- package/src/utils/scanDepsToOptimize.ts +6 -5
- package/src/utils/state.ts +5 -7
- package/src/utils/utils.ts +5 -5
- package/types/config/getOptionsFilled.d.ts +9 -2
- package/types/config/getOptionsFilled.d.ts.map +1 -1
- package/types/config/getServerOptionsFilled.d.ts.map +1 -1
- package/types/exports/build.d.ts +1 -1
- package/types/exports/build.d.ts.map +1 -1
- package/types/exports/dev.d.ts.map +1 -1
- package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
- package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
- package/types/user-interface/index.d.ts.map +1 -1
- package/types/utils/env-editor.d.ts +9 -0
- package/types/utils/env-editor.d.ts.map +1 -0
- package/types/utils/fs.d.ts +9 -0
- package/types/utils/fs.d.ts.map +1 -0
- package/types/utils/patches.d.ts.map +1 -1
- package/types/utils/scanDepsToOptimize.d.ts.map +1 -1
- package/types/utils/state.d.ts.map +1 -1
- package/types/utils/utils.d.ts +2 -2
- package/types/utils/utils.d.ts.map +1 -1
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process'
|
|
2
2
|
import { createHash } from 'node:crypto'
|
|
3
|
+
import {
|
|
4
|
+
copyFileSync,
|
|
5
|
+
existsSync,
|
|
6
|
+
lstatSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
readdirSync,
|
|
9
|
+
readFileSync,
|
|
10
|
+
realpathSync,
|
|
11
|
+
rmSync,
|
|
12
|
+
statSync,
|
|
13
|
+
symlinkSync,
|
|
14
|
+
writeFileSync,
|
|
15
|
+
} from 'node:fs'
|
|
3
16
|
import module from 'node:module'
|
|
4
17
|
import path from 'node:path'
|
|
5
18
|
import { pathToFileURL } from 'node:url'
|
|
@@ -13,8 +26,8 @@ import {
|
|
|
13
26
|
type NativeAppManifest,
|
|
14
27
|
type PlistValue,
|
|
15
28
|
} from '@vxrn/utils/nativeAppManifest'
|
|
16
|
-
import FSExtra from 'fs-extra'
|
|
17
29
|
import sharp from 'sharp'
|
|
30
|
+
import { readJSONSync } from '../utils/fs'
|
|
18
31
|
import { swiftPackageDirectories } from '../utils/swiftPackageId'
|
|
19
32
|
|
|
20
33
|
type NativeProjectPatches = {
|
|
@@ -298,7 +311,7 @@ ${imports.join('\n')}
|
|
|
298
311
|
}
|
|
299
312
|
|
|
300
313
|
function generateOneBridgingHeader(dest: string, app: NativeAppManifest): void {
|
|
301
|
-
|
|
314
|
+
writeFileSync(
|
|
302
315
|
path.join(dest, app.name, ONE_BRIDGING_HEADER_NAME),
|
|
303
316
|
renderOneBridgingHeader(app)
|
|
304
317
|
)
|
|
@@ -488,11 +501,11 @@ function copyAppResources({
|
|
|
488
501
|
}
|
|
489
502
|
for (const [file, target] of copies) {
|
|
490
503
|
const source = path.resolve(root, file)
|
|
491
|
-
if (!
|
|
504
|
+
if (!existsSync(source)) {
|
|
492
505
|
throw new Error(`[vxrn] native.app names ${file}, which does not exist`)
|
|
493
506
|
}
|
|
494
|
-
|
|
495
|
-
|
|
507
|
+
mkdirSync(path.dirname(target), { recursive: true })
|
|
508
|
+
copyFileSync(source, target)
|
|
496
509
|
}
|
|
497
510
|
}
|
|
498
511
|
|
|
@@ -801,7 +814,7 @@ function generateSceneDelegate(args: {
|
|
|
801
814
|
}): void {
|
|
802
815
|
const { dest, platform, app } = args
|
|
803
816
|
if (platform !== 'ios') return
|
|
804
|
-
|
|
817
|
+
writeFileSync(
|
|
805
818
|
path.join(dest, app.name, 'SceneDelegate.swift'),
|
|
806
819
|
renderSceneDelegateSwift(app.name)
|
|
807
820
|
)
|
|
@@ -809,7 +822,7 @@ function generateSceneDelegate(args: {
|
|
|
809
822
|
// widgets the app gets its own file when it has any entitlement.
|
|
810
823
|
const entitlements = appEntitlements(app)
|
|
811
824
|
if (Object.keys(entitlements).length && !app.ios?.widgets) {
|
|
812
|
-
|
|
825
|
+
writeFileSync(
|
|
813
826
|
path.join(dest, app.name, `${app.name}.entitlements`),
|
|
814
827
|
renderEntitlements(entitlements)
|
|
815
828
|
)
|
|
@@ -818,7 +831,7 @@ function generateSceneDelegate(args: {
|
|
|
818
831
|
|
|
819
832
|
function generateIosAppIntents(dest: string, platform: 'ios' | 'android', app: NativeAppManifest): void {
|
|
820
833
|
if (platform !== 'ios' || !app.ios?.appIntents) return
|
|
821
|
-
|
|
834
|
+
writeFileSync(
|
|
822
835
|
path.join(dest, app.name, 'OneAppIntents.swift'),
|
|
823
836
|
renderIosAppIntentsSwift(app.ios.appIntents.actions)
|
|
824
837
|
)
|
|
@@ -829,17 +842,17 @@ function generateIosWidgets(dest: string, app: NativeAppManifest): void {
|
|
|
829
842
|
if (!widgets) return
|
|
830
843
|
const appDir = path.join(dest, app.name)
|
|
831
844
|
const extensionDir = path.join(dest, 'OneWidgets')
|
|
832
|
-
|
|
845
|
+
mkdirSync(extensionDir, { recursive: true })
|
|
833
846
|
const entitlements = `<?xml version="1.0" encoding="UTF-8"?>
|
|
834
847
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
835
848
|
<plist version="1.0"><dict><key>com.apple.security.application-groups</key><array><string>${escapeXml(widgets.appGroup)}</string></array></dict></plist>
|
|
836
849
|
`
|
|
837
|
-
|
|
850
|
+
writeFileSync(
|
|
838
851
|
path.join(appDir, 'OneAppWidgets.entitlements'),
|
|
839
852
|
renderEntitlements(appEntitlements(app))
|
|
840
853
|
)
|
|
841
|
-
|
|
842
|
-
|
|
854
|
+
writeFileSync(path.join(extensionDir, 'OneWidgets.entitlements'), entitlements)
|
|
855
|
+
writeFileSync(
|
|
843
856
|
path.join(extensionDir, 'WidgetInfo.plist'),
|
|
844
857
|
`<?xml version="1.0" encoding="UTF-8"?>
|
|
845
858
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -857,7 +870,7 @@ function generateIosWidgets(dest: string, app: NativeAppManifest): void {
|
|
|
857
870
|
</dict></plist>
|
|
858
871
|
`
|
|
859
872
|
)
|
|
860
|
-
|
|
873
|
+
writeFileSync(
|
|
861
874
|
path.join(appDir, 'OneWidgetContract.swift'),
|
|
862
875
|
`import Foundation
|
|
863
876
|
import ActivityKit
|
|
@@ -885,7 +898,7 @@ enum OneWidgetContract {
|
|
|
885
898
|
}
|
|
886
899
|
`
|
|
887
900
|
)
|
|
888
|
-
|
|
901
|
+
writeFileSync(
|
|
889
902
|
path.join(extensionDir, 'OneWidget.swift'),
|
|
890
903
|
`import SwiftUI
|
|
891
904
|
import WidgetKit
|
|
@@ -1176,7 +1189,7 @@ struct OneWidgetsBundle: WidgetBundle {
|
|
|
1176
1189
|
}
|
|
1177
1190
|
`
|
|
1178
1191
|
)
|
|
1179
|
-
|
|
1192
|
+
writeFileSync(
|
|
1180
1193
|
path.join(appDir, 'OneWidgetsBridge.m'),
|
|
1181
1194
|
`#import <React/RCTBridgeModule.h>
|
|
1182
1195
|
#import <React/RCTEventEmitter.h>
|
|
@@ -1193,7 +1206,7 @@ RCT_EXTERN_METHOD(pushToken:(NSString *)identifier resolver:(RCTPromiseResolveBl
|
|
|
1193
1206
|
@end
|
|
1194
1207
|
`
|
|
1195
1208
|
)
|
|
1196
|
-
|
|
1209
|
+
writeFileSync(
|
|
1197
1210
|
path.join(appDir, 'OneWidgetsBridge.swift'),
|
|
1198
1211
|
`import Foundation
|
|
1199
1212
|
import React
|
|
@@ -1387,7 +1400,7 @@ async function writeAppearanceIcon(args: {
|
|
|
1387
1400
|
const variantSource = (variant: { source?: string } | undefined) => {
|
|
1388
1401
|
if (!variant?.source) return source
|
|
1389
1402
|
const resolved = path.resolve(root, variant.source)
|
|
1390
|
-
if (!
|
|
1403
|
+
if (!existsSync(resolved)) {
|
|
1391
1404
|
throw new Error(`[vxrn] native.app icon appearance source does not exist: ${resolved}`)
|
|
1392
1405
|
}
|
|
1393
1406
|
return resolved
|
|
@@ -1421,7 +1434,7 @@ async function writeAppearanceIcon(args: {
|
|
|
1421
1434
|
)
|
|
1422
1435
|
images.push(entry('icon-1024-tinted.png', 'tinted'))
|
|
1423
1436
|
}
|
|
1424
|
-
|
|
1437
|
+
writeFileSync(
|
|
1425
1438
|
path.join(iconDir, 'Contents.json'),
|
|
1426
1439
|
`${JSON.stringify({ images, info: { author: 'xcode', version: 1 } }, null, 2)}\n`
|
|
1427
1440
|
)
|
|
@@ -1441,14 +1454,14 @@ async function generateAppIcons(args: {
|
|
|
1441
1454
|
const template: {
|
|
1442
1455
|
images: Array<{ idiom: string; scale: string; size: string; filename?: string }>
|
|
1443
1456
|
info: { author: string; version: number }
|
|
1444
|
-
} = JSON.parse(
|
|
1457
|
+
} = JSON.parse(readFileSync(path.join(assetsDir, 'AppIcon.appiconset', 'Contents.json'), 'utf8'))
|
|
1445
1458
|
const icons: Array<[string, NativeAppIcon]> = [
|
|
1446
1459
|
['AppIcon', app.icon],
|
|
1447
1460
|
...Object.entries(app.alternateIcons ?? {}),
|
|
1448
1461
|
]
|
|
1449
1462
|
for (const [name, icon] of icons) {
|
|
1450
1463
|
const source = path.resolve(root, icon.source)
|
|
1451
|
-
if (!
|
|
1464
|
+
if (!existsSync(source)) {
|
|
1452
1465
|
throw new Error(`[vxrn] native.app icon source does not exist: ${source}`)
|
|
1453
1466
|
}
|
|
1454
1467
|
const metadata = await sharp(source).metadata()
|
|
@@ -1456,7 +1469,7 @@ async function generateAppIcons(args: {
|
|
|
1456
1469
|
throw new Error(`[vxrn] native.app icon source must be a square image at least 1024px wide: ${source}`)
|
|
1457
1470
|
}
|
|
1458
1471
|
const iconDir = path.join(assetsDir, `${name}.appiconset`)
|
|
1459
|
-
|
|
1472
|
+
mkdirSync(iconDir, { recursive: true })
|
|
1460
1473
|
if (icon.dark || icon.tinted) {
|
|
1461
1474
|
await writeAppearanceIcon({ root, iconDir, icon, source })
|
|
1462
1475
|
continue
|
|
@@ -1483,13 +1496,13 @@ async function generateAppIcons(args: {
|
|
|
1483
1496
|
.png()
|
|
1484
1497
|
.toFile(path.join(iconDir, filename))
|
|
1485
1498
|
}
|
|
1486
|
-
|
|
1499
|
+
writeFileSync(path.join(iconDir, 'Contents.json'), `${JSON.stringify(contents, null, 2)}\n`)
|
|
1487
1500
|
}
|
|
1488
1501
|
return
|
|
1489
1502
|
}
|
|
1490
1503
|
|
|
1491
1504
|
const source = path.resolve(root, app.icon.source)
|
|
1492
|
-
if (!
|
|
1505
|
+
if (!existsSync(source)) {
|
|
1493
1506
|
throw new Error(`[vxrn] native.app.icon source does not exist: ${source}`)
|
|
1494
1507
|
}
|
|
1495
1508
|
const metadata = await sharp(source).metadata()
|
|
@@ -1504,7 +1517,7 @@ async function generateAppIcons(args: {
|
|
|
1504
1517
|
Object.entries(app.alternateIcons ?? {}).map(
|
|
1505
1518
|
async ([name, icon]): Promise<[string, NativeAppIcon, string]> => {
|
|
1506
1519
|
const alternateSource = path.resolve(root, icon.source)
|
|
1507
|
-
if (!
|
|
1520
|
+
if (!existsSync(alternateSource)) {
|
|
1508
1521
|
throw new Error(`[vxrn] native.app icon source does not exist: ${alternateSource}`)
|
|
1509
1522
|
}
|
|
1510
1523
|
const alternate = await sharp(alternateSource).metadata()
|
|
@@ -1597,8 +1610,8 @@ function generateAndroidIconForwarder(dest: string, app: NativeAppManifest): voi
|
|
|
1597
1610
|
...packageName.split('.'),
|
|
1598
1611
|
'AppIconLauncherActivity.kt'
|
|
1599
1612
|
)
|
|
1600
|
-
|
|
1601
|
-
|
|
1613
|
+
mkdirSync(path.dirname(file), { recursive: true })
|
|
1614
|
+
writeFileSync(
|
|
1602
1615
|
file,
|
|
1603
1616
|
`package ${packageName}
|
|
1604
1617
|
|
|
@@ -1646,19 +1659,19 @@ async function generateAppIconPreviews(args: {
|
|
|
1646
1659
|
const resources = appIconPreviewResources(name)
|
|
1647
1660
|
if (platform === 'android') {
|
|
1648
1661
|
const dir = path.join(dest, 'app', 'src', 'main', 'res', 'drawable-nodpi')
|
|
1649
|
-
|
|
1662
|
+
mkdirSync(dir, { recursive: true })
|
|
1650
1663
|
await preview(3).toFile(path.join(dir, `${resources.android}.png`))
|
|
1651
1664
|
continue
|
|
1652
1665
|
}
|
|
1653
1666
|
const dir = path.join(dest, app.name, 'Images.xcassets', `${resources.ios}.imageset`)
|
|
1654
|
-
|
|
1667
|
+
mkdirSync(dir, { recursive: true })
|
|
1655
1668
|
const images: Array<Record<string, string>> = []
|
|
1656
1669
|
for (const scale of [1, 2, 3]) {
|
|
1657
1670
|
const filename = `preview@${scale}x.png`
|
|
1658
1671
|
await preview(scale).toFile(path.join(dir, filename))
|
|
1659
1672
|
images.push({ filename, idiom: 'universal', scale: `${scale}x` })
|
|
1660
1673
|
}
|
|
1661
|
-
|
|
1674
|
+
writeFileSync(
|
|
1662
1675
|
path.join(dir, 'Contents.json'),
|
|
1663
1676
|
`${JSON.stringify({ images, info: { author: 'xcode', version: 1 } }, null, 2)}\n`
|
|
1664
1677
|
)
|
|
@@ -1687,7 +1700,7 @@ async function generateAdaptiveIcon(args: {
|
|
|
1687
1700
|
for (const [layer, file] of Object.entries(layers)) {
|
|
1688
1701
|
if (!file) continue
|
|
1689
1702
|
const source = path.resolve(root, file)
|
|
1690
|
-
if (!
|
|
1703
|
+
if (!existsSync(source)) {
|
|
1691
1704
|
throw new Error(`[vxrn] native.app.android.adaptiveIcon.${layer} does not exist: ${source}`)
|
|
1692
1705
|
}
|
|
1693
1706
|
for (const [density, multiplier] of Object.entries(ANDROID_DENSITIES)) {
|
|
@@ -1700,7 +1713,7 @@ async function generateAdaptiveIcon(args: {
|
|
|
1700
1713
|
}
|
|
1701
1714
|
}
|
|
1702
1715
|
if (!adaptiveIcon.background) {
|
|
1703
|
-
|
|
1716
|
+
writeFileSync(
|
|
1704
1717
|
path.join(res, 'values', 'ic_launcher_background.xml'),
|
|
1705
1718
|
`<?xml version="1.0" encoding="utf-8"?>
|
|
1706
1719
|
<resources>
|
|
@@ -1716,9 +1729,9 @@ async function generateAdaptiveIcon(args: {
|
|
|
1716
1729
|
${adaptiveIcon.monochrome ? ' <monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>\n' : ''}</adaptive-icon>
|
|
1717
1730
|
`
|
|
1718
1731
|
const anydpi = path.join(res, 'mipmap-anydpi-v26')
|
|
1719
|
-
|
|
1732
|
+
mkdirSync(anydpi, { recursive: true })
|
|
1720
1733
|
for (const filename of ['ic_launcher.xml', 'ic_launcher_round.xml']) {
|
|
1721
|
-
|
|
1734
|
+
writeFileSync(path.join(anydpi, filename), adaptiveXml)
|
|
1722
1735
|
}
|
|
1723
1736
|
}
|
|
1724
1737
|
|
|
@@ -1767,8 +1780,8 @@ function generateAccentColor(args: { dest: string; app: NativeAppManifest }): vo
|
|
|
1767
1780
|
const accent = args.app.ios?.accentColor
|
|
1768
1781
|
if (!accent) return
|
|
1769
1782
|
const colorDir = path.join(args.dest, args.app.name, 'Images.xcassets', 'AccentColor.colorset')
|
|
1770
|
-
|
|
1771
|
-
|
|
1783
|
+
mkdirSync(colorDir, { recursive: true })
|
|
1784
|
+
writeFileSync(
|
|
1772
1785
|
path.join(colorDir, 'Contents.json'),
|
|
1773
1786
|
xcodeColorSet(accent.light, accent.dark)
|
|
1774
1787
|
)
|
|
@@ -1787,7 +1800,7 @@ async function generateSplashScreen(args: {
|
|
|
1787
1800
|
const cover = app.splash.resizeMode === 'cover'
|
|
1788
1801
|
const prepareArtwork = async (sourcePath: string, backgroundColor: string) => {
|
|
1789
1802
|
const source = path.resolve(root, sourcePath)
|
|
1790
|
-
if (!
|
|
1803
|
+
if (!existsSync(source)) {
|
|
1791
1804
|
throw new Error(`[vxrn] native.app.splash source does not exist: ${source}`)
|
|
1792
1805
|
}
|
|
1793
1806
|
// a vector source rasterizes at the density its largest use needs: the
|
|
@@ -1822,7 +1835,7 @@ async function generateSplashScreen(args: {
|
|
|
1822
1835
|
// launch surface scales it (aspect-fill on ios, fill on android).
|
|
1823
1836
|
const readBackground = (sourcePath: string) => {
|
|
1824
1837
|
const source = path.resolve(root, sourcePath)
|
|
1825
|
-
if (!
|
|
1838
|
+
if (!existsSync(source)) {
|
|
1826
1839
|
throw new Error(`[vxrn] native.app.splash backgroundImage does not exist: ${source}`)
|
|
1827
1840
|
}
|
|
1828
1841
|
return sharp(source).rotate().png().toBuffer({ resolveWithObject: true })
|
|
@@ -1841,7 +1854,7 @@ async function generateSplashScreen(args: {
|
|
|
1841
1854
|
pointWidth: number | undefined
|
|
1842
1855
|
) => {
|
|
1843
1856
|
const dir = path.join(assets, `${name}.imageset`)
|
|
1844
|
-
|
|
1857
|
+
mkdirSync(dir, { recursive: true })
|
|
1845
1858
|
const scales = pointWidth === undefined ? [1] : [1, 2, 3]
|
|
1846
1859
|
const images: Array<Record<string, unknown>> = []
|
|
1847
1860
|
for (const [variant, suffix, appearances] of [
|
|
@@ -1866,7 +1879,7 @@ async function generateSplashScreen(args: {
|
|
|
1866
1879
|
})
|
|
1867
1880
|
}
|
|
1868
1881
|
}
|
|
1869
|
-
|
|
1882
|
+
writeFileSync(
|
|
1870
1883
|
path.join(dir, 'Contents.json'),
|
|
1871
1884
|
`${JSON.stringify({ images, info: { author: 'xcode', version: 1 } }, null, 2)}\n`
|
|
1872
1885
|
)
|
|
@@ -1883,13 +1896,13 @@ async function generateSplashScreen(args: {
|
|
|
1883
1896
|
}
|
|
1884
1897
|
// the launch background is a named color so a dark launch gets its own.
|
|
1885
1898
|
const colorDir = path.join(assets, 'SplashBackground.colorset')
|
|
1886
|
-
|
|
1887
|
-
|
|
1899
|
+
mkdirSync(colorDir, { recursive: true })
|
|
1900
|
+
writeFileSync(
|
|
1888
1901
|
path.join(colorDir, 'Contents.json'),
|
|
1889
1902
|
xcodeColorSet(app.splash.backgroundColor, dark?.backgroundColor)
|
|
1890
1903
|
)
|
|
1891
1904
|
const { red, green, blue } = srgb(app.splash.backgroundColor)
|
|
1892
|
-
|
|
1905
|
+
writeFileSync(
|
|
1893
1906
|
path.join(appDir, 'LaunchScreen.storyboard'),
|
|
1894
1907
|
`<?xml version="1.0" encoding="UTF-8"?>
|
|
1895
1908
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="launch-controller">
|
|
@@ -1974,7 +1987,7 @@ ${
|
|
|
1974
1987
|
.png()
|
|
1975
1988
|
.toBuffer()
|
|
1976
1989
|
const drawableDensity = path.join(mainRes, `${drawablePrefix}-${density}`)
|
|
1977
|
-
|
|
1990
|
+
mkdirSync(drawableDensity, { recursive: true })
|
|
1978
1991
|
await sharp({
|
|
1979
1992
|
create: {
|
|
1980
1993
|
width: canvasSize,
|
|
@@ -2007,18 +2020,18 @@ ${
|
|
|
2007
2020
|
: undefined
|
|
2008
2021
|
if (background) {
|
|
2009
2022
|
const nodpi = path.join(mainRes, 'drawable-nodpi')
|
|
2010
|
-
|
|
2011
|
-
|
|
2023
|
+
mkdirSync(nodpi, { recursive: true })
|
|
2024
|
+
writeFileSync(path.join(nodpi, 'splash_background.png'), background.data)
|
|
2012
2025
|
if (darkBackground) {
|
|
2013
2026
|
const nightNodpi = path.join(mainRes, 'drawable-night-nodpi')
|
|
2014
|
-
|
|
2015
|
-
|
|
2027
|
+
mkdirSync(nightNodpi, { recursive: true })
|
|
2028
|
+
writeFileSync(
|
|
2016
2029
|
path.join(nightNodpi, 'splash_background.png'),
|
|
2017
2030
|
darkBackground
|
|
2018
2031
|
)
|
|
2019
2032
|
}
|
|
2020
2033
|
}
|
|
2021
|
-
|
|
2034
|
+
writeFileSync(
|
|
2022
2035
|
path.join(drawable, 'launch_screen.xml'),
|
|
2023
2036
|
`<?xml version="1.0" encoding="utf-8"?>
|
|
2024
2037
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
|
@@ -2036,7 +2049,7 @@ ${
|
|
|
2036
2049
|
</layer-list>
|
|
2037
2050
|
`
|
|
2038
2051
|
)
|
|
2039
|
-
|
|
2052
|
+
writeFileSync(
|
|
2040
2053
|
path.join(mainRes, 'values', 'colors.xml'),
|
|
2041
2054
|
`<?xml version="1.0" encoding="utf-8"?>
|
|
2042
2055
|
<resources>
|
|
@@ -2045,8 +2058,8 @@ ${
|
|
|
2045
2058
|
`
|
|
2046
2059
|
)
|
|
2047
2060
|
if (dark) {
|
|
2048
|
-
|
|
2049
|
-
|
|
2061
|
+
mkdirSync(path.join(mainRes, 'values-night'), { recursive: true })
|
|
2062
|
+
writeFileSync(
|
|
2050
2063
|
path.join(mainRes, 'values-night', 'colors.xml'),
|
|
2051
2064
|
`<?xml version="1.0" encoding="utf-8"?>
|
|
2052
2065
|
<resources>
|
|
@@ -2056,19 +2069,19 @@ ${
|
|
|
2056
2069
|
)
|
|
2057
2070
|
}
|
|
2058
2071
|
const stylesPath = path.join(mainRes, 'values', 'styles.xml')
|
|
2059
|
-
const styles =
|
|
2072
|
+
const styles = readFileSync(stylesPath, 'utf8').replace(
|
|
2060
2073
|
' <!-- Customize your theme here. -->',
|
|
2061
2074
|
' <item name="android:windowBackground">@drawable/launch_screen</item>'
|
|
2062
2075
|
)
|
|
2063
|
-
|
|
2076
|
+
writeFileSync(stylesPath, styles)
|
|
2064
2077
|
const stylesV31 = path.join(mainRes, 'values-v31')
|
|
2065
|
-
|
|
2078
|
+
mkdirSync(stylesV31, { recursive: true })
|
|
2066
2079
|
// a values-v31 AppTheme replaces the base one on API 31+, so it is the base
|
|
2067
2080
|
// theme (parent included) plus the system splash items, never a bare style.
|
|
2068
2081
|
if (!styles.includes('</style>')) {
|
|
2069
2082
|
throw new Error('[vxrn] prebuild template styles.xml lost its AppTheme </style> anchor')
|
|
2070
2083
|
}
|
|
2071
|
-
|
|
2084
|
+
writeFileSync(
|
|
2072
2085
|
path.join(stylesV31, 'styles.xml'),
|
|
2073
2086
|
styles.replace(
|
|
2074
2087
|
'</style>',
|
|
@@ -2901,17 +2914,17 @@ export const generateForPlatform = async (
|
|
|
2901
2914
|
const nitroWebImage = platform === 'ios' && nativeProjectPatches.hasNitroWebImage(root)
|
|
2902
2915
|
|
|
2903
2916
|
// owned output: regenerate from the manifest so reruns reproduce bytes.
|
|
2904
|
-
|
|
2917
|
+
rmSync(dest, { recursive: true, force: true })
|
|
2905
2918
|
|
|
2906
2919
|
for (const absoluteSrc of files) {
|
|
2907
2920
|
const relativeFilePath = path.relative(src, absoluteSrc)
|
|
2908
|
-
const stat =
|
|
2921
|
+
const stat = lstatSync(absoluteSrc)
|
|
2909
2922
|
if (stat.isDirectory()) continue
|
|
2910
2923
|
|
|
2911
2924
|
const extension = path.extname(absoluteSrc)
|
|
2912
2925
|
const raw = ['.png', '.jar', '.keystore'].includes(extension)
|
|
2913
2926
|
? null
|
|
2914
|
-
:
|
|
2927
|
+
: readFileSync(absoluteSrc, 'utf8')
|
|
2915
2928
|
const { destRelativePath, content } = renderPrebuildFile({
|
|
2916
2929
|
relativePath: relativeFilePath,
|
|
2917
2930
|
content: raw,
|
|
@@ -2920,15 +2933,15 @@ export const generateForPlatform = async (
|
|
|
2920
2933
|
nitroWebImage,
|
|
2921
2934
|
})
|
|
2922
2935
|
const destPath = path.resolve(dest, destRelativePath)
|
|
2923
|
-
|
|
2936
|
+
mkdirSync(path.dirname(destPath), { recursive: true })
|
|
2924
2937
|
|
|
2925
2938
|
console.info('copying', '"' + absoluteSrc + '"', 'to', '"' + destPath + '"')
|
|
2926
2939
|
|
|
2927
2940
|
if (content === null) {
|
|
2928
|
-
|
|
2941
|
+
copyFileSync(absoluteSrc, destPath)
|
|
2929
2942
|
continue
|
|
2930
2943
|
}
|
|
2931
|
-
|
|
2944
|
+
writeFileSync(destPath, content, {
|
|
2932
2945
|
encoding: 'utf8',
|
|
2933
2946
|
mode: stat.mode,
|
|
2934
2947
|
})
|
|
@@ -2963,14 +2976,14 @@ const KOTLIN_IMPORT_ARTIFACTS = [
|
|
|
2963
2976
|
|
|
2964
2977
|
function kotlinSourceImports(dir: string): Set<string> {
|
|
2965
2978
|
const imports = new Set<string>()
|
|
2966
|
-
if (!
|
|
2979
|
+
if (!existsSync(dir)) return imports
|
|
2967
2980
|
const visit = (entry: string) => {
|
|
2968
|
-
if (
|
|
2969
|
-
for (const child of
|
|
2981
|
+
if (statSync(entry).isDirectory()) {
|
|
2982
|
+
for (const child of readdirSync(entry)) visit(path.join(entry, child))
|
|
2970
2983
|
return
|
|
2971
2984
|
}
|
|
2972
2985
|
if (!entry.endsWith('.kt')) return
|
|
2973
|
-
for (const line of
|
|
2986
|
+
for (const line of readFileSync(entry, 'utf8').split('\n')) {
|
|
2974
2987
|
const match = /^\s*import\s+([A-Za-z0-9_.]+)/.exec(line)
|
|
2975
2988
|
if (match) imports.add(match[1])
|
|
2976
2989
|
}
|
|
@@ -2981,8 +2994,8 @@ function kotlinSourceImports(dir: string): Set<string> {
|
|
|
2981
2994
|
|
|
2982
2995
|
export function enableAppComposeIntegration(dest: string) {
|
|
2983
2996
|
const rootBuildGradlePath = path.join(dest, 'build.gradle')
|
|
2984
|
-
if (
|
|
2985
|
-
let content =
|
|
2997
|
+
if (existsSync(rootBuildGradlePath)) {
|
|
2998
|
+
let content = readFileSync(rootBuildGradlePath, 'utf8')
|
|
2986
2999
|
const composePluginClasspath =
|
|
2987
3000
|
' classpath("org.jetbrains.kotlin.plugin.compose:org.jetbrains.kotlin.plugin.compose.gradle.plugin:$kotlinVersion")'
|
|
2988
3001
|
if (!content.includes('org.jetbrains.kotlin.plugin.compose')) {
|
|
@@ -2990,13 +3003,13 @@ export function enableAppComposeIntegration(dest: string) {
|
|
|
2990
3003
|
? 'classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")'
|
|
2991
3004
|
: 'classpath "org.jetbrains.kotlin:kotlin-gradle-plugin"'
|
|
2992
3005
|
content = insertAfterLine(content, anchor, composePluginClasspath)
|
|
2993
|
-
|
|
3006
|
+
writeFileSync(rootBuildGradlePath, content, 'utf8')
|
|
2994
3007
|
}
|
|
2995
3008
|
}
|
|
2996
3009
|
|
|
2997
3010
|
const appBuildGradlePath = path.join(dest, 'app/build.gradle')
|
|
2998
|
-
if (
|
|
2999
|
-
let content =
|
|
3011
|
+
if (existsSync(appBuildGradlePath)) {
|
|
3012
|
+
let content = readFileSync(appBuildGradlePath, 'utf8')
|
|
3000
3013
|
if (!content.includes('org.jetbrains.kotlin.plugin.compose')) {
|
|
3001
3014
|
const pluginAnchor = content.includes('apply plugin: "org.jetbrains.kotlin.android"')
|
|
3002
3015
|
? 'apply plugin: "org.jetbrains.kotlin.android"'
|
|
@@ -3054,7 +3067,7 @@ export function enableAppComposeIntegration(dest: string) {
|
|
|
3054
3067
|
].join('\n')
|
|
3055
3068
|
)
|
|
3056
3069
|
}
|
|
3057
|
-
|
|
3070
|
+
writeFileSync(appBuildGradlePath, content, 'utf8')
|
|
3058
3071
|
}
|
|
3059
3072
|
}
|
|
3060
3073
|
|
|
@@ -3065,8 +3078,8 @@ export async function generateKotlinSources({ root, dest }: { root: string; dest
|
|
|
3065
3078
|
// breaks :app:compileDebugKotlin when two preserved copies declare one class.
|
|
3066
3079
|
const skip = new Set(['node_modules', 'ios', 'android', 'dist', 'types', 'build', 'tests', '__tests__', 'scripts', 'evidence'])
|
|
3067
3080
|
const sources: string[] = []
|
|
3068
|
-
const manifest =
|
|
3069
|
-
?
|
|
3081
|
+
const manifest = existsSync(path.join(root, 'package.json'))
|
|
3082
|
+
? readJSONSync(path.join(root, 'package.json'))
|
|
3070
3083
|
: {}
|
|
3071
3084
|
const workspacePatterns: string[] = Array.isArray(manifest.workspaces)
|
|
3072
3085
|
? manifest.workspaces
|
|
@@ -3079,8 +3092,8 @@ export async function generateKotlinSources({ root, dest }: { root: string; dest
|
|
|
3079
3092
|
const collect = (dir: string) => {
|
|
3080
3093
|
// declared workspace packages belong to this build; other nested packages
|
|
3081
3094
|
// own their sources and fixtures.
|
|
3082
|
-
if (dir !== root &&
|
|
3083
|
-
for (const entry of
|
|
3095
|
+
if (dir !== root && existsSync(path.join(dir, 'package.json')) && !workspaceRoots.has(dir)) return
|
|
3096
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
3084
3097
|
if (entry.name.startsWith('.') || skip.has(entry.name)) continue
|
|
3085
3098
|
const source = path.join(dir, entry.name)
|
|
3086
3099
|
if (entry.isDirectory()) collect(source)
|
|
@@ -3091,7 +3104,7 @@ export async function generateKotlinSources({ root, dest }: { root: string; dest
|
|
|
3091
3104
|
// the generator owns this directory: rebuild it so a moved or deleted source
|
|
3092
3105
|
// cannot leave a stale copy that redeclares a live class.
|
|
3093
3106
|
const output = path.join(dest, 'app/src/main/java/one/source')
|
|
3094
|
-
|
|
3107
|
+
rmSync(output, { recursive: true, force: true })
|
|
3095
3108
|
if (sources.length === 0) return
|
|
3096
3109
|
const { kotlinSourceId, renderKotlinSourceGlue, writeNativeSourceDeclaration } = await import(
|
|
3097
3110
|
'../utils/nativeSourceContract'
|
|
@@ -3100,12 +3113,12 @@ export async function generateKotlinSources({ root, dest }: { root: string; dest
|
|
|
3100
3113
|
for (const source of sources) {
|
|
3101
3114
|
const id = kotlinSourceId(root, source)
|
|
3102
3115
|
const target = path.join(output, id)
|
|
3103
|
-
|
|
3104
|
-
|
|
3116
|
+
mkdirSync(target, { recursive: true })
|
|
3117
|
+
copyFileSync(source, path.join(target, path.basename(source)))
|
|
3105
3118
|
const contract = writeNativeSourceDeclaration(source)
|
|
3106
3119
|
if (contract.views.length > 0) hasViews = true
|
|
3107
3120
|
if (contract.modules.length > 0 || contract.views.length > 0) {
|
|
3108
|
-
|
|
3121
|
+
writeFileSync(
|
|
3109
3122
|
path.join(target, `OneNativeSource_${id}.kt`),
|
|
3110
3123
|
renderKotlinSourceGlue(id, contract).source
|
|
3111
3124
|
)
|
|
@@ -3131,11 +3144,11 @@ async function generateSwiftPackages({ root, dest }: { root: string; dest: strin
|
|
|
3131
3144
|
const podDir = path.join(dest, 'OneSwiftPackages', id)
|
|
3132
3145
|
const manifest = swiftPodManifest(
|
|
3133
3146
|
path.join(packageDir, 'Package.swift'),
|
|
3134
|
-
|
|
3147
|
+
readFileSync(path.join(packageDir, 'Package.swift'), 'utf8')
|
|
3135
3148
|
)
|
|
3136
3149
|
const sources: string[] = []
|
|
3137
3150
|
const collect = (dir: string) => {
|
|
3138
|
-
for (const entry of
|
|
3151
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
3139
3152
|
// a package at the app root holds the generated native projects too
|
|
3140
3153
|
if (entry.name.startsWith('.') || skip.has(entry.name)) continue
|
|
3141
3154
|
const full = path.join(dir, entry.name)
|
|
@@ -3155,16 +3168,16 @@ async function generateSwiftPackages({ root, dest }: { root: string; dest: strin
|
|
|
3155
3168
|
// tree with real directories and link each file.
|
|
3156
3169
|
for (const source of sources) {
|
|
3157
3170
|
const link = path.join(podDir, 'Sources', path.relative(packageDir, source))
|
|
3158
|
-
|
|
3159
|
-
|
|
3171
|
+
mkdirSync(path.dirname(link), { recursive: true })
|
|
3172
|
+
symlinkSync(realpathSync(source), link)
|
|
3160
3173
|
}
|
|
3161
3174
|
if (artifacts.glue) {
|
|
3162
|
-
|
|
3175
|
+
writeFileSync(
|
|
3163
3176
|
path.join(podDir, 'Sources', 'OneNativeSource.generated.swift'),
|
|
3164
3177
|
artifacts.glue
|
|
3165
3178
|
)
|
|
3166
3179
|
}
|
|
3167
|
-
|
|
3180
|
+
writeFileSync(
|
|
3168
3181
|
path.join(podDir, `${id}.podspec`),
|
|
3169
3182
|
`Pod::Spec.new do |s|
|
|
3170
3183
|
s.name = '${id}'
|
|
@@ -3183,7 +3196,7 @@ async function generateSwiftPackages({ root, dest }: { root: string; dest: strin
|
|
|
3183
3196
|
end
|
|
3184
3197
|
`
|
|
3185
3198
|
)
|
|
3186
|
-
|
|
3199
|
+
writeFileSync(
|
|
3187
3200
|
path.join(podDir, 'Register.m'),
|
|
3188
3201
|
hasView ? `#import <Foundation/Foundation.h>
|
|
3189
3202
|
|
|
@@ -3237,12 +3250,12 @@ export function applyAndroidDependencyPatches(args: {
|
|
|
3237
3250
|
'MainActivity.kt'
|
|
3238
3251
|
)
|
|
3239
3252
|
const rendered = nativeProjectPatches.holdLaunchScreenInMainActivity(
|
|
3240
|
-
nativeProjectPatches.addReactNativeScreensFix(
|
|
3253
|
+
nativeProjectPatches.addReactNativeScreensFix(readFileSync(activityPath, 'utf8'))
|
|
3241
3254
|
)
|
|
3242
3255
|
if (!rendered.includes('RNScreensFragmentFactory')) {
|
|
3243
3256
|
throw new Error('[vxrn] failed to apply the react-native-screens activity patch')
|
|
3244
3257
|
}
|
|
3245
|
-
|
|
3258
|
+
writeFileSync(activityPath, rendered)
|
|
3246
3259
|
}
|
|
3247
3260
|
|
|
3248
3261
|
// use the community cli's final configuration so project-owned dependency
|
|
@@ -3270,7 +3283,7 @@ export async function getNativeDependencyInventory(
|
|
|
3270
3283
|
let version = 'unknown'
|
|
3271
3284
|
try {
|
|
3272
3285
|
version =
|
|
3273
|
-
JSON.parse(
|
|
3286
|
+
JSON.parse(readFileSync(path.join(depRoot, 'package.json'), 'utf8'))
|
|
3274
3287
|
.version ?? 'unknown'
|
|
3275
3288
|
} catch {}
|
|
3276
3289
|
const platforms = Object.entries(dependency.platforms)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createDebugger } from '@vxrn/debug'
|
|
2
|
-
import FSExtra from 'fs-extra'
|
|
3
2
|
import path from 'node:path'
|
|
3
|
+
import { outputJSON, readJSON } from '../utils/fs'
|
|
4
4
|
import { createFilter, type Plugin } from 'vite'
|
|
5
5
|
import type { AutoDepOptimizationOptions } from '../types'
|
|
6
6
|
import {
|
|
@@ -141,7 +141,7 @@ export async function findDepsToOptimize({
|
|
|
141
141
|
const {
|
|
142
142
|
lockFileHash: cachedLockFileHash,
|
|
143
143
|
depsToPreBundleForSsr: cachedDepsToPreBundle,
|
|
144
|
-
} = await
|
|
144
|
+
} = await readJSON(cacheFilePath)
|
|
145
145
|
|
|
146
146
|
if (
|
|
147
147
|
lockFileHash === cachedLockFileHash &&
|
|
@@ -167,7 +167,7 @@ export async function findDepsToOptimize({
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
if (!noCache) {
|
|
170
|
-
void
|
|
170
|
+
void outputJSON(cacheFilePath, {
|
|
171
171
|
lockFileHash,
|
|
172
172
|
depsToPreBundleForSsr: value,
|
|
173
173
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
-
import
|
|
2
|
+
import { copyFile, mkdir, readFile } from 'node:fs/promises'
|
|
3
3
|
import { getMimeType } from 'hono/utils/mime'
|
|
4
4
|
|
|
5
5
|
import type { Plugin, ResolvedConfig } from 'vite'
|
|
@@ -90,8 +90,8 @@ export function reactNativeDevAssetPlugin(
|
|
|
90
90
|
ASSET_DEST_DIR,
|
|
91
91
|
assetData.relativeFileSystemLocation
|
|
92
92
|
)
|
|
93
|
-
await
|
|
94
|
-
await
|
|
93
|
+
await mkdir(assetsDestDir, { recursive: true })
|
|
94
|
+
await copyFile(
|
|
95
95
|
id,
|
|
96
96
|
path.join(assetsDestDir, `${assetData.name}.${assetData.type}`)
|
|
97
97
|
)
|
|
@@ -137,7 +137,7 @@ export default asset;
|
|
|
137
137
|
'./' + pathname.slice(`/${DEV_ASSET_DEST_PATH}/`.length).replace(/\.*$/, '') // './src/assets/one-ball.png'
|
|
138
138
|
|
|
139
139
|
try {
|
|
140
|
-
const asset = await
|
|
140
|
+
const asset = await readFile(assetPath)
|
|
141
141
|
|
|
142
142
|
res.setHeader(
|
|
143
143
|
'content-type',
|