@bitmagic/cli 0.1.83-dev.1 → 0.1.83-dev.3
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/README.md +69 -0
- package/assets/skills/publishing-to-steam/SKILL.md +218 -0
- package/dist/assets/vxl-summary.d.ts +6 -20
- package/dist/assets/vxl-summary.js +9 -100
- package/dist/assets/vxl-summary.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/check.js +5 -0
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/forge.js +1 -1
- package/dist/commands/forge.js.map +1 -1
- package/dist/commands/ios.js +88 -136
- package/dist/commands/ios.js.map +1 -1
- package/dist/commands/steam-build.d.ts +67 -0
- package/dist/commands/steam-build.js +286 -0
- package/dist/commands/steam-build.js.map +1 -0
- package/dist/commands/steam-portal.d.ts +1 -0
- package/dist/commands/steam-portal.js +319 -0
- package/dist/commands/steam-portal.js.map +1 -0
- package/dist/commands/steam-upload.d.ts +37 -0
- package/dist/commands/steam-upload.js +174 -0
- package/dist/commands/steam-upload.js.map +1 -0
- package/dist/commands/steam.d.ts +1 -0
- package/dist/commands/steam.js +504 -0
- package/dist/commands/steam.js.map +1 -0
- package/dist/commands/verify.js +6 -0
- package/dist/commands/verify.js.map +1 -1
- package/dist/editor/asset-viewer.js +5 -4
- package/dist/editor/asset-viewer.js.map +1 -1
- package/dist/editor/server.js +1 -1
- package/dist/editor/server.js.map +1 -1
- package/dist/editor/shell-page.js +3 -3
- package/dist/forge/browser-host.d.ts +1 -1
- package/dist/forge/browser-host.js +1 -1
- package/dist/forge/browser-host.js.map +1 -1
- package/dist/ios/native-overrides.d.ts +27 -0
- package/dist/ios/native-overrides.js +87 -0
- package/dist/ios/native-overrides.js.map +1 -0
- package/dist/ios/record-validate.d.ts +1 -33
- package/dist/ios/record-validate.js +2 -100
- package/dist/ios/record-validate.js.map +1 -1
- package/dist/ios/store-bridge.d.ts +26 -0
- package/dist/ios/store-bridge.js +224 -0
- package/dist/ios/store-bridge.js.map +1 -0
- package/dist/ios/storekit-config.d.ts +15 -0
- package/dist/ios/storekit-config.js +106 -0
- package/dist/ios/storekit-config.js.map +1 -0
- package/dist/ios/xcode-template.d.ts +12 -3
- package/dist/ios/xcode-template.js +158 -27
- package/dist/ios/xcode-template.js.map +1 -1
- package/dist/package/collect-urls.d.ts +1 -1
- package/dist/package/collect-urls.js +10 -2
- package/dist/package/collect-urls.js.map +1 -1
- package/dist/package/offline-payload.d.ts +35 -0
- package/dist/package/offline-payload.js +142 -0
- package/dist/package/offline-payload.js.map +1 -0
- package/dist/package/packaged-check.d.ts +39 -0
- package/dist/package/packaged-check.js +104 -0
- package/dist/package/packaged-check.js.map +1 -0
- package/dist/package/transform.d.ts +4 -4
- package/dist/package/transform.js +3 -3
- package/dist/project/published-three.d.ts +14 -0
- package/dist/project/published-three.js +91 -0
- package/dist/project/published-three.js.map +1 -0
- package/dist/publish/bundle.js +6 -0
- package/dist/publish/bundle.js.map +1 -1
- package/dist/scaffold/project-files.js +7 -4
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.js +2 -0
- package/dist/scaffold/project.js.map +1 -1
- package/dist/scaffold/skill-files.js +3 -1
- package/dist/scaffold/skill-files.js.map +1 -1
- package/dist/scaffold/steam-skill-files.d.ts +2 -0
- package/dist/scaffold/steam-skill-files.js +7 -0
- package/dist/scaffold/steam-skill-files.js.map +1 -0
- package/dist/steam/art-generate.d.ts +55 -0
- package/dist/steam/art-generate.js +174 -0
- package/dist/steam/art-generate.js.map +1 -0
- package/dist/steam/art-render.d.ts +25 -0
- package/dist/steam/art-render.js +157 -0
- package/dist/steam/art-render.js.map +1 -0
- package/dist/steam/art-use.d.ts +20 -0
- package/dist/steam/art-use.js +84 -0
- package/dist/steam/art-use.js.map +1 -0
- package/dist/steam/art.d.ts +98 -0
- package/dist/steam/art.js +243 -0
- package/dist/steam/art.js.map +1 -0
- package/dist/steam/check.d.ts +21 -0
- package/dist/steam/check.js +113 -0
- package/dist/steam/check.js.map +1 -0
- package/dist/steam/config.d.ts +57 -0
- package/dist/steam/config.js +145 -0
- package/dist/steam/config.js.map +1 -0
- package/dist/steam/electron-cache.d.ts +11 -0
- package/dist/steam/electron-cache.js +105 -0
- package/dist/steam/electron-cache.js.map +1 -0
- package/dist/steam/fuses.d.ts +16 -0
- package/dist/steam/fuses.js +75 -0
- package/dist/steam/fuses.js.map +1 -0
- package/dist/steam/icon-files.d.ts +16 -0
- package/dist/steam/icon-files.js +70 -0
- package/dist/steam/icon-files.js.map +1 -0
- package/dist/steam/image-info.d.ts +16 -0
- package/dist/steam/image-info.js +89 -0
- package/dist/steam/image-info.js.map +1 -0
- package/dist/steam/launch-check.d.ts +12 -0
- package/dist/steam/launch-check.js +101 -0
- package/dist/steam/launch-check.js.map +1 -0
- package/dist/steam/media.d.ts +48 -0
- package/dist/steam/media.js +155 -0
- package/dist/steam/media.js.map +1 -0
- package/dist/steam/package-macos.d.ts +52 -0
- package/dist/steam/package-macos.js +268 -0
- package/dist/steam/package-macos.js.map +1 -0
- package/dist/steam/package-windows.d.ts +23 -0
- package/dist/steam/package-windows.js +83 -0
- package/dist/steam/package-windows.js.map +1 -0
- package/dist/steam/paths.d.ts +35 -0
- package/dist/steam/paths.js +44 -0
- package/dist/steam/paths.js.map +1 -0
- package/dist/steam/playtest-shots.d.ts +18 -0
- package/dist/steam/playtest-shots.js +83 -0
- package/dist/steam/playtest-shots.js.map +1 -0
- package/dist/steam/portal-recipes.d.ts +25 -0
- package/dist/steam/portal-recipes.js +61 -0
- package/dist/steam/portal-recipes.js.map +1 -0
- package/dist/steam/portal.d.ts +58 -0
- package/dist/steam/portal.js +340 -0
- package/dist/steam/portal.js.map +1 -0
- package/dist/steam/raster.d.ts +58 -0
- package/dist/steam/raster.js +285 -0
- package/dist/steam/raster.js.map +1 -0
- package/dist/steam/shell-files.d.ts +17 -0
- package/dist/steam/shell-files.js +268 -0
- package/dist/steam/shell-files.js.map +1 -0
- package/dist/steam/specs.d.ts +61 -0
- package/dist/steam/specs.js +103 -0
- package/dist/steam/specs.js.map +1 -0
- package/dist/steam/steampipe.d.ts +46 -0
- package/dist/steam/steampipe.js +170 -0
- package/dist/steam/steampipe.js.map +1 -0
- package/dist/steam/store-copy.d.ts +88 -0
- package/dist/steam/store-copy.js +214 -0
- package/dist/steam/store-copy.js.map +1 -0
- package/dist/steam/tags.d.ts +9 -0
- package/dist/steam/tags.js +52 -0
- package/dist/steam/tags.js.map +1 -0
- package/dist/steam/trailer.d.ts +34 -0
- package/dist/steam/trailer.js +141 -0
- package/dist/steam/trailer.js.map +1 -0
- package/dist/theme/kernel.d.ts +14 -0
- package/dist/theme/kernel.js +15 -0
- package/dist/theme/kernel.js.map +1 -0
- package/dist/theme/theme-io.js +11 -16
- package/dist/theme/theme-io.js.map +1 -1
- package/dist/vendor/hud-theme/catalog.js +71 -0
- package/dist/vendor/hud-theme/engine/hud/ThemeTokens.js +115 -0
- package/dist/{theme/theme-color-math.js → vendor/hud-theme/engine/hud/colorMath.js} +13 -14
- package/dist/vendor/hud-theme/engine/hud/decorations.js +179 -0
- package/dist/vendor/hud-theme/engine/hud/fonts.js +147 -0
- package/dist/vendor/hud-theme/engine/hud/presets.js +80 -0
- package/dist/vendor/hud-theme/engine/hud/resolveWorldTheme.js +66 -0
- package/dist/vendor/hud-theme/engine/hud/themes/bitmagic.js +29 -0
- package/dist/vendor/hud-theme/engine/hud/themes/nexus.js +69 -0
- package/dist/vendor/hud-theme/engine/hud/themes/racing.js +57 -0
- package/dist/vendor/hud-theme/engine/hud/themes/rift-raider.js +63 -0
- package/dist/vendor/hud-theme/engine/hud/themes/simulator.js +55 -0
- package/dist/vendor/hud-theme/engine/hud/themes/village-keep.js +108 -0
- package/dist/vendor/hud-theme/engine/hud/validateTheme.js +535 -0
- package/dist/vendor/hud-theme/index.js +26 -0
- package/dist/{theme/theme-merge.js → vendor/hud-theme/merge.js} +0 -1
- package/dist/{theme/theme-report.js → vendor/hud-theme/report.js} +8 -9
- package/dist/{theme/theme-stored.js → vendor/hud-theme/stored.js} +6 -9
- package/dist/{theme/theme-validate.js → vendor/hud-theme/validate-strict.js} +102 -164
- package/dist/verify/browser.d.ts +11 -0
- package/dist/verify/browser.js +222 -155
- package/dist/verify/browser.js.map +1 -1
- package/dist/verify/categories.d.ts +1 -1
- package/dist/verify/categories.js +1 -0
- package/dist/verify/categories.js.map +1 -1
- package/dist/verify/classify.d.ts +14 -2
- package/dist/verify/classify.js +23 -4
- package/dist/verify/classify.js.map +1 -1
- package/dist/verify/hud-theme.d.ts +19 -14
- package/dist/verify/hud-theme.js +23 -17
- package/dist/verify/hud-theme.js.map +1 -1
- package/dist/verify/mobile-parity.d.ts +1 -1
- package/dist/verify/mobile-parity.js +1 -1
- package/dist/verify/start.d.ts +3 -2
- package/dist/verify/start.js +1 -1
- package/dist/verify/start.js.map +1 -1
- package/package.json +8 -6
- package/dist/theme/hud-theme-catalog.d.ts +0 -235
- package/dist/theme/hud-theme-catalog.js +0 -389
- package/dist/theme/hud-theme-catalog.js.map +0 -1
- package/dist/theme/theme-color-math.d.ts +0 -21
- package/dist/theme/theme-color-math.js.map +0 -1
- package/dist/theme/theme-merge.d.ts +0 -36
- package/dist/theme/theme-merge.js.map +0 -1
- package/dist/theme/theme-report.d.ts +0 -28
- package/dist/theme/theme-report.js.map +0 -1
- package/dist/theme/theme-stored.d.ts +0 -21
- package/dist/theme/theme-stored.js.map +0 -1
- package/dist/theme/theme-validate.d.ts +0 -41
- package/dist/theme/theme-validate.js.map +0 -1
|
@@ -13,9 +13,12 @@
|
|
|
13
13
|
import * as fs from 'fs';
|
|
14
14
|
import * as path from 'path';
|
|
15
15
|
import { FALLBACK_MIME, MIME_TYPES } from './local-server.js';
|
|
16
|
+
import { CUSTOM_GROUP_DIR, STOREKIT_FILE_NAME } from './native-overrides.js';
|
|
17
|
+
import { STORE_BRIDGE_SWIFT } from './store-bridge.js';
|
|
16
18
|
export const TARGET_NAME = 'Game';
|
|
17
19
|
export const PAYLOAD_DIR_NAME = 'GamePayload';
|
|
18
20
|
export const URL_SCHEME = 'bmapp';
|
|
21
|
+
const DEBUG_ENTITLEMENTS = 'Debug.entitlements';
|
|
19
22
|
/** Fixed 24-hex-char pbxproj object ids. */
|
|
20
23
|
function uid(n) {
|
|
21
24
|
return `BA5EBA11000000000000${n.toString(16).toUpperCase().padStart(4, '0')}`;
|
|
@@ -47,10 +50,69 @@ const ID = {
|
|
|
47
50
|
buildSchemeHandler: uid(24),
|
|
48
51
|
buildAssets: uid(25),
|
|
49
52
|
buildPayload: uid(26),
|
|
53
|
+
refStoreBridge: uid(27),
|
|
54
|
+
buildStoreBridge: uid(28),
|
|
55
|
+
refNativeExtensions: uid(29),
|
|
56
|
+
buildNativeExtensions: uid(30),
|
|
57
|
+
customGroup: uid(31),
|
|
58
|
+
refStoreKit: uid(32),
|
|
50
59
|
};
|
|
51
|
-
|
|
60
|
+
/** The creator's own Swift files (ios/Sources/) take ids from 0x100 up, two per file. */
|
|
61
|
+
function customFileIds(index) {
|
|
62
|
+
return { ref: uid(0x100 + index * 2), build: uid(0x101 + index * 2) };
|
|
63
|
+
}
|
|
64
|
+
const NO_OVERRIDES = { swiftFiles: [], extensionClasses: [], hasStoreKitConfig: false };
|
|
65
|
+
function shellSources() {
|
|
66
|
+
return [
|
|
67
|
+
{ ref: ID.refAppDelegate, build: ID.buildAppDelegate, path: 'AppDelegate.swift', name: 'AppDelegate.swift' },
|
|
68
|
+
{ ref: ID.refViewController, build: ID.buildViewController, path: 'GameViewController.swift', name: 'GameViewController.swift' },
|
|
69
|
+
{ ref: ID.refSchemeHandler, build: ID.buildSchemeHandler, path: 'PayloadSchemeHandler.swift', name: 'PayloadSchemeHandler.swift' },
|
|
70
|
+
{ ref: ID.refStoreBridge, build: ID.buildStoreBridge, path: 'StoreBridge.swift', name: 'StoreBridge.swift' },
|
|
71
|
+
{ ref: ID.refNativeExtensions, build: ID.buildNativeExtensions, path: 'NativeExtensions.swift', name: 'NativeExtensions.swift' },
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
function customSources(overrides) {
|
|
75
|
+
return overrides.swiftFiles.map((rel, index) => ({
|
|
76
|
+
...customFileIds(index),
|
|
77
|
+
path: rel,
|
|
78
|
+
name: rel.slice(rel.lastIndexOf('/') + 1),
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
function pbxproj(config, overrides) {
|
|
82
|
+
const shell = shellSources();
|
|
83
|
+
const custom = customSources(overrides);
|
|
84
|
+
const all = [...shell, ...custom];
|
|
85
|
+
const buildFiles = all
|
|
86
|
+
.map((f) => `\t\t${f.build} /* ${f.name} in Sources */ = {isa = PBXBuildFile; fileRef = ${f.ref}; };`)
|
|
87
|
+
.join('\n');
|
|
88
|
+
const fileRefs = all
|
|
89
|
+
.map((f) => `\t\t${f.ref} /* ${f.name} */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "${f.path}"; sourceTree = "<group>"; };`)
|
|
90
|
+
.join('\n');
|
|
91
|
+
const groupChildren = (files) => files.map((f) => `\t\t\t\t${f.ref} /* ${f.name} */,`).join('\n');
|
|
92
|
+
const sourcePhaseFiles = all.map((f) => `\t\t\t\t${f.build} /* ${f.name} in Sources */,`).join('\n');
|
|
93
|
+
// The StoreKit catalogue is referenced (so Xcode shows it, and the scheme can point at it)
|
|
94
|
+
// but belongs to no build phase: it must never ship inside the app.
|
|
95
|
+
const storeKitRef = overrides.hasStoreKitConfig
|
|
96
|
+
? `\n\t\t${ID.refStoreKit} /* ${STOREKIT_FILE_NAME} */ = {isa = PBXFileReference; lastKnownFileType = text; path = ${STOREKIT_FILE_NAME}; sourceTree = "<group>"; };`
|
|
97
|
+
: '';
|
|
98
|
+
const storeKitChild = overrides.hasStoreKitConfig ? `\n\t\t\t\t${ID.refStoreKit} /* ${STOREKIT_FILE_NAME} */,` : '';
|
|
99
|
+
const customGroupChild = custom.length > 0 ? `\n\t\t\t\t${ID.customGroup} /* ${CUSTOM_GROUP_DIR} */,` : '';
|
|
100
|
+
const customGroup = custom.length > 0
|
|
101
|
+
? `
|
|
102
|
+
\t\t${ID.customGroup} /* ${CUSTOM_GROUP_DIR} */ = {
|
|
103
|
+
\t\t\tisa = PBXGroup;
|
|
104
|
+
\t\t\tchildren = (
|
|
105
|
+
${groupChildren(custom)}
|
|
106
|
+
\t\t\t);
|
|
107
|
+
\t\t\tpath = ${CUSTOM_GROUP_DIR};
|
|
108
|
+
\t\t\tsourceTree = "<group>";
|
|
109
|
+
\t\t};`
|
|
110
|
+
: '';
|
|
52
111
|
const team = config.teamId !== undefined ? `\n\t\t\t\tDEVELOPMENT_TEAM = "${config.teamId}";` : '';
|
|
53
|
-
|
|
112
|
+
// Debug only: StoreKit's local testing refuses an app that is not signed for development
|
|
113
|
+
// ("not installed for development"), and a run signed to run locally does not get
|
|
114
|
+
// get-task-allow on its own. Release — every archive and store upload — never carries it.
|
|
115
|
+
const targetSettings = (debug) => `\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;${debug ? `\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = ${DEBUG_ENTITLEMENTS};` : ''}
|
|
54
116
|
\t\t\t\tCODE_SIGN_STYLE = Automatic;
|
|
55
117
|
\t\t\t\tCURRENT_PROJECT_VERSION = ${config.buildNumber};${team}
|
|
56
118
|
\t\t\t\tGENERATE_INFOPLIST_FILE = NO;
|
|
@@ -75,18 +137,14 @@ function pbxproj(config) {
|
|
|
75
137
|
\tobjects = {
|
|
76
138
|
|
|
77
139
|
/* Begin PBXBuildFile section */
|
|
78
|
-
|
|
79
|
-
\t\t${ID.buildViewController} /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ${ID.refViewController}; };
|
|
80
|
-
\t\t${ID.buildSchemeHandler} /* PayloadSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = ${ID.refSchemeHandler}; };
|
|
140
|
+
${buildFiles}
|
|
81
141
|
\t\t${ID.buildAssets} /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ${ID.refAssets}; };
|
|
82
142
|
\t\t${ID.buildPayload} /* ${PAYLOAD_DIR_NAME} in Resources */ = {isa = PBXBuildFile; fileRef = ${ID.refPayload}; };
|
|
83
143
|
/* End PBXBuildFile section */
|
|
84
144
|
|
|
85
145
|
/* Begin PBXFileReference section */
|
|
86
146
|
\t\t${ID.productRef} /* app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${config.productName}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
87
|
-
|
|
88
|
-
\t\t${ID.refViewController} /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = "<group>"; };
|
|
89
|
-
\t\t${ID.refSchemeHandler} /* PayloadSchemeHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadSchemeHandler.swift; sourceTree = "<group>"; };
|
|
147
|
+
${fileRefs}${storeKitRef}
|
|
90
148
|
\t\t${ID.refInfoPlist} /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
91
149
|
\t\t${ID.refAssets} /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
|
92
150
|
\t\t${ID.refPayload} /* ${PAYLOAD_DIR_NAME} */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ${PAYLOAD_DIR_NAME}; sourceTree = "<group>"; };
|
|
@@ -106,8 +164,8 @@ function pbxproj(config) {
|
|
|
106
164
|
\t\t${ID.mainGroup} = {
|
|
107
165
|
\t\t\tisa = PBXGroup;
|
|
108
166
|
\t\t\tchildren = (
|
|
109
|
-
\t\t\t\t${ID.sourcesGroup} /* Sources
|
|
110
|
-
\t\t\t\t${ID.refInfoPlist} /* Info.plist
|
|
167
|
+
\t\t\t\t${ID.sourcesGroup} /* Sources */,${customGroupChild}
|
|
168
|
+
\t\t\t\t${ID.refInfoPlist} /* Info.plist */,${storeKitChild}
|
|
111
169
|
\t\t\t\t${ID.refAssets} /* Assets.xcassets */,
|
|
112
170
|
\t\t\t\t${ID.refPayload} /* ${PAYLOAD_DIR_NAME} */,
|
|
113
171
|
\t\t\t\t${ID.productsGroup} /* Products */,
|
|
@@ -117,13 +175,11 @@ function pbxproj(config) {
|
|
|
117
175
|
\t\t${ID.sourcesGroup} /* Sources */ = {
|
|
118
176
|
\t\t\tisa = PBXGroup;
|
|
119
177
|
\t\t\tchildren = (
|
|
120
|
-
|
|
121
|
-
\t\t\t\t${ID.refViewController} /* GameViewController.swift */,
|
|
122
|
-
\t\t\t\t${ID.refSchemeHandler} /* PayloadSchemeHandler.swift */,
|
|
178
|
+
${groupChildren(shell)}
|
|
123
179
|
\t\t\t);
|
|
124
180
|
\t\t\tpath = Sources;
|
|
125
181
|
\t\t\tsourceTree = "<group>";
|
|
126
|
-
\t\t}
|
|
182
|
+
\t\t};${customGroup}
|
|
127
183
|
\t\t${ID.productsGroup} /* Products */ = {
|
|
128
184
|
\t\t\tisa = PBXGroup;
|
|
129
185
|
\t\t\tchildren = (
|
|
@@ -196,9 +252,7 @@ function pbxproj(config) {
|
|
|
196
252
|
\t\t\tisa = PBXSourcesBuildPhase;
|
|
197
253
|
\t\t\tbuildActionMask = 2147483647;
|
|
198
254
|
\t\t\tfiles = (
|
|
199
|
-
|
|
200
|
-
\t\t\t\t${ID.buildViewController} /* GameViewController.swift in Sources */,
|
|
201
|
-
\t\t\t\t${ID.buildSchemeHandler} /* PayloadSchemeHandler.swift in Sources */,
|
|
255
|
+
${sourcePhaseFiles}
|
|
202
256
|
\t\t\t);
|
|
203
257
|
\t\t\trunOnlyForDeploymentPostprocessing = 0;
|
|
204
258
|
\t\t};
|
|
@@ -245,14 +299,14 @@ function pbxproj(config) {
|
|
|
245
299
|
\t\t${ID.targetDebug} /* Debug */ = {
|
|
246
300
|
\t\t\tisa = XCBuildConfiguration;
|
|
247
301
|
\t\t\tbuildSettings = {
|
|
248
|
-
${targetSettings}
|
|
302
|
+
${targetSettings(true)}
|
|
249
303
|
\t\t\t};
|
|
250
304
|
\t\t\tname = Debug;
|
|
251
305
|
\t\t};
|
|
252
306
|
\t\t${ID.targetRelease} /* Release */ = {
|
|
253
307
|
\t\t\tisa = XCBuildConfiguration;
|
|
254
308
|
\t\t\tbuildSettings = {
|
|
255
|
-
${targetSettings}
|
|
309
|
+
${targetSettings(false)}
|
|
256
310
|
\t\t\t};
|
|
257
311
|
\t\t\tname = Release;
|
|
258
312
|
\t\t};
|
|
@@ -283,7 +337,21 @@ ${targetSettings}
|
|
|
283
337
|
}
|
|
284
338
|
`;
|
|
285
339
|
}
|
|
286
|
-
|
|
340
|
+
/**
|
|
341
|
+
* The scheme. With a StoreKit catalogue, its Run action points at it, which is what makes
|
|
342
|
+
* purchases work when the app is run from Xcode with no App Store account, and it runs the Debug
|
|
343
|
+
* configuration, the one signed for development (see DEBUG_ENTITLEMENTS). The reference is
|
|
344
|
+
* relative to the xcodeproj's xcshareddata folder, so `../../` is the project folder the
|
|
345
|
+
* catalogue is copied into. It only ever applies to a run started from Xcode, never to an
|
|
346
|
+
* archive, so a store build cannot pick it up.
|
|
347
|
+
*/
|
|
348
|
+
function xcscheme(config, overrides) {
|
|
349
|
+
const storeKit = overrides.hasStoreKitConfig
|
|
350
|
+
? `
|
|
351
|
+
<StoreKitConfigurationFileReference
|
|
352
|
+
identifier = "../../${STOREKIT_FILE_NAME}">
|
|
353
|
+
</StoreKitConfigurationFileReference>`
|
|
354
|
+
: '';
|
|
287
355
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
288
356
|
<Scheme LastUpgradeVersion="1500" version="1.7">
|
|
289
357
|
<BuildAction parallelizeBuildables="YES" buildImplicitDependencies="YES">
|
|
@@ -299,7 +367,7 @@ function xcscheme(config) {
|
|
|
299
367
|
</BuildActionEntry>
|
|
300
368
|
</BuildActionEntries>
|
|
301
369
|
</BuildAction>
|
|
302
|
-
<LaunchAction buildConfiguration="Release" selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle="0" useCustomWorkingDirectory="NO" ignoresPersistentStateOnLaunch="NO" debugDocumentVersioning="YES" debugServiceExtension="internal" allowLocationSimulation="YES">
|
|
370
|
+
<LaunchAction buildConfiguration="${overrides.hasStoreKitConfig ? 'Debug' : 'Release'}" selectedDebuggerIdentifier="Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier="Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle="0" useCustomWorkingDirectory="NO" ignoresPersistentStateOnLaunch="NO" debugDocumentVersioning="YES" debugServiceExtension="internal" allowLocationSimulation="YES">
|
|
303
371
|
<BuildableProductRunnable runnableDebuggingMode="0">
|
|
304
372
|
<BuildableReference
|
|
305
373
|
BuildableIdentifier="primary"
|
|
@@ -308,7 +376,7 @@ function xcscheme(config) {
|
|
|
308
376
|
BlueprintName="${TARGET_NAME}"
|
|
309
377
|
ReferencedContainer="container:App.xcodeproj">
|
|
310
378
|
</BuildableReference>
|
|
311
|
-
</BuildableProductRunnable
|
|
379
|
+
</BuildableProductRunnable>${storeKit}
|
|
312
380
|
</LaunchAction>
|
|
313
381
|
<ArchiveAction buildConfiguration="Release" revealArchiveInOrganizer="YES">
|
|
314
382
|
</ArchiveAction>
|
|
@@ -417,6 +485,8 @@ import WebKit
|
|
|
417
485
|
/// origin, which file:// would not give them.
|
|
418
486
|
class GameViewController: UIViewController, WKNavigationDelegate {
|
|
419
487
|
private var webView: WKWebView?
|
|
488
|
+
private let storeBridge = StoreBridge()
|
|
489
|
+
private let extensions = NativeExtensions.make()
|
|
420
490
|
|
|
421
491
|
override func viewDidLoad() {
|
|
422
492
|
super.viewDidLoad()
|
|
@@ -426,6 +496,13 @@ class GameViewController: UIViewController, WKNavigationDelegate {
|
|
|
426
496
|
configuration.setURLSchemeHandler(PayloadSchemeHandler(), forURLScheme: PayloadSchemeHandler.scheme)
|
|
427
497
|
configuration.allowsInlineMediaPlayback = true
|
|
428
498
|
configuration.mediaTypesRequiringUserActionForPlayback = []
|
|
499
|
+
// App Store purchases: the engine's store finds this handler and talks StoreKit through it.
|
|
500
|
+
configuration.userContentController.addScriptMessageHandler(
|
|
501
|
+
storeBridge, contentWorld: .page, name: StoreBridge.handlerName
|
|
502
|
+
)
|
|
503
|
+
for nativeExtension in extensions {
|
|
504
|
+
nativeExtension.configure(configuration)
|
|
505
|
+
}
|
|
429
506
|
|
|
430
507
|
let webView = WKWebView(frame: view.bounds, configuration: configuration)
|
|
431
508
|
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
@@ -442,6 +519,11 @@ class GameViewController: UIViewController, WKNavigationDelegate {
|
|
|
442
519
|
#endif
|
|
443
520
|
view.addSubview(webView)
|
|
444
521
|
self.webView = webView
|
|
522
|
+
storeBridge.webView = webView
|
|
523
|
+
storeBridge.start()
|
|
524
|
+
for nativeExtension in extensions {
|
|
525
|
+
nativeExtension.attach(to: webView, in: self)
|
|
526
|
+
}
|
|
445
527
|
|
|
446
528
|
// ?platform=mobile is the engine's own boot override: it wins over every device probe,
|
|
447
529
|
// so even a desktop-primary game boots with touch controls and mobile budgets.
|
|
@@ -491,6 +573,42 @@ class GameViewController: UIViewController, WKNavigationDelegate {
|
|
|
491
573
|
}
|
|
492
574
|
}
|
|
493
575
|
`;
|
|
576
|
+
/**
|
|
577
|
+
* The hook creator Swift (ios/Sources/) plugs into, and the list of adopters this build found.
|
|
578
|
+
* Generated because Swift has no static registration: the CLI scans the creator's files for
|
|
579
|
+
* classes adopting the protocol (native-overrides.ts) and lists them here. Each needs an init
|
|
580
|
+
* that takes no arguments; one that lacks it fails the build with Swift's own error, naming it.
|
|
581
|
+
*/
|
|
582
|
+
export function nativeExtensionsSwift(classNames) {
|
|
583
|
+
const list = classNames.map((name) => ` ${name}(),`).join('\n');
|
|
584
|
+
return `import UIKit
|
|
585
|
+
import WebKit
|
|
586
|
+
|
|
587
|
+
/// Native code of the creator's own (the project's ios/Sources/ folder) joins the game view
|
|
588
|
+
/// through this protocol. Adopt it in a class with a no-argument init and bitmagic ios build
|
|
589
|
+
/// installs it. Both methods are optional.
|
|
590
|
+
protocol BitmagicNativeExtension: AnyObject {
|
|
591
|
+
/// Before the web view exists: add script message handlers and user scripts here.
|
|
592
|
+
func configure(_ configuration: WKWebViewConfiguration)
|
|
593
|
+
/// Once the web view exists and is on screen.
|
|
594
|
+
func attach(to webView: WKWebView, in controller: UIViewController)
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
extension BitmagicNativeExtension {
|
|
598
|
+
func configure(_ configuration: WKWebViewConfiguration) {}
|
|
599
|
+
func attach(to webView: WKWebView, in controller: UIViewController) {}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/// Generated by bitmagic ios build from the classes found in ios/Sources/.
|
|
603
|
+
enum NativeExtensions {
|
|
604
|
+
static func make() -> [BitmagicNativeExtension] {
|
|
605
|
+
return [
|
|
606
|
+
${list}
|
|
607
|
+
]
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
`;
|
|
611
|
+
}
|
|
494
612
|
/** The Swift MIME dictionary, generated from the SAME table the validation server uses. */
|
|
495
613
|
function swiftMimeEntries() {
|
|
496
614
|
return [...MIME_TYPES]
|
|
@@ -560,6 +678,15 @@ ${swiftMimeEntries()}
|
|
|
560
678
|
}
|
|
561
679
|
`;
|
|
562
680
|
}
|
|
681
|
+
const DEBUG_ENTITLEMENTS_PLIST = `<?xml version="1.0" encoding="UTF-8"?>
|
|
682
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
683
|
+
<plist version="1.0">
|
|
684
|
+
<dict>
|
|
685
|
+
\t<key>get-task-allow</key>
|
|
686
|
+
\t<true/>
|
|
687
|
+
</dict>
|
|
688
|
+
</plist>
|
|
689
|
+
`;
|
|
563
690
|
const XCASSETS_ROOT_CONTENTS = `{
|
|
564
691
|
"info" : {
|
|
565
692
|
"author" : "xcode",
|
|
@@ -604,21 +731,25 @@ const LAUNCH_BACKGROUND_CONTENTS = `{
|
|
|
604
731
|
}
|
|
605
732
|
`;
|
|
606
733
|
/**
|
|
607
|
-
* Write the whole project (everything except the payload contents
|
|
608
|
-
* their own producers). Existing files are overwritten — the
|
|
734
|
+
* Write the whole project (everything except the payload contents, the icon PNG and the
|
|
735
|
+
* creator's own files, which have their own producers). Existing files are overwritten — the
|
|
736
|
+
* project is CLI-owned. `overrides` describes what `copyNativeOverrides` puts in it.
|
|
609
737
|
*/
|
|
610
|
-
export function stampXcodeProject(projectDir, config) {
|
|
738
|
+
export function stampXcodeProject(projectDir, config, overrides = NO_OVERRIDES) {
|
|
611
739
|
const write = (relPath, content) => {
|
|
612
740
|
const target = path.join(projectDir, ...relPath.split('/'));
|
|
613
741
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
614
742
|
fs.writeFileSync(target, content);
|
|
615
743
|
};
|
|
616
|
-
write('App.xcodeproj/project.pbxproj', pbxproj(config));
|
|
617
|
-
write(`App.xcodeproj/xcshareddata/xcschemes/${TARGET_NAME}.xcscheme`, xcscheme(config));
|
|
744
|
+
write('App.xcodeproj/project.pbxproj', pbxproj(config, overrides));
|
|
745
|
+
write(`App.xcodeproj/xcshareddata/xcschemes/${TARGET_NAME}.xcscheme`, xcscheme(config, overrides));
|
|
618
746
|
write('Info.plist', infoPlist(config));
|
|
747
|
+
write(DEBUG_ENTITLEMENTS, DEBUG_ENTITLEMENTS_PLIST);
|
|
619
748
|
write('Sources/AppDelegate.swift', APP_DELEGATE_SWIFT);
|
|
620
749
|
write('Sources/GameViewController.swift', GAME_VIEW_CONTROLLER_SWIFT);
|
|
621
750
|
write('Sources/PayloadSchemeHandler.swift', payloadSchemeHandlerSwift());
|
|
751
|
+
write('Sources/StoreBridge.swift', STORE_BRIDGE_SWIFT);
|
|
752
|
+
write('Sources/NativeExtensions.swift', nativeExtensionsSwift(overrides.extensionClasses));
|
|
622
753
|
write('Assets.xcassets/Contents.json', XCASSETS_ROOT_CONTENTS);
|
|
623
754
|
write('Assets.xcassets/AppIcon.appiconset/Contents.json', APPICON_CONTENTS);
|
|
624
755
|
write('Assets.xcassets/LaunchBackground.colorset/Contents.json', LAUNCH_BACKGROUND_CONTENTS);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcode-template.js","sourceRoot":"","sources":["../../src/ios/xcode-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"xcode-template.js","sourceRoot":"","sources":["../../src/ios/xcode-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ export interface CollectedUrls {
|
|
|
12
12
|
}
|
|
13
13
|
/** Walk any JSON value, collecting remote-URL strings outside the deny-listed fields. */
|
|
14
14
|
export declare function deepWalkUrls(value: unknown, out: Set<string>): void;
|
|
15
|
-
/**
|
|
15
|
+
/** Asset URLs hard-coded in the compiled game code, over the pro project's dist. */
|
|
16
16
|
export declare function scanCompiledCodeUrls(compiledCode: string): Set<string>;
|
|
17
17
|
/** All compiled game JS under dist/src/work, concatenated — for reference scans. */
|
|
18
18
|
export declare function readCompiledGameCode(root: string): string;
|
|
@@ -50,10 +50,18 @@ export function deepWalkUrls(value, out) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* File types a game's own code loads by literal URL: models, voxels, images, audio, video. A sky
|
|
55
|
+
* the game swaps per world (`skyUrl: 'https://…/image.webp'` in a theme table) is as much an asset
|
|
56
|
+
* as a GLB, and the record pass only sees what the first scene loads — so a later world's sky
|
|
57
|
+
* would otherwise ship missing. Data endpoints (`.json`, API paths) are deliberately not here:
|
|
58
|
+
* a backend response is not an asset to snapshot.
|
|
59
|
+
*/
|
|
60
|
+
const CODE_ASSET_URL = /https?:\/\/[^"'`\s)\\]+\.(?:glb|gltf|vxl|vwld|png|webp|jpe?g|gif|svg|ktx2|hdr|mp3|ogg|opus|wav|m4a|mp4|webm)\b/g;
|
|
61
|
+
/** Asset URLs hard-coded in the compiled game code, over the pro project's dist. */
|
|
54
62
|
export function scanCompiledCodeUrls(compiledCode) {
|
|
55
63
|
const urls = new Set();
|
|
56
|
-
for (const match of compiledCode.match(
|
|
64
|
+
for (const match of compiledCode.match(CODE_ASSET_URL) ?? []) {
|
|
57
65
|
urls.add(match);
|
|
58
66
|
}
|
|
59
67
|
return urls;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect-urls.js","sourceRoot":"","sources":["../../src/package/collect-urls.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,yFAAyF;AACzF,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,eAAe;IACf,cAAc;IACd,sBAAsB;IACtB,oBAAoB;IACpB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;IACpB,WAAW;CACZ,CAAC,CAAC;AAeH,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,GAAgB;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,WAAW,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAClD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACnC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"collect-urls.js","sourceRoot":"","sources":["../../src/package/collect-urls.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { RendererChoice } from '../browser-gl.js';
|
|
2
|
+
import type { Output } from '../output.js';
|
|
3
|
+
import type { ProjectContext } from '../project/context.js';
|
|
4
|
+
import type { MobileOrientation } from '../project/platform-declaration.js';
|
|
5
|
+
import { type TransformOptions } from './transform.js';
|
|
6
|
+
/**
|
|
7
|
+
* The bundle to package: the self-contained `--single-file` build, reused when it was built from
|
|
8
|
+
* this exact source and rebuilt otherwise. Never the default build, which loads three.js, Rapier
|
|
9
|
+
* and the other CDN packages from esm.sh at runtime and so cannot boot without a network.
|
|
10
|
+
* `json` sends the compiler's and bundler's output to stderr, keeping stdout for the result.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ensureSelfContainedBundle(context: ProjectContext, output: Output, json: boolean): string;
|
|
13
|
+
export interface OfflinePayloadOptions {
|
|
14
|
+
root: string;
|
|
15
|
+
html: string;
|
|
16
|
+
payloadDir: string;
|
|
17
|
+
/** Downloaded-asset cache, keyed by URL hash. */
|
|
18
|
+
cacheDir: string;
|
|
19
|
+
/** One subdirectory per validation pass lands here. */
|
|
20
|
+
checkDir: string;
|
|
21
|
+
distribution: TransformOptions['distribution'];
|
|
22
|
+
platform: 'mobile' | 'desktop';
|
|
23
|
+
orientation?: MobileOrientation;
|
|
24
|
+
renderers: readonly RendererChoice[];
|
|
25
|
+
skipValidation: boolean;
|
|
26
|
+
/** How the validation browser is described in progress lines, e.g. "iPhone viewport". */
|
|
27
|
+
deviceLabel: string;
|
|
28
|
+
output: Output;
|
|
29
|
+
}
|
|
30
|
+
export interface OfflinePayloadResult {
|
|
31
|
+
assetMap: Map<string, string>;
|
|
32
|
+
/** Only ever true after every pass ran clean. */
|
|
33
|
+
offlineValidated: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare function buildOfflinePayload(options: OfflinePayloadOptions): Promise<OfflinePayloadResult>;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The game as a packaged app ships it: the self-contained bundle, every asset it loads mirrored
|
|
3
|
+
* into a `vendor/` tree beside it, the page rewritten to load them from there — and PROOF that it
|
|
4
|
+
* boots with no network, on each renderer the target runs. Shared by `bitmagic ios build` and
|
|
5
|
+
* `bitmagic steam build`; the steps are §4c-f of docs/ios-export-design.md.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { CliError } from '../errors.js';
|
|
10
|
+
import { buildBundlePaths, isCurrentBundle, runBuild } from '../publish/bundle.js';
|
|
11
|
+
import { computeFingerprint } from '../publish/fingerprint.js';
|
|
12
|
+
import { collectUrls } from './collect-urls.js';
|
|
13
|
+
import { runPackagedCheck } from './packaged-check.js';
|
|
14
|
+
import { transformBundleHtml } from './transform.js';
|
|
15
|
+
import { vendorBasePathFor, vendorUrls } from './vendor.js';
|
|
16
|
+
/**
|
|
17
|
+
* The bundle to package: the self-contained `--single-file` build, reused when it was built from
|
|
18
|
+
* this exact source and rebuilt otherwise. Never the default build, which loads three.js, Rapier
|
|
19
|
+
* and the other CDN packages from esm.sh at runtime and so cannot boot without a network.
|
|
20
|
+
* `json` sends the compiler's and bundler's output to stderr, keeping stdout for the result.
|
|
21
|
+
*/
|
|
22
|
+
export function ensureSelfContainedBundle(context, output, json) {
|
|
23
|
+
const fingerprint = computeFingerprint(context.root);
|
|
24
|
+
if (isCurrentBundle(context.root, fingerprint, true)) {
|
|
25
|
+
output.info('Reusing the existing self-contained bundle (source unchanged).');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
output.info('Building the self-contained game bundle…');
|
|
29
|
+
runBuild(context.root, context.metadata.engineVersion, { singleFile: true, stderr: json });
|
|
30
|
+
}
|
|
31
|
+
const { htmlPath } = buildBundlePaths(context.root);
|
|
32
|
+
try {
|
|
33
|
+
return fs.readFileSync(htmlPath, 'utf-8');
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
throw new CliError(`The built bundle at ${htmlPath} is missing. Run \`bitmagic build\`, then package again.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const RENDERER_LABELS = { webgpu: 'WebGPU', webgl: 'WebGL' };
|
|
40
|
+
/**
|
|
41
|
+
* Stage the payload afresh: vendored files land here, then the transformed page. The
|
|
42
|
+
* sw-cache-buster stub rides along for a project still on an engine that registered it on
|
|
43
|
+
* localhost, so the validation passes find the file; current engines register no worker.
|
|
44
|
+
*/
|
|
45
|
+
function stagePayload(payloadDir, root) {
|
|
46
|
+
fs.rmSync(payloadDir, { recursive: true, force: true });
|
|
47
|
+
fs.mkdirSync(payloadDir, { recursive: true });
|
|
48
|
+
const stub = path.join(root, 'sw-cache-buster.js');
|
|
49
|
+
if (fs.existsSync(stub))
|
|
50
|
+
fs.copyFileSync(stub, path.join(payloadDir, 'sw-cache-buster.js'));
|
|
51
|
+
}
|
|
52
|
+
export async function buildOfflinePayload(options) {
|
|
53
|
+
const { output } = options;
|
|
54
|
+
const collected = await collectUrls(options.root);
|
|
55
|
+
for (const note of collected.notes)
|
|
56
|
+
output.info(note);
|
|
57
|
+
stagePayload(options.payloadDir, options.root);
|
|
58
|
+
/** Mirror `urls` into the payload, narrating cache reuse and anything that would not fetch. */
|
|
59
|
+
const vendor = async (urls) => {
|
|
60
|
+
const result = await vendorUrls({ urls, cacheDir: options.cacheDir, payloadDir: options.payloadDir });
|
|
61
|
+
if (result.cacheHits > 0)
|
|
62
|
+
output.info(` ${result.cacheHits} from the local cache.`);
|
|
63
|
+
for (const failure of result.failures) {
|
|
64
|
+
// A warning, not a refusal: a stale URL the game never loads must not block packaging, and
|
|
65
|
+
// the offline validation below is the gate that catches one the game DOES load.
|
|
66
|
+
output.info(` warning: could not vendor ${failure.url} (${failure.error})`);
|
|
67
|
+
}
|
|
68
|
+
return result.entries;
|
|
69
|
+
};
|
|
70
|
+
output.info(`Vendoring ${collected.urls.size} assets into the app…`);
|
|
71
|
+
const assetMap = await vendor(collected.urls);
|
|
72
|
+
const baseRewrites = new Map();
|
|
73
|
+
for (const base of collected.bases) {
|
|
74
|
+
const rel = vendorBasePathFor(base);
|
|
75
|
+
if (rel !== null)
|
|
76
|
+
baseRewrites.set(base, rel);
|
|
77
|
+
}
|
|
78
|
+
const indexPath = path.join(options.payloadDir, 'index.html');
|
|
79
|
+
const writeTransformed = () => {
|
|
80
|
+
const transformed = transformBundleHtml({ html: options.html, distribution: options.distribution, assetMap, baseRewrites });
|
|
81
|
+
fs.writeFileSync(indexPath, transformed.html);
|
|
82
|
+
return transformed.rewrites;
|
|
83
|
+
};
|
|
84
|
+
const rewrites = writeTransformed();
|
|
85
|
+
output.info(`Asset map: ${assetMap.size} entries, ${rewrites} URL literals rewritten.`);
|
|
86
|
+
if (options.skipValidation) {
|
|
87
|
+
output.info('Offline validation skipped — this app is NOT confirmed to work without a network.');
|
|
88
|
+
return { assetMap, offlineValidated: false };
|
|
89
|
+
}
|
|
90
|
+
// Record passes: play the game the way the app will, once per renderer, and vendor whatever
|
|
91
|
+
// either one still fetched — the empirical net under the static collection (§4e of the design).
|
|
92
|
+
const recordedMisses = new Set();
|
|
93
|
+
for (const renderer of options.renderers) {
|
|
94
|
+
output.info(`Recording runtime asset requests (headless Chrome, ${options.deviceLabel}, ${RENDERER_LABELS[renderer]})…`);
|
|
95
|
+
const recorded = await runPackagedCheck({
|
|
96
|
+
payloadDir: options.payloadDir,
|
|
97
|
+
artifactDir: path.join(options.checkDir, `record-${renderer}`),
|
|
98
|
+
mode: 'record',
|
|
99
|
+
renderer,
|
|
100
|
+
platform: options.platform,
|
|
101
|
+
...(options.orientation !== undefined ? { orientation: options.orientation } : {}),
|
|
102
|
+
});
|
|
103
|
+
for (const url of recorded.misses)
|
|
104
|
+
recordedMisses.add(url);
|
|
105
|
+
}
|
|
106
|
+
if (recordedMisses.size > 0) {
|
|
107
|
+
output.info(` ${recordedMisses.size} runtime-discovered asset(s) — vendoring those too.`);
|
|
108
|
+
for (const [url, rel] of await vendor(recordedMisses))
|
|
109
|
+
assetMap.set(url, rel);
|
|
110
|
+
writeTransformed();
|
|
111
|
+
}
|
|
112
|
+
// Every offline pass runs even when an earlier one fails, so one error lists every problem.
|
|
113
|
+
const problems = [];
|
|
114
|
+
const failedArtifacts = [];
|
|
115
|
+
for (const renderer of options.renderers) {
|
|
116
|
+
const label = RENDERER_LABELS[renderer];
|
|
117
|
+
output.info(`Validating the app works offline (${label})…`);
|
|
118
|
+
const artifactDir = path.join(options.checkDir, `offline-${renderer}`);
|
|
119
|
+
const offline = await runPackagedCheck({
|
|
120
|
+
payloadDir: options.payloadDir,
|
|
121
|
+
artifactDir,
|
|
122
|
+
mode: 'offline',
|
|
123
|
+
renderer,
|
|
124
|
+
platform: options.platform,
|
|
125
|
+
...(options.orientation !== undefined ? { orientation: options.orientation } : {}),
|
|
126
|
+
});
|
|
127
|
+
for (const warning of offline.result.warnings)
|
|
128
|
+
output.info(` warning (${label}): ${warning}`);
|
|
129
|
+
if (!offline.result.ok || offline.misses.length > 0) {
|
|
130
|
+
problems.push(...offline.result.failures.map((failure) => ` ✗ ${label}: ${failure}`), ...offline.misses.map((url) => ` ✗ ${label}: still requests ${url}`));
|
|
131
|
+
failedArtifacts.push(artifactDir);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (failedArtifacts.length > 0) {
|
|
135
|
+
throw new CliError('The packaged game does not work without a network:\n'
|
|
136
|
+
+ problems.join('\n')
|
|
137
|
+
+ `\nArtifacts: ${failedArtifacts.join(', ')}`, 5);
|
|
138
|
+
}
|
|
139
|
+
output.info(`Offline validation passed on ${options.renderers.map((r) => RENDERER_LABELS[r]).join(' and ')} — the game renders with no network.`);
|
|
140
|
+
return { assetMap, offlineValidated: true };
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=offline-payload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offline-payload.js","sourceRoot":"","sources":["../../src/package/offline-payload.ts"],"names":[],"mappings":"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"}
|