@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
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.bitmagic/steam/art.json` — which pictures the store kit is cut from, and how each capsule is
|
|
3
|
+
* laid out: where the crop sits, where the logo goes and how big it is, how much the art is
|
|
4
|
+
* darkened behind it.
|
|
5
|
+
*
|
|
6
|
+
* The agent is the art director here. `steam art render` draws every asset from this file, the
|
|
7
|
+
* agent LOOKS at the results, edits a layout and renders again — so every knob is a plain number
|
|
8
|
+
* with a default that suits a typical key art, and nothing about a layout is hidden in code.
|
|
9
|
+
*
|
|
10
|
+
* Pure: reading, defaulting and composing HTML. Rendering lives in art-render.ts.
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { readJsonFile, writeJsonAtomic } from '../atomic-json.js';
|
|
15
|
+
import { CliError } from '../errors.js';
|
|
16
|
+
import { STORE_IMAGE_SPECS } from './specs.js';
|
|
17
|
+
export const SOURCE_NAMES = ['wide', 'tall', 'hero', 'logo', 'icon'];
|
|
18
|
+
/** Where each source lands when a candidate is chosen, relative to `.bitmagic/steam/`. */
|
|
19
|
+
export const DEFAULT_SOURCE_FILES = {
|
|
20
|
+
wide: 'art/keyart-wide.png',
|
|
21
|
+
tall: 'art/keyart-tall.png',
|
|
22
|
+
hero: 'art/keyart-hero.png',
|
|
23
|
+
logo: 'art/logo.png',
|
|
24
|
+
icon: 'art/icon.png',
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Defaults per asset, tuned for a key art with its subject near the centre. The small capsule's
|
|
28
|
+
* logo nearly fills it because Valve asks for exactly that (it is shown as small as 120x45); the
|
|
29
|
+
* tall capsules put the logo where the art is usually emptiest — sky above, ground below.
|
|
30
|
+
*/
|
|
31
|
+
export const DEFAULT_LAYOUTS = {
|
|
32
|
+
header_capsule: {
|
|
33
|
+
focus: [0.5, 0.45], zoom: 1, logo: { x: 0.5, y: 0.5, width: 0.62, maxHeight: 0.62 },
|
|
34
|
+
scrim: 'radial', scrimStrength: 0.35, dim: 0, blur: 0,
|
|
35
|
+
},
|
|
36
|
+
small_capsule: {
|
|
37
|
+
focus: [0.5, 0.5], zoom: 1, logo: { x: 0.5, y: 0.5, width: 0.9, maxHeight: 0.84 },
|
|
38
|
+
scrim: 'radial', scrimStrength: 0.45, dim: 0.1, blur: 0,
|
|
39
|
+
},
|
|
40
|
+
main_capsule: {
|
|
41
|
+
focus: [0.5, 0.5], zoom: 1, logo: { x: 0.5, y: 0.8, width: 0.5, maxHeight: 0.34 },
|
|
42
|
+
scrim: 'bottom', scrimStrength: 0.55, dim: 0, blur: 0,
|
|
43
|
+
},
|
|
44
|
+
vertical_capsule: {
|
|
45
|
+
focus: [0.5, 0.45], zoom: 1, logo: { x: 0.5, y: 0.16, width: 0.86, maxHeight: 0.26 },
|
|
46
|
+
scrim: 'top', scrimStrength: 0.45, dim: 0, blur: 0,
|
|
47
|
+
},
|
|
48
|
+
page_background: {
|
|
49
|
+
focus: [0.5, 0.5], zoom: 1.04, logo: null,
|
|
50
|
+
scrim: 'none', scrimStrength: 0, dim: 0.45, blur: 3,
|
|
51
|
+
},
|
|
52
|
+
library_capsule: {
|
|
53
|
+
focus: [0.5, 0.45], zoom: 1, logo: { x: 0.5, y: 0.84, width: 0.86, maxHeight: 0.24 },
|
|
54
|
+
scrim: 'bottom', scrimStrength: 0.55, dim: 0, blur: 0,
|
|
55
|
+
},
|
|
56
|
+
library_header: {
|
|
57
|
+
focus: [0.5, 0.45], zoom: 1, logo: { x: 0.5, y: 0.5, width: 0.62, maxHeight: 0.62 },
|
|
58
|
+
scrim: 'radial', scrimStrength: 0.35, dim: 0, blur: 0,
|
|
59
|
+
},
|
|
60
|
+
library_hero: {
|
|
61
|
+
focus: [0.5, 0.5], zoom: 1, logo: null,
|
|
62
|
+
scrim: 'none', scrimStrength: 0, dim: 0, blur: 0,
|
|
63
|
+
},
|
|
64
|
+
app_icon: {
|
|
65
|
+
focus: [0.5, 0.5], zoom: 1, logo: null,
|
|
66
|
+
scrim: 'none', scrimStrength: 0, dim: 0, blur: 0,
|
|
67
|
+
},
|
|
68
|
+
shortcut_icon: {
|
|
69
|
+
focus: [0.5, 0.5], zoom: 1, logo: null,
|
|
70
|
+
scrim: 'none', scrimStrength: 0, dim: 0, blur: 0,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
function num(value, fallback, min, max) {
|
|
74
|
+
return typeof value === 'number' && Number.isFinite(value) ? Math.min(max, Math.max(min, value)) : fallback;
|
|
75
|
+
}
|
|
76
|
+
function readLogo(value, fallback) {
|
|
77
|
+
if (value === null)
|
|
78
|
+
return null;
|
|
79
|
+
if (typeof value !== 'object')
|
|
80
|
+
return fallback;
|
|
81
|
+
const record = value;
|
|
82
|
+
const base = fallback ?? { x: 0.5, y: 0.5, width: 0.6, maxHeight: 0.5 };
|
|
83
|
+
return {
|
|
84
|
+
x: num(record.x, base.x, 0, 1),
|
|
85
|
+
y: num(record.y, base.y, 0, 1),
|
|
86
|
+
width: num(record.width, base.width, 0.05, 1),
|
|
87
|
+
maxHeight: num(record.maxHeight, base.maxHeight, 0.05, 1),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const SCRIMS = ['none', 'bottom', 'top', 'left', 'right', 'radial'];
|
|
91
|
+
const ART_SOURCES = ['wide', 'tall', 'hero', 'icon'];
|
|
92
|
+
/** One asset's layout: the file's fields over the default, each clamped to a sane range. */
|
|
93
|
+
export function readLayout(id, value) {
|
|
94
|
+
const base = DEFAULT_LAYOUTS[id];
|
|
95
|
+
if (base === undefined)
|
|
96
|
+
throw new CliError(`art.json has a layout for "${id}", which is not a Steam asset.`);
|
|
97
|
+
if (typeof value !== 'object' || value === null)
|
|
98
|
+
return base;
|
|
99
|
+
const record = value;
|
|
100
|
+
const focus = Array.isArray(record.focus) && record.focus.length === 2
|
|
101
|
+
? [num(record.focus[0], base.focus[0], 0, 1), num(record.focus[1], base.focus[1], 0, 1)]
|
|
102
|
+
: base.focus;
|
|
103
|
+
const source = typeof record.source === 'string' && ART_SOURCES.includes(record.source)
|
|
104
|
+
? record.source
|
|
105
|
+
: base.source;
|
|
106
|
+
return {
|
|
107
|
+
...(source !== undefined ? { source } : {}),
|
|
108
|
+
focus,
|
|
109
|
+
zoom: num(record.zoom, base.zoom, 1, 4),
|
|
110
|
+
logo: 'logo' in record ? readLogo(record.logo, base.logo) : base.logo,
|
|
111
|
+
scrim: typeof record.scrim === 'string' && SCRIMS.includes(record.scrim) ? record.scrim : base.scrim,
|
|
112
|
+
scrimStrength: num(record.scrimStrength, base.scrimStrength, 0, 1),
|
|
113
|
+
dim: num(record.dim, base.dim, 0, 1),
|
|
114
|
+
blur: num(record.blur, base.blur, 0, 40),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export function readArtConfig(file) {
|
|
118
|
+
const parsed = readJsonFile(file);
|
|
119
|
+
const record = typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
120
|
+
const sourcesRaw = typeof record.sources === 'object' && record.sources !== null
|
|
121
|
+
? record.sources
|
|
122
|
+
: {};
|
|
123
|
+
const sources = {};
|
|
124
|
+
for (const name of SOURCE_NAMES) {
|
|
125
|
+
const value = sourcesRaw[name];
|
|
126
|
+
if (typeof value === 'string' && value.trim() !== '')
|
|
127
|
+
sources[name] = value.trim();
|
|
128
|
+
}
|
|
129
|
+
const layoutsRaw = typeof record.layouts === 'object' && record.layouts !== null
|
|
130
|
+
? record.layouts
|
|
131
|
+
: {};
|
|
132
|
+
const layouts = {};
|
|
133
|
+
for (const spec of STORE_IMAGE_SPECS) {
|
|
134
|
+
if (spec.logo === 'only')
|
|
135
|
+
continue;
|
|
136
|
+
layouts[spec.id] = readLayout(spec.id, layoutsRaw[spec.id]);
|
|
137
|
+
}
|
|
138
|
+
for (const id of Object.keys(layoutsRaw)) {
|
|
139
|
+
if (layouts[id] === undefined)
|
|
140
|
+
throw new CliError(`art.json has a layout for "${id}", which is not a Steam asset.`);
|
|
141
|
+
}
|
|
142
|
+
return { sources, layouts };
|
|
143
|
+
}
|
|
144
|
+
/** Write the file with every layout spelled out, so the agent sees every knob it can turn. */
|
|
145
|
+
export function writeArtConfig(file, config) {
|
|
146
|
+
writeJsonAtomic(file, config);
|
|
147
|
+
}
|
|
148
|
+
/** Record `relPath` as the `name` source, keeping everything else in the file. */
|
|
149
|
+
export function setArtSource(file, name, relPath) {
|
|
150
|
+
const config = readArtConfig(file);
|
|
151
|
+
config.sources[name] = relPath;
|
|
152
|
+
writeArtConfig(file, config);
|
|
153
|
+
return config;
|
|
154
|
+
}
|
|
155
|
+
/** The absolute path of a source, or null when art.json names none or the file is gone. */
|
|
156
|
+
export function resolveSource(steamDir, config, name) {
|
|
157
|
+
const rel = config.sources[name];
|
|
158
|
+
if (rel === undefined)
|
|
159
|
+
return null;
|
|
160
|
+
const abs = path.resolve(steamDir, rel);
|
|
161
|
+
return fs.existsSync(abs) ? abs : null;
|
|
162
|
+
}
|
|
163
|
+
/** Where the logo lands on a `width`x`height` canvas, keeping its aspect inside both limits. */
|
|
164
|
+
export function placeLogo(placement, canvas, logo) {
|
|
165
|
+
const aspect = logo.width / logo.height;
|
|
166
|
+
let w = placement.width * canvas.width;
|
|
167
|
+
let h = w / aspect;
|
|
168
|
+
const maxH = placement.maxHeight * canvas.height;
|
|
169
|
+
if (h > maxH) {
|
|
170
|
+
h = maxH;
|
|
171
|
+
w = h * aspect;
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
left: Math.round(placement.x * canvas.width - w / 2),
|
|
175
|
+
top: Math.round(placement.y * canvas.height - h / 2),
|
|
176
|
+
width: Math.round(w),
|
|
177
|
+
height: Math.round(h),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function scrimCss(layout, logo, canvas) {
|
|
181
|
+
const s = layout.scrimStrength;
|
|
182
|
+
const dark = `rgba(0,0,0,${s.toFixed(3)})`;
|
|
183
|
+
switch (layout.scrim) {
|
|
184
|
+
case 'bottom': return `linear-gradient(to top, ${dark} 0%, rgba(0,0,0,0) 60%)`;
|
|
185
|
+
case 'top': return `linear-gradient(to bottom, ${dark} 0%, rgba(0,0,0,0) 60%)`;
|
|
186
|
+
case 'left': return `linear-gradient(to right, ${dark} 0%, rgba(0,0,0,0) 60%)`;
|
|
187
|
+
case 'right': return `linear-gradient(to left, ${dark} 0%, rgba(0,0,0,0) 60%)`;
|
|
188
|
+
case 'radial': {
|
|
189
|
+
const cx = logo ? ((logo.left + logo.width / 2) / canvas.width) * 100 : 50;
|
|
190
|
+
const cy = logo ? ((logo.top + logo.height / 2) / canvas.height) * 100 : 50;
|
|
191
|
+
return `radial-gradient(ellipse at ${cx.toFixed(1)}% ${cy.toFixed(1)}%, ${dark} 0%, rgba(0,0,0,0) 65%)`;
|
|
192
|
+
}
|
|
193
|
+
case 'none': return 'none';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The page that draws one asset. Images arrive as data URLs; `logo` is null for assets that must
|
|
198
|
+
* carry none (the hero, the background, the icons).
|
|
199
|
+
*/
|
|
200
|
+
export function assetHtml(options) {
|
|
201
|
+
const { spec, layout } = options;
|
|
202
|
+
const canvas = { width: spec.width, height: spec.height };
|
|
203
|
+
const placed = layout.logo !== null && options.logo !== null
|
|
204
|
+
? placeLogo(layout.logo, canvas, options.logo)
|
|
205
|
+
: null;
|
|
206
|
+
const fx = (layout.focus[0] * 100).toFixed(2);
|
|
207
|
+
const fy = (layout.focus[1] * 100).toFixed(2);
|
|
208
|
+
// Blur pulls transparent black in from outside the box; a hair of extra zoom hides that rim.
|
|
209
|
+
const zoom = layout.blur > 0 ? Math.max(layout.zoom, 1 + (layout.blur * 4) / Math.min(spec.width, spec.height)) : layout.zoom;
|
|
210
|
+
const shadow = Math.max(2, Math.round(Math.min(spec.width, spec.height) / 60));
|
|
211
|
+
return `<!doctype html><html><head><meta charset="utf-8"><style>
|
|
212
|
+
html,body{margin:0;padding:0;width:${spec.width}px;height:${spec.height}px;overflow:hidden;background:#000}
|
|
213
|
+
.art{position:absolute;inset:0;background:url("${options.artUrl}") ${fx}% ${fy}% / cover no-repeat;transform:scale(${zoom.toFixed(4)});transform-origin:${fx}% ${fy}%;${layout.blur > 0 ? `filter:blur(${layout.blur}px);` : ''}}
|
|
214
|
+
.dim{position:absolute;inset:0;background:rgba(0,0,0,${layout.dim.toFixed(3)})}
|
|
215
|
+
.scrim{position:absolute;inset:0;background:${scrimCss(layout, placed, canvas)}}
|
|
216
|
+
.logo{position:absolute;filter:drop-shadow(0 ${Math.round(shadow / 2)}px ${shadow}px rgba(0,0,0,0.55))}
|
|
217
|
+
</style></head><body>
|
|
218
|
+
<div class="art"></div>
|
|
219
|
+
${layout.dim > 0 ? '<div class="dim"></div>' : ''}
|
|
220
|
+
${layout.scrim !== 'none' ? '<div class="scrim"></div>' : ''}
|
|
221
|
+
${placed !== null && options.logo !== null
|
|
222
|
+
? `<img class="logo" src="${options.logo.url}" style="left:${placed.left}px;top:${placed.top}px;width:${placed.width}px;height:${placed.height}px">`
|
|
223
|
+
: ''}
|
|
224
|
+
</body></html>`;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The library logo: the logo alone, transparent, scaled to touch the 1280x720 box on one side —
|
|
228
|
+
* "1280 px wide and/or 720 px tall", in Valve's words — with its own aspect kept.
|
|
229
|
+
*/
|
|
230
|
+
export function libraryLogoSize(logo, box) {
|
|
231
|
+
const aspect = logo.width / logo.height;
|
|
232
|
+
if (aspect >= box.width / box.height) {
|
|
233
|
+
return { width: box.width, height: Math.max(1, Math.round(box.width / aspect)) };
|
|
234
|
+
}
|
|
235
|
+
return { width: Math.max(1, Math.round(box.height * aspect)), height: box.height };
|
|
236
|
+
}
|
|
237
|
+
export function logoOnlyHtml(logoUrl, size) {
|
|
238
|
+
return `<!doctype html><html><head><meta charset="utf-8"><style>
|
|
239
|
+
html,body{margin:0;padding:0;width:${size.width}px;height:${size.height}px;overflow:hidden;background:transparent}
|
|
240
|
+
img{display:block;width:${size.width}px;height:${size.height}px}
|
|
241
|
+
</style></head><body><img src="${logoUrl}"></body></html>`;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=art.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"art.js","sourceRoot":"","sources":["../../src/steam/art.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SteamPaths } from './paths.js';
|
|
2
|
+
import { type SteamImageSpec } from './specs.js';
|
|
3
|
+
export interface KitFinding {
|
|
4
|
+
level: 'error' | 'warning';
|
|
5
|
+
area: 'copy' | 'images' | 'screenshots' | 'trailer';
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
export interface KitCheck {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
findings: KitFinding[];
|
|
11
|
+
screenshots: string[];
|
|
12
|
+
trailer: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** One image against its spec. Pure apart from the read. */
|
|
15
|
+
export declare function checkImage(spec: SteamImageSpec, file: string): string[];
|
|
16
|
+
export declare function listScreenshots(paths: SteamPaths): string[];
|
|
17
|
+
export declare function findTrailer(paths: SteamPaths): string | null;
|
|
18
|
+
export declare function checkKit(options: {
|
|
19
|
+
paths: SteamPaths;
|
|
20
|
+
knownTags: ReadonlySet<string> | null;
|
|
21
|
+
}): Promise<KitCheck>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bitmagic steam check` — everything Steamworks will ask for, held to Valve's rules before anyone
|
|
3
|
+
* uploads it: the store copy, every image at its exact size, the screenshots, the trailer.
|
|
4
|
+
* Errors are what blocks a review; warnings are what a reviewer or a player would notice.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { readImageInfo } from './image-info.js';
|
|
9
|
+
import { probeVideo } from './media.js';
|
|
10
|
+
import { LIBRARY_LOGO_BOX, MAC_ICNS_FILE, MIN_SCREENSHOTS, SCREENSHOT_HEIGHT, SCREENSHOT_WIDTH, SHORTCUT_ICO_FILE, STORE_IMAGE_SPECS, } from './specs.js';
|
|
11
|
+
import { checkStoreCopy, readStoreCopy } from './store-copy.js';
|
|
12
|
+
import { trailerProblems } from './trailer.js';
|
|
13
|
+
/** One image against its spec. Pure apart from the read. */
|
|
14
|
+
export function checkImage(spec, file) {
|
|
15
|
+
if (!fs.existsSync(file))
|
|
16
|
+
return [spec.required ? 'missing' : 'missing (optional)'];
|
|
17
|
+
const info = readImageInfo(fs.readFileSync(file));
|
|
18
|
+
if (info === null)
|
|
19
|
+
return ['not a PNG or JPEG file'];
|
|
20
|
+
const problems = [];
|
|
21
|
+
if (info.format !== spec.format)
|
|
22
|
+
problems.push(`is ${info.format}, Steam wants ${spec.format}`);
|
|
23
|
+
if (spec.logo === 'only') {
|
|
24
|
+
const touchesBox = (info.width === LIBRARY_LOGO_BOX.width && info.height <= LIBRARY_LOGO_BOX.height)
|
|
25
|
+
|| (info.height === LIBRARY_LOGO_BOX.height && info.width <= LIBRARY_LOGO_BOX.width);
|
|
26
|
+
if (!touchesBox)
|
|
27
|
+
problems.push(`is ${info.width}x${info.height}; it must be 1280 wide and/or 720 tall`);
|
|
28
|
+
if (!info.alpha)
|
|
29
|
+
problems.push('has no transparency');
|
|
30
|
+
}
|
|
31
|
+
else if (info.width !== spec.width || info.height !== spec.height) {
|
|
32
|
+
problems.push(`is ${info.width}x${info.height}, Steam wants exactly ${spec.width}x${spec.height}`);
|
|
33
|
+
}
|
|
34
|
+
return problems;
|
|
35
|
+
}
|
|
36
|
+
export function listScreenshots(paths) {
|
|
37
|
+
if (!fs.existsSync(paths.screenshotsDir))
|
|
38
|
+
return [];
|
|
39
|
+
return fs.readdirSync(paths.screenshotsDir)
|
|
40
|
+
.filter((name) => /\.(png|jpe?g)$/i.test(name))
|
|
41
|
+
.sort()
|
|
42
|
+
.map((name) => path.join(paths.screenshotsDir, name));
|
|
43
|
+
}
|
|
44
|
+
export function findTrailer(paths) {
|
|
45
|
+
if (!fs.existsSync(paths.trailerDir))
|
|
46
|
+
return null;
|
|
47
|
+
const videos = fs.readdirSync(paths.trailerDir)
|
|
48
|
+
.filter((name) => /\.(mp4|mov|wmv)$/i.test(name))
|
|
49
|
+
.map((name) => path.join(paths.trailerDir, name))
|
|
50
|
+
.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
51
|
+
return videos[0] ?? null;
|
|
52
|
+
}
|
|
53
|
+
export async function checkKit(options) {
|
|
54
|
+
const { paths } = options;
|
|
55
|
+
const findings = [];
|
|
56
|
+
const copy = readStoreCopy(paths.storePath);
|
|
57
|
+
if (copy === null) {
|
|
58
|
+
findings.push({ level: 'error', area: 'copy', message: `No store copy at ${paths.storePath} — run \`bitmagic steam init\`.` });
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
for (const finding of checkStoreCopy(copy, options.knownTags)) {
|
|
62
|
+
findings.push({ level: finding.level, area: 'copy', message: `${finding.field}: ${finding.message}` });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const spec of STORE_IMAGE_SPECS) {
|
|
66
|
+
for (const problem of checkImage(spec, path.join(paths.kitDir, spec.file))) {
|
|
67
|
+
const optional = problem === 'missing (optional)';
|
|
68
|
+
findings.push({
|
|
69
|
+
level: optional ? 'warning' : 'error',
|
|
70
|
+
area: 'images',
|
|
71
|
+
message: `${spec.file} ${problem}${problem.startsWith('missing') ? ' — `bitmagic steam art render`' : ''}`,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const rel of [SHORTCUT_ICO_FILE, MAC_ICNS_FILE]) {
|
|
76
|
+
if (!fs.existsSync(path.join(paths.kitDir, rel))) {
|
|
77
|
+
findings.push({ level: 'error', area: 'images', message: `${rel} missing — \`bitmagic steam art render\` writes it from the icon art.` });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const screenshots = listScreenshots(paths);
|
|
81
|
+
if (screenshots.length < MIN_SCREENSHOTS) {
|
|
82
|
+
findings.push({
|
|
83
|
+
level: 'error',
|
|
84
|
+
area: 'screenshots',
|
|
85
|
+
message: `${screenshots.length} screenshot(s); Steam needs at least ${MIN_SCREENSHOTS} — \`bitmagic steam screenshots\`.`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
for (const file of screenshots) {
|
|
89
|
+
const info = readImageInfo(fs.readFileSync(file));
|
|
90
|
+
if (info === null) {
|
|
91
|
+
findings.push({ level: 'error', area: 'screenshots', message: `${path.basename(file)} is not an image.` });
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (info.width < SCREENSHOT_WIDTH || info.height < SCREENSHOT_HEIGHT || Math.abs(info.width / info.height - 16 / 9) > 0.01) {
|
|
95
|
+
findings.push({
|
|
96
|
+
level: 'error',
|
|
97
|
+
area: 'screenshots',
|
|
98
|
+
message: `${path.basename(file)} is ${info.width}x${info.height}; Steam wants 16:9 at 1920x1080 or larger.`,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const trailer = findTrailer(paths);
|
|
103
|
+
if (trailer === null) {
|
|
104
|
+
findings.push({ level: 'error', area: 'trailer', message: 'No trailer. Steam requires one before release — `bitmagic steam trailer`.' });
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
for (const problem of trailerProblems(await probeVideo(trailer), trailer)) {
|
|
108
|
+
findings.push({ level: problem.level, area: 'trailer', message: `${path.basename(trailer)}: ${problem.message}` });
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { ok: !findings.some((finding) => finding.level === 'error'), findings, screenshots, trailer };
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/steam/check.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GAElB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAe/C,4DAA4D;AAC5D,MAAM,UAAU,UAAU,CAAC,IAAoB,EAAE,IAAY;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAClD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,iBAAiB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAChG,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,gBAAgB,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC;eAC/F,CAAC,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACvF,IAAI,CAAC,UAAU;YAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,wCAAwC,CAAC,CAAC;QACxG,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACxD,CAAC;SAAM,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACpE,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,yBAAyB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,CAAC;IACpD,OAAO,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC9C,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAiB;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;SAC5C,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;SAChD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACnE,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAG9B;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC1B,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAElC,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,KAAK,CAAC,SAAS,iCAAiC,EAAE,CAAC,CAAC;IACjI,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;QACrC,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC3E,MAAM,QAAQ,GAAG,OAAO,KAAK,oBAAoB,CAAC;YAClD,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;gBACrC,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,EAAE;aAC3G,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,uEAAuE,EAAE,CAAC,CAAC;QAC5I,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,WAAW,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACzC,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,GAAG,WAAW,CAAC,MAAM,wCAAwC,eAAe,oCAAoC;SAC1H,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;YAC3G,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,GAAG,gBAAgB,IAAI,IAAI,CAAC,MAAM,GAAG,iBAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;YAC3H,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,4CAA4C;aAC5G,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,2EAA2E,EAAE,CAAC,CAAC;IAC3I,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,OAAO,IAAI,eAAe,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;YAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACrH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACxG,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface SteamConfigFile {
|
|
2
|
+
/** The app id Steamworks gave the game when the app credit was spent. */
|
|
3
|
+
appId?: number;
|
|
4
|
+
/** Depot ids. Steamworks creates `appId + 1` with the app; the second depot is added by hand. */
|
|
5
|
+
depots?: {
|
|
6
|
+
windows?: number;
|
|
7
|
+
macos?: number;
|
|
8
|
+
};
|
|
9
|
+
/** The Steam LOGIN NAME steamcmd uploads with. Never a password. */
|
|
10
|
+
account?: string;
|
|
11
|
+
/** Overrides game.json's gameName for the executable, window title and store copy. */
|
|
12
|
+
displayName?: string;
|
|
13
|
+
/** Shown in the .exe's version resource and the .app's CFBundleShortVersionString. */
|
|
14
|
+
version?: string;
|
|
15
|
+
/** The macOS bundle identifier; `ai.bitmagic.game.<gameid>` unless set. */
|
|
16
|
+
bundleId?: string;
|
|
17
|
+
/** codesign identity, when the keychain holds more than one Developer ID Application. */
|
|
18
|
+
macIdentity?: string;
|
|
19
|
+
/** A `notarytool store-credentials` keychain profile to notarize with, instead of an API key. */
|
|
20
|
+
notaryProfile?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SteamAppConfig {
|
|
23
|
+
appId?: number;
|
|
24
|
+
windowsDepot?: number;
|
|
25
|
+
macosDepot?: number;
|
|
26
|
+
account?: string;
|
|
27
|
+
/** Any unicode — the window title, the store name. */
|
|
28
|
+
displayName: string;
|
|
29
|
+
/** ASCII-safe filename for `<Game>.exe` and `<Game>.app`. */
|
|
30
|
+
productName: string;
|
|
31
|
+
version: string;
|
|
32
|
+
/** yyyyMMddHHmm, UTC — CFBundleVersion and the .exe build field; always increases. */
|
|
33
|
+
buildNumber: string;
|
|
34
|
+
bundleId: string;
|
|
35
|
+
macIdentity?: string;
|
|
36
|
+
notaryProfile?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The executable's filename: ASCII letters, digits, space and dash, accents folded rather than
|
|
40
|
+
* dropped, at most 40 characters, never a Windows device name, never ending in a dot or dash.
|
|
41
|
+
* The same rules as the Creator's Steam export (game-play-agent name-sanitizer.ts), so a game
|
|
42
|
+
* exported from either lane ships under the same filename.
|
|
43
|
+
*/
|
|
44
|
+
export declare function sanitizeExecutableName(name: string, gameId: string): string;
|
|
45
|
+
export declare function readSteamConfigFile(configPath: string): SteamConfigFile;
|
|
46
|
+
/** Merge `patch` into the file on disk and write it back. Returns the merged file. */
|
|
47
|
+
export declare function updateSteamConfigFile(configPath: string, patch: SteamConfigFile): SteamConfigFile;
|
|
48
|
+
/** Parse a Steam numeric id from a flag, naming the flag when it is not one. */
|
|
49
|
+
export declare function parseSteamId(flag: string, value: string | undefined): number | undefined;
|
|
50
|
+
export declare function resolveSteamConfig(options: {
|
|
51
|
+
root: string;
|
|
52
|
+
gameId: string;
|
|
53
|
+
configPath: string;
|
|
54
|
+
now?: Date;
|
|
55
|
+
}): SteamAppConfig;
|
|
56
|
+
/** The app id, or a refusal that says where to get one. */
|
|
57
|
+
export declare function requireAppId(config: SteamAppConfig): number;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The game's identity on Steam: `.bitmagic/steam.json`.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is an id Steamworks assigned or a name the creator chose, so it is the one file
|
|
5
|
+
* in the lane worth keeping — `steam init` writes it and every later command reads it. It never
|
|
6
|
+
* holds a password: steamcmd caches its own login (see steampipe.ts), and the builder account's
|
|
7
|
+
* NAME is all this file needs to ask it for that cached login.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import { writeJsonAtomic, readJsonFile } from '../atomic-json.js';
|
|
12
|
+
import { CliError } from '../errors.js';
|
|
13
|
+
import { readGameName } from '../project/game-name.js';
|
|
14
|
+
import { buildNumberNow, deriveBundleId } from '../ios/app-config.js';
|
|
15
|
+
const WINDOWS_RESERVED = new Set([
|
|
16
|
+
'CON', 'PRN', 'AUX', 'NUL',
|
|
17
|
+
'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
|
|
18
|
+
'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* The executable's filename: ASCII letters, digits, space and dash, accents folded rather than
|
|
22
|
+
* dropped, at most 40 characters, never a Windows device name, never ending in a dot or dash.
|
|
23
|
+
* The same rules as the Creator's Steam export (game-play-agent name-sanitizer.ts), so a game
|
|
24
|
+
* exported from either lane ships under the same filename.
|
|
25
|
+
*/
|
|
26
|
+
export function sanitizeExecutableName(name, gameId) {
|
|
27
|
+
const cleaned = name
|
|
28
|
+
.normalize('NFKD')
|
|
29
|
+
.replace(/[̀-ͯ]/g, '')
|
|
30
|
+
.replace(/[^A-Za-z0-9 -]/g, ' ')
|
|
31
|
+
.replace(/\s+/g, ' ')
|
|
32
|
+
.trim()
|
|
33
|
+
.slice(0, 40)
|
|
34
|
+
.trim()
|
|
35
|
+
.replace(/[.-]+$/, '')
|
|
36
|
+
.trim();
|
|
37
|
+
if (cleaned.length === 0 || WINDOWS_RESERVED.has(cleaned.toUpperCase())) {
|
|
38
|
+
return `Bitmagic Game ${gameId.replace(/[^A-Za-z0-9-]/g, '').slice(0, 16)}`.trim();
|
|
39
|
+
}
|
|
40
|
+
return cleaned;
|
|
41
|
+
}
|
|
42
|
+
function positiveInt(value) {
|
|
43
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0 ? value : undefined;
|
|
44
|
+
}
|
|
45
|
+
function nonEmpty(value) {
|
|
46
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
47
|
+
}
|
|
48
|
+
export function readSteamConfigFile(configPath) {
|
|
49
|
+
const parsed = readJsonFile(configPath);
|
|
50
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
|
|
51
|
+
return {};
|
|
52
|
+
const record = parsed;
|
|
53
|
+
const depotsRaw = record.depots;
|
|
54
|
+
const depots = typeof depotsRaw === 'object' && depotsRaw !== null
|
|
55
|
+
? {
|
|
56
|
+
windows: positiveInt(depotsRaw.windows),
|
|
57
|
+
macos: positiveInt(depotsRaw.macos),
|
|
58
|
+
}
|
|
59
|
+
: undefined;
|
|
60
|
+
return {
|
|
61
|
+
appId: positiveInt(record.appId),
|
|
62
|
+
...(depots !== undefined ? { depots } : {}),
|
|
63
|
+
account: nonEmpty(record.account),
|
|
64
|
+
displayName: nonEmpty(record.displayName),
|
|
65
|
+
version: nonEmpty(record.version),
|
|
66
|
+
bundleId: nonEmpty(record.bundleId),
|
|
67
|
+
macIdentity: nonEmpty(record.macIdentity),
|
|
68
|
+
notaryProfile: nonEmpty(record.notaryProfile),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Drop undefined leaves so the written file holds only what was actually set. */
|
|
72
|
+
function compact(file) {
|
|
73
|
+
const out = {};
|
|
74
|
+
if (file.appId !== undefined)
|
|
75
|
+
out.appId = file.appId;
|
|
76
|
+
if (file.depots?.windows !== undefined || file.depots?.macos !== undefined) {
|
|
77
|
+
out.depots = {
|
|
78
|
+
...(file.depots.windows !== undefined ? { windows: file.depots.windows } : {}),
|
|
79
|
+
...(file.depots.macos !== undefined ? { macos: file.depots.macos } : {}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
if (file.account !== undefined)
|
|
83
|
+
out.account = file.account;
|
|
84
|
+
if (file.displayName !== undefined)
|
|
85
|
+
out.displayName = file.displayName;
|
|
86
|
+
if (file.version !== undefined)
|
|
87
|
+
out.version = file.version;
|
|
88
|
+
if (file.bundleId !== undefined)
|
|
89
|
+
out.bundleId = file.bundleId;
|
|
90
|
+
if (file.macIdentity !== undefined)
|
|
91
|
+
out.macIdentity = file.macIdentity;
|
|
92
|
+
if (file.notaryProfile !== undefined)
|
|
93
|
+
out.notaryProfile = file.notaryProfile;
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
/** Merge `patch` into the file on disk and write it back. Returns the merged file. */
|
|
97
|
+
export function updateSteamConfigFile(configPath, patch) {
|
|
98
|
+
const current = readSteamConfigFile(configPath);
|
|
99
|
+
const merged = {
|
|
100
|
+
...current,
|
|
101
|
+
...Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined)),
|
|
102
|
+
depots: { ...current.depots, ...Object.fromEntries(Object.entries(patch.depots ?? {}).filter(([, v]) => v !== undefined)) },
|
|
103
|
+
};
|
|
104
|
+
const out = compact(merged);
|
|
105
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
106
|
+
writeJsonAtomic(configPath, out);
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
/** Parse a Steam numeric id from a flag, naming the flag when it is not one. */
|
|
110
|
+
export function parseSteamId(flag, value) {
|
|
111
|
+
if (value === undefined)
|
|
112
|
+
return undefined;
|
|
113
|
+
const trimmed = value.trim();
|
|
114
|
+
if (!/^\d{1,10}$/.test(trimmed) || Number(trimmed) <= 0) {
|
|
115
|
+
throw new CliError(`--${flag} must be a positive number as Steamworks shows it (got ${JSON.stringify(value)}).`);
|
|
116
|
+
}
|
|
117
|
+
return Number(trimmed);
|
|
118
|
+
}
|
|
119
|
+
export function resolveSteamConfig(options) {
|
|
120
|
+
const file = readSteamConfigFile(options.configPath);
|
|
121
|
+
const displayName = file.displayName ?? readGameName(options.root);
|
|
122
|
+
return {
|
|
123
|
+
...(file.appId !== undefined ? { appId: file.appId } : {}),
|
|
124
|
+
...(file.depots?.windows !== undefined ? { windowsDepot: file.depots.windows } : {}),
|
|
125
|
+
...(file.depots?.macos !== undefined ? { macosDepot: file.depots.macos } : {}),
|
|
126
|
+
...(file.account !== undefined ? { account: file.account } : {}),
|
|
127
|
+
displayName,
|
|
128
|
+
productName: sanitizeExecutableName(displayName, options.gameId),
|
|
129
|
+
version: file.version ?? '1.0.0',
|
|
130
|
+
buildNumber: buildNumberNow(options.now),
|
|
131
|
+
bundleId: file.bundleId ?? deriveBundleId(options.gameId),
|
|
132
|
+
...(file.macIdentity !== undefined ? { macIdentity: file.macIdentity } : {}),
|
|
133
|
+
...(file.notaryProfile !== undefined ? { notaryProfile: file.notaryProfile } : {}),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** The app id, or a refusal that says where to get one. */
|
|
137
|
+
export function requireAppId(config) {
|
|
138
|
+
if (config.appId === undefined) {
|
|
139
|
+
throw new CliError('No Steam app id on file. The creator buys an app credit in Steamworks (the $100 Steam Direct '
|
|
140
|
+
+ 'fee) and creates the app; then run `bitmagic steam init --app-id <id>` with the id '
|
|
141
|
+
+ 'Steamworks shows on the app\'s page.', 3);
|
|
142
|
+
}
|
|
143
|
+
return config.appId;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/steam/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAsCtE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;IAC1B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACtE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CACvE,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,MAAc;IACjE,MAAM,OAAO,GAAG,IAAI;SACjB,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,IAAI,EAAE;SACN,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,IAAI,EAAE,CAAC;IACV,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACxE,OAAO,iBAAiB,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IACrF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/F,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACtF,MAAM,MAAM,GAAG,MAAiC,CAAC;IACjD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,MAAM,MAAM,GAAG,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,IAAI;QAChE,CAAC,CAAC;YACA,OAAO,EAAE,WAAW,CAAE,SAAqC,CAAC,OAAO,CAAC;YACpE,KAAK,EAAE,WAAW,CAAE,SAAqC,CAAC,KAAK,CAAC;SACjE;QACD,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;QAChC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;QACjC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC;QACzC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;QACjC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;QACnC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC;QACzC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,SAAS,OAAO,CAAC,IAAqB;IACpC,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACrD,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3E,GAAG,CAAC,MAAM,GAAG;YACX,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC3D,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACvE,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;QAAE,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC3D,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC9D,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACvE,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;QAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IAC7E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,qBAAqB,CAAC,UAAkB,EAAE,KAAsB;IAC9E,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,MAAM,GAAoB;QAC9B,GAAG,OAAO;QACV,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QACvF,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,EAAE;KAC5H,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,eAAe,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACjC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAyB;IAClE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,QAAQ,CAAC,KAAK,IAAI,0DAA0D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnH,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAKlC;IACC,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO;QACL,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,WAAW;QACX,WAAW,EAAE,sBAAsB,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC;QAChE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,OAAO;QAChC,WAAW,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC;QACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC;QACzD,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnF,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,QAAQ,CAChB,+FAA+F;cAC3F,qFAAqF;cACrF,sCAAsC,EAC1C,CAAC,CACF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const ELECTRON_VERSION = "44.5.1";
|
|
2
|
+
export type ShellPlatform = 'win32-x64' | 'darwin-x64' | 'darwin-arm64';
|
|
3
|
+
export declare function electronCacheDir(): string;
|
|
4
|
+
/** `SHASUMS256.txt` → file name → sha256. Pure. */
|
|
5
|
+
export declare function parseShaSums(text: string): Map<string, string>;
|
|
6
|
+
/**
|
|
7
|
+
* The extracted release for `platform`, downloading and verifying it first if needed. macOS
|
|
8
|
+
* releases are unpacked with `ditto`, the only extractor that keeps a framework's symlinks as
|
|
9
|
+
* symlinks — which is also why the macOS build needs a Mac.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ensureElectronShell(platform: ShellPlatform, log: (message: string) => void): Promise<string>;
|