@makefully/adaptfully 2.1.0 → 3.0.1

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 CHANGED
@@ -1,430 +1,517 @@
1
- # Adaptfully
2
-
3
- Platform abstraction and Wrapfully deploy client for Makefully games.
4
-
5
- - **Adaptfully runtime** — shared auth and platform services via `adaptfully.register()` / `adaptfully.get()`
6
- - **Wrapfully deploy** — zip-and-post CLI for building desktop, mobile, and Steam packages
7
-
8
- ## Install
9
-
10
- ```bash
11
- npm install @makefully/adaptfully
12
- ```
13
-
14
- Maintainers: see [PUBLISHING.md](PUBLISHING.md) for npm trusted publishing setup.
15
-
16
- ## Adaptfully runtime
17
-
18
- Games register platform services before load and retrieve them in-game. Auth is selected at **build time** by the game's build tooling — the game never chooses Google vs Steam directly.
19
-
20
- ```javascript
21
- // Set by the build (before account.js loads):
22
- adaptfully.register('auth', adaptfully.auth.Google);
23
-
24
- // In-game:
25
- var platform = adaptfully.get('auth');
26
- platform.login(function (result) { /* ... */ });
27
- ```
28
-
29
- ### Auth plugins
30
-
31
- | Plugin | Registration | Used for |
32
- |--------|--------------|----------|
33
- | `adaptfully.auth.Google` | `adaptfully.register('auth', adaptfully.auth.Google)` | Web, Android, iOS |
34
- | `adaptfully.auth.Steam` | `adaptfully.register('auth', adaptfully.auth.Steam)` | Steam / Electron |
35
- | `adaptfully.auth.Dev` | `adaptfully.register('auth', adaptfully.auth.Dev)` | Local dev (test user) |
36
-
37
- Games can register shared dependencies before auth:
38
-
39
- ```javascript
40
- adaptfully.register('storage', myStorage);
41
- adaptfully.register('config', {
42
- googleClientId: '...',
43
- googleTokenKey: 'mygame_google_token',
44
- apiBase: 'https://api.example.com/',
45
- });
46
- ```
47
-
48
- ### Node build helpers
49
-
50
- ```javascript
51
- import {
52
- getAuthScriptsForChannel,
53
- authRegistrationScript,
54
- filterIncludesForBuildChannel,
55
- extScriptsForBuildChannel,
56
- } from '@makefully/adaptfully';
57
- ```
58
-
59
- `getAuthScriptsForChannel('web')` returns ordered runtime script paths. `authRegistrationScript('steam')` returns the inline registration snippet for that channel.
60
-
61
- ---
62
-
63
- ## Wrapfully deploy
64
-
65
- Zips your web build and configuration, POSTs them to a Wrapfully build server, and saves the platform build artifacts it returns to `./output/`.
66
-
67
- ## Quick start
68
-
69
- 1. Build your web app into a deploy folder (default: `./deploy/`, must include `index.html`).
70
- 2. Add build configuration to `package.json` (see [Configuration](#configuration)).
71
- 3. Add icons and any signing credentials under `./assets/meta/`.
72
- 4. Deploy to your build server:
73
-
74
- ```bash
75
- npx wrapfully-deploy android http://build.example.com:9630/
76
- ```
77
-
78
- Build artifacts are written to `./output/`.
79
-
80
- ## Usage
81
-
82
- Run from your project root:
83
-
84
- ```bash
85
- npx wrapfully-deploy [builder] [server] [mode]
86
- ```
87
-
88
- | Argument | Default | Description |
89
- |----------|---------|-------------|
90
- | `builder` | `all` | Build target (see [Builders](#builders)). **Must be a valid builder name** — `all` is not a valid endpoint; always pass a platform. |
91
- | `server` | see below | Base URL of the build server |
92
- | `mode` | `extract` | `extract` unpacks the response zip into `./output/`; any other value saves `./output/{name}-{version}-{builder}.zip` |
93
-
94
- Examples:
95
-
96
- ```bash
97
- # Android release build
98
- npx wrapfully-deploy android http://build.example.com:9630/
99
-
100
- # Mac build using server from environment variable
101
- export WRAPFULLY_SERVER=http://build.example.com:9630/
102
- npx wrapfully-deploy mac
103
-
104
- # Save the response as a zip instead of extracting
105
- npx wrapfully-deploy win http://build.example.com:9630/ zip
106
- ```
107
-
108
- Add scripts to your project's `package.json`:
109
-
110
- ```json
111
- {
112
- "scripts": {
113
- "deploy:android": "wrapfully-deploy android",
114
- "deploy:mac": "wrapfully-deploy mac"
115
- }
116
- }
117
- ```
118
-
119
- Set `WRAPFULLY_SERVER` or a `server` field in `wrapfully.json` so scripts do not need the address on every invocation.
120
-
121
- ### Server address
122
-
123
- The server URL is resolved in this order:
124
-
125
- 1. CLI argument
126
- 2. `WRAPFULLY_SERVER` environment variable
127
- 3. `server` field in `wrapfully.json`
128
- 4. `http://localhost:9630/`
129
-
130
- Keep server addresses and credentials out of version control — use environment variables or a gitignored `wrapfully.json`.
131
-
132
- ## What gets sent
133
-
134
- The client POSTs a zip stream to:
135
-
136
- ```
137
- {server}{builder}/{name}-{version}
138
- ```
139
-
140
- For example, a project named `mygame` at version `1.2.0` with builder `android`:
141
-
142
- ```
143
- http://build.example.com:9630/android/mygame-1.2.0
144
- ```
145
-
146
- The server extracts the zip, reads the embedded `package.json`, runs the build for that platform, and streams a zip of artifacts back to the client.
147
-
148
- ### Zip contents
149
-
150
- | Archive path | Source on disk | Purpose |
151
- |--------------|----------------|---------|
152
- | `deploy/` | `{deployFolder}/` (default `./deploy/`) | Built web app (HTML, JS, assets) |
153
- | `deploy/index.html` | `{deployFolder}/index.html` | Entry point (also included via the directory) |
154
- | `meta/` | `./assets/meta/` (if present) | Icons, signing keys, and publish credentials |
155
- | `package.json` | project root | Merged `package.json` + `wrapfully.json` config |
156
-
157
- ### Project layout
158
-
159
- ```
160
- mygame/
161
- ├── package.json # npm metadata + config block (see below)
162
- ├── wrapfully.json # optional merged into config
163
- ├── deploy/ # built web app (or set deployFolder in config)
164
- │ └── index.html
165
- └── assets/
166
- └── meta/ # packaged as meta/ in the zip
167
- ├── icon-foreground.png
168
- ├── icon-background.png
169
- └── publish/ # platform signing & deploy credentials
170
- ├── build.json
171
- ├── android/
172
- ├── apple.json
173
- └── ...
174
- ```
175
-
176
- Icons (`icon-foreground.png`, `icon-background.png`) are required for mobile, desktop, and Steam builds.
177
-
178
- ### Icons
179
-
180
- Place two layered PNG files in `./assets/meta/` (packaged as `meta/` in the zip):
181
-
182
- | File | Purpose |
183
- |------|---------|
184
- | `icon-foreground.png` | Foreground layer (typically the character or subject) |
185
- | `icon-background.png` | Background layer (typically the scene or environment) |
186
-
187
- The build server composites the foreground over the background, applies a binding/logo overlay, and generates the icon sizes each platform needs.
188
-
189
- **Recommended format:** 1536×1536 pixel square PNGs for both files. Images with other dimensions are scaled to 1536×1536 automatically, but matching the target size produces the sharpest results.
190
-
191
- ## Configuration
192
-
193
- Build settings are read from `package.json`. The client merges any `wrapfully.json` fields into `package.json`'s `config` object before sending.
194
-
195
- ### `package.json`
196
-
197
- Standard npm fields (`name`, `version`, `description`) are used directly. Add a `config` block:
198
-
199
- ```json
200
- {
201
- "name": "mygame",
202
- "version": "1.2.0",
203
- "description": "My game",
204
- "config": {
205
- "title": "My Game",
206
- "packageName": "com.example.mygame",
207
- "publisherDisplayName": "Example Games",
208
- "publisherFullName": "Example Games LLC",
209
- "publisherWebsite": "https://example.com",
210
- "publisherEmailAddress": "hello@example.com",
211
- "scope": "https://example.com/games/",
212
- "themeColor": "#1a1a2e",
213
- "twitterId": "@examplegames",
214
- "steamId": 1234567,
215
- "properties": [
216
- { "tag": "plugin", "name": "cordova-plugin-inappbrowser" },
217
- { "tag": "allow-navigation", "href": "*" }
218
- ]
219
- }
220
- }
221
- ```
222
-
223
- | Field | Used by | Description |
224
- |-------|---------|-------------|
225
- | `title` | All | Display name shown in stores and app shells |
226
- | `packageName` | Cordova, Electron, UWP | Reverse-DNS identifier (`com.company.game`) |
227
- | `publisherDisplayName` | Cordova, Electron, web | Short publisher name |
228
- | `publisherFullName` | Electron | Legal entity name for copyright |
229
- | `publisherWebsite` | Cordova, web | Company URL |
230
- | `publisherEmailAddress` | Cordova | Contact email |
231
- | `scope` | Web/PWA | Base URL scope for the web app |
232
- | `themeColor` | Cordova, UWP, web | Loading screen / theme color |
233
- | `twitterId` | Web | Twitter handle for meta tags |
234
- | `steamId` | Steam | Steam app ID |
235
- | `properties` | Cordova | Cordova config.xml entries (plugins, allow-navigation, etc.) |
236
- | `deployFolder` | Client | Deploy directory name (default: `deploy`) |
237
-
238
- ### `wrapfully.json`
239
-
240
- Optional. Fields are shallow-merged into `package.json`'s `config`:
241
-
242
- ```json
243
- {
244
- "deployFolder": "dist",
245
- "server": "http://build.example.com:9630/",
246
- "title": "My Game",
247
- "packageName": "com.example.mygame"
248
- }
249
- ```
250
-
251
- Use this to set the server address or override config per environment without editing `package.json`.
252
-
253
- ## Builders
254
-
255
- Each builder name becomes a path segment on the server. Some builds require a specific host OS on the server side; composite builders fan out to multiple platforms automatically.
256
-
257
- | Builder | Output |
258
- |---------|--------|
259
- | `android` | Release Android (.aab) |
260
- | `android-dev` | Debug Android (.apk) |
261
- | `ios` | Release iOS (.ipa) |
262
- | `ios-dev` | Debug iOS (.ipa) |
263
- | `ios-sim` | iOS Simulator (.app) |
264
- | `mac` | Release Mac (.app) |
265
- | `mac-dev` | Debug Mac (.app) with DevTools |
266
- | `win` | Windows portable (.exe) |
267
- | `win-dev` | Debug Windows portable with DevTools |
268
- | `linux` | Linux build |
269
- | `linux-dev` | Debug Linux build with DevTools |
270
- | `uwp` | Universal Windows Package |
271
- | `webapp` | Service-worker web app (optionally SFTP deploy) |
272
- | `steam` | Windows + Mac + Linux, uploads to Steam |
273
- | `steam-dev` | Debug Windows + Mac + Linux, no Steam upload |
274
- | `cordova` | Release Android + iOS |
275
- | `cordova-dev` | Debug Android + iOS |
276
- | `apple` | Release Mac + iOS |
277
- | `apple-dev` | Release Mac + debug iOS |
278
-
279
- For a single platform, pass the specific builder name rather than a composite.
280
-
281
- ### Platform package requirements
282
-
283
- Signing keys, provisioning profiles, and store credentials go in `./assets/meta/publish/` on disk (sent as `meta/publish/` in the zip). **These files contain secrets** — add them to `.gitignore` and never commit them to a public repository.
284
-
285
- #### Android (`android`, `android-dev`)
286
-
287
- Place keystore files in `assets/meta/publish/android/`. Include `assets/meta/publish/build.json`:
288
-
289
- ```json
290
- {
291
- "android": {
292
- "debug": {
293
- "keystore": "./android/debug.keystore",
294
- "packageType": "apk",
295
- "storePassword": "android",
296
- "alias": "androiddebugkey",
297
- "password": "android",
298
- "keystoreType": ""
299
- },
300
- "release": {
301
- "keystore": "./android/release.keystore",
302
- "packageType": "bundle",
303
- "storePassword": "(your store password)",
304
- "alias": "(your alias)",
305
- "password": "(your password)",
306
- "keystoreType": ""
307
- }
308
- }
309
- }
310
- ```
311
-
312
- To deploy to Google Play, also include `assets/meta/publish/google.json`:
313
-
314
- ```json
315
- {
316
- "type": "service_account",
317
- "project_id": "(your project id)",
318
- "private_key_id": "(your private key id)",
319
- "private_key": "(your private key)",
320
- "client_email": "(your service account email)",
321
- "client_id": "(your client id)",
322
- "auth_uri": "https://accounts.google.com/o/oauth2/auth",
323
- "token_uri": "https://oauth2.googleapis.com/token",
324
- "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
325
- "client_x509_cert_url": "(your service account cert URL)"
326
- }
327
- ```
328
-
329
- #### Apple (`ios`, `ios-dev`, `ios-sim`, `mac`, `apple`, `apple-dev`)
330
-
331
- Include `assets/meta/publish/build.json` with iOS signing settings:
332
-
333
- ```json
334
- {
335
- "ios": {
336
- "debug": {
337
- "codeSignIdentity": "iPhone Development",
338
- "provisioningProfile": "(your development provisioning profile id)",
339
- "developmentTeam": "(your team id)",
340
- "packageType": "development",
341
- "automaticProvisioning": false
342
- },
343
- "release": {
344
- "codeSignIdentity": "iPhone Distribution",
345
- "provisioningProfile": "(your distribution provisioning profile id)",
346
- "developmentTeam": "(your team id)",
347
- "packageType": "app-store",
348
- "automaticProvisioning": false
349
- }
350
- }
351
- }
352
- ```
353
-
354
- To deploy to the App Store, include `assets/meta/publish/apple.json`:
355
-
356
- ```json
357
- {
358
- "category": "(your app's category)",
359
- "identity": "(your team identity)",
360
- "username": "(your username)",
361
- "password": "(your password)"
362
- }
363
- ```
364
-
365
- #### Cordova (`cordova`, `cordova-dev`)
366
-
367
- Requires the Android and Apple package requirements above.
368
-
369
- #### Steam (`steam`, `steam-dev`)
370
-
371
- `steam-dev` builds debug Electron binaries for Windows, Mac, and Linux without uploading to Steam. No `steam.json` credentials are required.
372
-
373
- For release uploads, include `assets/meta/publish/steam.json`:
374
-
375
- ```json
376
- {
377
- "username": "(your username)",
378
- "password": "(your password)"
379
- }
380
- ```
381
-
382
- Also set `steamId` in your `config` block.
383
-
384
- Steam builds can run on either the Windows or Mac server. The server that receives the request builds its own platforms and requests the rest from the other server (Windows builds `win` and requests `mac`/`linux`; Mac builds `mac`/`linux` and requests `win`). Install the Steamworks SDK ContentBuilder on any server that will upload to Steam.
385
-
386
- When builds relay between servers, `meta/publish/` credentials travel in the zip with the game payload.
387
-
388
- #### Electron (`win`, `win-dev`, `mac`, `mac-dev`, `linux`, `linux-dev`, `steam`, `steam-dev`)
389
-
390
- `-dev` builders produce debug Electron apps with DevTools enabled and the application menu visible. Dev builds skip code signing, notarization, and Steam upload. No publish credentials are required for dev builds.
391
-
392
- Release `win` builds can be signed with `assets/meta/publish/ms.json` (see Windows below). Release `mac` builds can use `assets/meta/publish/apple.json` for signing and notarization (see Apple above).
393
-
394
- #### Web app (`webapp`)
395
-
396
- To deploy via SFTP, include `assets/meta/publish/sftp.json`:
397
-
398
- ```json
399
- {
400
- "webapp": {
401
- "host": "(your sftp host)",
402
- "port": 22,
403
- "user": "(your username)",
404
- "password": "(your password)",
405
- "path": "(the sftp subdirectory in which to publish the app)"
406
- }
407
- }
408
- ```
409
-
410
- #### Windows (`win`, `win-dev`, `uwp`)
411
-
412
- To sign the app, place your certificate at `assets/meta/publish/ms/packcert.pfx` and include `assets/meta/publish/ms.json`:
413
-
414
- ```json
415
- {
416
- "publisherName": "CN=(your publisher id)",
417
- "certificateFile": "./ms/packcert.pfx",
418
- "password": "(your password)"
419
- }
420
- ```
421
-
422
- ## Response
423
-
424
- The server responds with a zip stream containing build artifacts (`.apk`, `.aab`, `.ipa`, `.app`, `.exe`, etc.) and optional status files. By default the client extracts this into `./output/`. Use a non-`extract` mode value to save the raw response zip instead.
425
-
426
- Every build also includes `wrapfully-status.json` with structured `success`, `warn`, and `error` events. The client prints these after extraction and exits with code 1 if any errors were reported, so build failures do not crash the server silently.
427
-
428
- ## License
429
-
430
- MIT
1
+ # Adaptfully
2
+
3
+ Platform abstraction and Wrapfully deploy client for Makefully games.
4
+
5
+ - **Adaptfully runtime** — shared auth and platform services via `adaptfully.register()` / `adaptfully.get()`
6
+ - **Adaptfully pipeline** — prebuild, build, and deploy stages driven by `config.platforms`
7
+ - **Wrapfully deploy** — zip-and-post client for building desktop, mobile, and Steam packages
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @makefully/adaptfully
13
+ ```
14
+
15
+ Maintainers: see [PUBLISHING.md](PUBLISHING.md) for npm trusted publishing setup.
16
+
17
+ ## Adaptfully runtime
18
+
19
+ Games register platform services before load and retrieve them in-game. Adaptfully applies platform registrations during **prebuild** — games compile a neutral `deploy/` folder, then Adaptfully writes `output/<platform>-prebuild/` with the correct auth and plugin scripts injected into HTML.
20
+
21
+ ### Pipeline stages
22
+
23
+ ```bash
24
+ adaptfully prebuild web # deploy/ → output/web-prebuild/
25
+ adaptfully build steam # prebuild + zip and send to Wrapfully
26
+ adaptfully deploy steam # build + platform release when credentials are present
27
+ ```
28
+
29
+ | Stage | What it does |
30
+ |-------|----------------|
31
+ | `prebuild` | Copy `deploy/` to `output/<platform>-prebuild/` and inject registrations into `config.htmlInjections` |
32
+ | `build` | Prebuild, then POST the result to Wrapfully |
33
+ | `deploy` | Build, then release to the target platform (Steam upload, webapp SFTP, etc. via Wrapfully when credentials are in `assets/meta/publish/`) |
34
+
35
+ `wrapfully-deploy` is a compatibility alias for `adaptfully deploy` when invoked with a Wrapfully builder name (`steam`, `win`, `android`, etc.).
36
+
37
+ Place `<!-- adaptfully -->` / `<!-- /adaptfully -->` markers in your HTML templates where registrations should be injected (typically between split bundle scripts, before `account.js` runs).
38
+
39
+ ```javascript
40
+ // Injected into deploy/index.html for the target platform (before game code):
41
+ adaptfully.register('auth', adaptfully.auth.Google);
42
+
43
+ // In-game:
44
+ const platform = adaptfully.get('auth');
45
+ platform.login(function (result) { /* ... */ });
46
+ ```
47
+
48
+ ### Auth plugins
49
+
50
+ | Plugin key | Registration | Runtime |
51
+ |------------|--------------|---------|
52
+ | `google-auth` | `adaptfully.register('auth', adaptfully.auth.Google)` | Web, Android, iOS |
53
+ | `steam-auth` | `adaptfully.register('auth', adaptfully.auth.Steam)` | Steam / Electron |
54
+ | `dev-auth` | `adaptfully.register('auth', adaptfully.auth.Dev)` | Local dev (test user) |
55
+
56
+ Use plugin keys in `config.platforms.<platform>.registrations`. Custom deploy scripts use a path relative to the deploy folder instead:
57
+
58
+ ```json
59
+ {
60
+ "config": {
61
+ "platforms": {
62
+ "steam": {
63
+ "registrations": {
64
+ "auth": "steam-auth",
65
+ "storage": "/javascript/custom-storage-solution.js"
66
+ }
67
+ },
68
+ "web": {
69
+ "registrations": {
70
+ "auth": "google-auth",
71
+ "storage": "/javascript/adaptfully-bridge.js"
72
+ }
73
+ },
74
+ "dev": {
75
+ "registrations": {
76
+ "auth": "dev-auth"
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ Standard plugin keys load bundled Adaptfully runtime scripts and emit an inline `adaptfully.register()` call. Path values add a `<script src="...">` tag — the script is expected to call `adaptfully.register()` itself (for example a bridge that wires `storage` and `config`).
85
+
86
+ Wrapfully builders (`steam`, `win`, `mac`, `android`, etc.) map to platform keys via defaults (`win` → `steam`) or an explicit `builders` array on the platform config.
87
+
88
+ ### Node API
89
+
90
+ ```javascript
91
+ import {
92
+ prebuildPlatform,
93
+ resolveHtmlInjections,
94
+ runAdaptfullyStage,
95
+ buildAdaptfullyInjection,
96
+ injectAdaptfullyRegistrations,
97
+ adaptfullyInjectionForPlatform,
98
+ resolveRegistrationAssets,
99
+ resolvePlatformKey,
100
+ resolveBuilderForPlatform,
101
+ getRuntimeDir,
102
+ resolveRuntimeScript,
103
+ STANDARD_PLUGINS,
104
+ } from '@makefully/adaptfully';
105
+ ```
106
+
107
+ - **`prebuildPlatform(deployFolder, platformKey, pkg)`** — copy `deploy/` to `output/<platform>-prebuild/` and inject registrations into `config.htmlInjections` (default: `index.html`).
108
+ - **`resolveRegistrationAssets(registrations)`** resolve runtime script paths, inline registration JS, and external script tags for a registration map (useful for Vite dev servers).
109
+ - **`runAdaptfullyStage('prebuild' | 'build' | 'deploy', platformKey, options)`** — run a pipeline stage programmatically.
110
+
111
+ ---
112
+
113
+ ## Wrapfully deploy
114
+
115
+ After prebuild, the build and deploy stages zip `output/<platform>-prebuild/` and POST it to a Wrapfully build server. Artifacts are saved to `./output/`.
116
+
117
+ ## Quick start
118
+
119
+ 1. Build your web app into a neutral deploy folder (default: `./deploy/`, must include `index.html` with adaptfully markers).
120
+ 2. Add `config.platforms` and other settings to `package.json` (see [Configuration](#configuration)).
121
+ 3. Add icons and any signing credentials under `./assets/meta/`.
122
+ 4. Prebuild for your target platform, then build or deploy:
123
+
124
+ ```bash
125
+ npx adaptfully prebuild web
126
+ npx adaptfully deploy steam http://build.example.com:9630/
127
+ ```
128
+
129
+ For web-only hosting (no Wrapfully), stop after prebuild and upload `output/web-prebuild/` yourself.
130
+
131
+ ## Usage
132
+
133
+ ### Adaptfully CLI
134
+
135
+ Run from your project root:
136
+
137
+ ```bash
138
+ npx adaptfully <prebuild|build|deploy> <platform> [server] [mode]
139
+ ```
140
+
141
+ | Stage | Description |
142
+ |-------|-------------|
143
+ | `prebuild` | Copy `deploy/` → `output/<platform>-prebuild/` with registrations injected into `config.htmlInjections` |
144
+ | `build` | Prebuild, then POST to Wrapfully (no platform release) |
145
+ | `deploy` | Prebuild, POST to Wrapfully, then release when credentials are present |
146
+
147
+ | Argument | Default | Description |
148
+ |----------|---------|-------------|
149
+ | `platform` | — | Platform key from `config.platforms` (`web`, `steam`, etc.) |
150
+ | `server` | see below | Wrapfully server base URL (`build` and `deploy` only) |
151
+ | `mode` | `extract` | `extract` unpacks the response zip into `./output/`; any other value saves `./output/{name}-{version}-{builder}.zip` |
152
+
153
+ Examples:
154
+
155
+ ```bash
156
+ # Prebuild for web (upload output/web-prebuild/ via FTP, S3, etc.)
157
+ npx adaptfully prebuild web
158
+
159
+ # Build for Steam via Wrapfully
160
+ npx adaptfully build steam http://build.example.com:9630/
161
+
162
+ # Full Steam deploy (build + upload when steam.json credentials are present)
163
+ npx adaptfully deploy steam http://build.example.com:9630/
164
+ ```
165
+
166
+ Add scripts to your project's `package.json`:
167
+
168
+ ```json
169
+ {
170
+ "scripts": {
171
+ "web:prebuild": "adaptfully prebuild web",
172
+ "steam:deploy": "adaptfully deploy steam"
173
+ }
174
+ }
175
+ ```
176
+
177
+ ### wrapfully-deploy (legacy alias)
178
+
179
+ ```bash
180
+ npx wrapfully-deploy [builder] [server] [mode]
181
+ ```
182
+
183
+ Accepts Wrapfully builder names (`steam`, `win`, `mac`, `android`, `webapp`, etc.) instead of platform keys. Maps to the matching `config.platforms` entry (defaults: `win` → `steam`, `webapp` → `web`) and runs the `deploy` stage.
184
+
185
+ ### Server address
186
+
187
+ The server URL is resolved in this order:
188
+
189
+ 1. CLI argument
190
+ 2. `WRAPFULLY_SERVER` environment variable
191
+ 3. `server` field in `wrapfully.json`
192
+ 4. `http://localhost:9630/`
193
+
194
+ Keep server addresses and credentials out of version control — use environment variables or a gitignored `wrapfully.json`.
195
+
196
+ ## What gets sent
197
+
198
+ The client POSTs a zip stream built from `output/<platform>-prebuild/` to:
199
+
200
+ ```
201
+ {server}{builder}/{name}-{version}
202
+ ```
203
+
204
+ For example, a project named `mygame` at version `1.2.0` with builder `android`:
205
+
206
+ ```
207
+ http://build.example.com:9630/android/mygame-1.2.0
208
+ ```
209
+
210
+ The server extracts the zip, reads the embedded `package.json`, runs the build for that platform, and streams a zip of artifacts back to the client.
211
+
212
+ ### Zip contents
213
+
214
+ | Archive path | Source on disk | Purpose |
215
+ |--------------|----------------|---------|
216
+ | `deploy/` | prebuilt `output/<platform>-prebuild/` | Built web app with Adaptfully registrations injected |
217
+ | `deploy/index.html` | prebuilt entry point | Platform-specific HTML |
218
+ | `meta/` | `./assets/meta/` (if present) | Icons, signing keys, and publish credentials |
219
+ | `package.json` | project root | Merged `package.json` + `wrapfully.json` config |
220
+
221
+ ### Project layout
222
+
223
+ ```
224
+ mygame/
225
+ ├── package.json # npm metadata + config.platforms (see below)
226
+ ├── wrapfully.json # optional merged into config
227
+ ├── deploy/ # neutral build output (default deployFolder)
228
+ │ └── index.html
229
+ ├── output/
230
+ │ ├── web-prebuild/ # after adaptfully prebuild web
231
+ │ └── steam-prebuild/ # after adaptfully prebuild steam
232
+ └── assets/
233
+ └── meta/ # packaged as meta/ in the zip
234
+ ├── icon-foreground.png
235
+ ├── icon-background.png
236
+ └── publish/ # platform signing & deploy credentials
237
+ ├── build.json
238
+ ├── android/
239
+ ├── apple.json
240
+ └── ...
241
+ ```
242
+
243
+ Icons (`icon-foreground.png`, `icon-background.png`) are required for mobile, desktop, and Steam builds.
244
+
245
+ ### Icons
246
+
247
+ Place two layered PNG files in `./assets/meta/` (packaged as `meta/` in the zip):
248
+
249
+ | File | Purpose |
250
+ |------|---------|
251
+ | `icon-foreground.png` | Foreground layer (typically the character or subject) |
252
+ | `icon-background.png` | Background layer (typically the scene or environment) |
253
+
254
+ The build server composites the foreground over the background, applies a binding/logo overlay, and generates the icon sizes each platform needs.
255
+
256
+ **Recommended format:** 1536×1536 pixel square PNGs for both files. Images with other dimensions are scaled to 1536×1536 automatically, but matching the target size produces the sharpest results.
257
+
258
+ ## Configuration
259
+
260
+ Build settings are read from `package.json`. The client merges any `wrapfully.json` fields into `package.json`'s `config` object before sending.
261
+
262
+ ### `package.json`
263
+
264
+ Standard npm fields (`name`, `version`, `description`) are used directly. Add a `config` block:
265
+
266
+ ```json
267
+ {
268
+ "name": "mygame",
269
+ "version": "1.2.0",
270
+ "description": "My game",
271
+ "config": {
272
+ "title": "My Game",
273
+ "packageName": "com.example.mygame",
274
+ "publisherDisplayName": "Example Games",
275
+ "publisherFullName": "Example Games LLC",
276
+ "publisherWebsite": "https://example.com",
277
+ "publisherEmailAddress": "hello@example.com",
278
+ "scope": "https://example.com/games/",
279
+ "themeColor": "#1a1a2e",
280
+ "twitterId": "@examplegames",
281
+ "steamId": 1234567,
282
+ "deployFolder": "deploy",
283
+ "platforms": {
284
+ "web": {
285
+ "registrations": {
286
+ "auth": "google-auth",
287
+ "storage": "/javascript/adaptfully-bridge.js"
288
+ }
289
+ },
290
+ "steam": {
291
+ "registrations": {
292
+ "auth": "steam-auth",
293
+ "storage": "/javascript/adaptfully-bridge.js"
294
+ }
295
+ }
296
+ },
297
+ "properties": [
298
+ { "tag": "plugin", "name": "cordova-plugin-inappbrowser" },
299
+ { "tag": "allow-navigation", "href": "*" }
300
+ ]
301
+ }
302
+ }
303
+ ```
304
+
305
+ | Field | Used by | Description |
306
+ |-------|---------|-------------|
307
+ | `title` | All | Display name shown in stores and app shells |
308
+ | `packageName` | Cordova, Electron, UWP | Reverse-DNS identifier (`com.company.game`) |
309
+ | `publisherDisplayName` | Cordova, Electron, web | Short publisher name |
310
+ | `publisherFullName` | Electron | Legal entity name for copyright |
311
+ | `publisherWebsite` | Cordova, web | Company URL |
312
+ | `publisherEmailAddress` | Cordova | Contact email |
313
+ | `scope` | Web/PWA | Base URL scope for the web app |
314
+ | `themeColor` | Cordova, UWP, web | Loading screen / theme color |
315
+ | `twitterId` | Web | Twitter handle for meta tags |
316
+ | `steamId` | Steam | Steam app ID |
317
+ | `deployFolder` | Client | Neutral deploy directory staged before prebuild (default: `deploy`) |
318
+ | `htmlInjections` | Prebuild | Deploy-relative HTML paths to inject (default: `["index.html"]`) |
319
+ | `outputFolder` | Client | Prebuild output root (default: `output`) |
320
+ | `platforms` | Prebuild | Per-platform registration maps (see [Adaptfully runtime](#adaptfully-runtime)) |
321
+ | `platforms.<name>.builder` | Build/deploy | Override Wrapfully builder for a platform (default: `web` → `webapp`, others match platform key) |
322
+ | `platforms.<name>.builders` | wrapfully-deploy | Map additional Wrapfully builder names to a platform |
323
+ | `properties` | Cordova | Cordova config.xml entries (plugins, allow-navigation, etc.) |
324
+
325
+ ### `wrapfully.json`
326
+
327
+ Optional. Fields are shallow-merged into `package.json`'s `config`:
328
+
329
+ ```json
330
+ {
331
+ "deployFolder": "dist",
332
+ "server": "http://build.example.com:9630/",
333
+ "title": "My Game",
334
+ "packageName": "com.example.mygame"
335
+ }
336
+ ```
337
+
338
+ Use this to set the server address or override config per environment without editing `package.json`.
339
+
340
+ ## Builders
341
+
342
+ Each builder name becomes a path segment on the server. Some builds require a specific host OS on the server side; composite builders fan out to multiple platforms automatically.
343
+
344
+ | Builder | Output |
345
+ |---------|--------|
346
+ | `android` | Release Android (.aab) |
347
+ | `android-dev` | Debug Android (.apk) |
348
+ | `ios` | Release iOS (.ipa) |
349
+ | `ios-dev` | Debug iOS (.ipa) |
350
+ | `ios-sim` | iOS Simulator (.app) |
351
+ | `mac` | Release Mac (.app) |
352
+ | `mac-dev` | Debug Mac (.app) with DevTools |
353
+ | `win` | Windows portable (.exe) |
354
+ | `win-dev` | Debug Windows portable with DevTools |
355
+ | `linux` | Linux build |
356
+ | `linux-dev` | Debug Linux build with DevTools |
357
+ | `uwp` | Universal Windows Package |
358
+ | `webapp` | Service-worker web app (optionally SFTP deploy) |
359
+ | `steam` | Windows + Mac + Linux, uploads to Steam |
360
+ | `steam-dev` | Debug Windows + Mac + Linux, no Steam upload |
361
+ | `cordova` | Release Android + iOS |
362
+ | `cordova-dev` | Debug Android + iOS |
363
+ | `apple` | Release Mac + iOS |
364
+ | `apple-dev` | Release Mac + debug iOS |
365
+
366
+ For a single platform, pass the specific builder name rather than a composite.
367
+
368
+ ### Platform package requirements
369
+
370
+ Signing keys, provisioning profiles, and store credentials go in `./assets/meta/publish/` on disk (sent as `meta/publish/` in the zip). **These files contain secrets** — add them to `.gitignore` and never commit them to a public repository.
371
+
372
+ #### Android (`android`, `android-dev`)
373
+
374
+ Place keystore files in `assets/meta/publish/android/`. Include `assets/meta/publish/build.json`:
375
+
376
+ ```json
377
+ {
378
+ "android": {
379
+ "debug": {
380
+ "keystore": "./android/debug.keystore",
381
+ "packageType": "apk",
382
+ "storePassword": "android",
383
+ "alias": "androiddebugkey",
384
+ "password": "android",
385
+ "keystoreType": ""
386
+ },
387
+ "release": {
388
+ "keystore": "./android/release.keystore",
389
+ "packageType": "bundle",
390
+ "storePassword": "(your store password)",
391
+ "alias": "(your alias)",
392
+ "password": "(your password)",
393
+ "keystoreType": ""
394
+ }
395
+ }
396
+ }
397
+ ```
398
+
399
+ To deploy to Google Play, also include `assets/meta/publish/google.json`:
400
+
401
+ ```json
402
+ {
403
+ "type": "service_account",
404
+ "project_id": "(your project id)",
405
+ "private_key_id": "(your private key id)",
406
+ "private_key": "(your private key)",
407
+ "client_email": "(your service account email)",
408
+ "client_id": "(your client id)",
409
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
410
+ "token_uri": "https://oauth2.googleapis.com/token",
411
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
412
+ "client_x509_cert_url": "(your service account cert URL)"
413
+ }
414
+ ```
415
+
416
+ #### Apple (`ios`, `ios-dev`, `ios-sim`, `mac`, `apple`, `apple-dev`)
417
+
418
+ Include `assets/meta/publish/build.json` with iOS signing settings:
419
+
420
+ ```json
421
+ {
422
+ "ios": {
423
+ "debug": {
424
+ "codeSignIdentity": "iPhone Development",
425
+ "provisioningProfile": "(your development provisioning profile id)",
426
+ "developmentTeam": "(your team id)",
427
+ "packageType": "development",
428
+ "automaticProvisioning": false
429
+ },
430
+ "release": {
431
+ "codeSignIdentity": "iPhone Distribution",
432
+ "provisioningProfile": "(your distribution provisioning profile id)",
433
+ "developmentTeam": "(your team id)",
434
+ "packageType": "app-store",
435
+ "automaticProvisioning": false
436
+ }
437
+ }
438
+ }
439
+ ```
440
+
441
+ To deploy to the App Store, include `assets/meta/publish/apple.json`:
442
+
443
+ ```json
444
+ {
445
+ "category": "(your app's category)",
446
+ "identity": "(your team identity)",
447
+ "username": "(your username)",
448
+ "password": "(your password)"
449
+ }
450
+ ```
451
+
452
+ #### Cordova (`cordova`, `cordova-dev`)
453
+
454
+ Requires the Android and Apple package requirements above.
455
+
456
+ #### Steam (`steam`, `steam-dev`)
457
+
458
+ `steam-dev` builds debug Electron binaries for Windows, Mac, and Linux without uploading to Steam. No `steam.json` credentials are required.
459
+
460
+ For release uploads, include `assets/meta/publish/steam.json`:
461
+
462
+ ```json
463
+ {
464
+ "username": "(your username)",
465
+ "password": "(your password)"
466
+ }
467
+ ```
468
+
469
+ Also set `steamId` in your `config` block.
470
+
471
+ Steam builds can run on either the Windows or Mac server. The server that receives the request builds its own platforms and requests the rest from the other server (Windows builds `win` and requests `mac`/`linux`; Mac builds `mac`/`linux` and requests `win`). Install the Steamworks SDK ContentBuilder on any server that will upload to Steam.
472
+
473
+ When builds relay between servers, `meta/publish/` credentials travel in the zip with the game payload.
474
+
475
+ #### Electron (`win`, `win-dev`, `mac`, `mac-dev`, `linux`, `linux-dev`, `steam`, `steam-dev`)
476
+
477
+ `-dev` builders produce debug Electron apps with DevTools enabled and the application menu visible. Dev builds skip code signing, notarization, and Steam upload. No publish credentials are required for dev builds.
478
+
479
+ Release `win` builds can be signed with `assets/meta/publish/ms.json` (see Windows below). Release `mac` builds can use `assets/meta/publish/apple.json` for signing and notarization (see Apple above).
480
+
481
+ #### Web app (`webapp`)
482
+
483
+ To deploy via SFTP, include `assets/meta/publish/sftp.json`:
484
+
485
+ ```json
486
+ {
487
+ "webapp": {
488
+ "host": "(your sftp host)",
489
+ "port": 22,
490
+ "user": "(your username)",
491
+ "password": "(your password)",
492
+ "path": "(the sftp subdirectory in which to publish the app)"
493
+ }
494
+ }
495
+ ```
496
+
497
+ #### Windows (`win`, `win-dev`, `uwp`)
498
+
499
+ To sign the app, place your certificate at `assets/meta/publish/ms/packcert.pfx` and include `assets/meta/publish/ms.json`:
500
+
501
+ ```json
502
+ {
503
+ "publisherName": "CN=(your publisher id)",
504
+ "certificateFile": "./ms/packcert.pfx",
505
+ "password": "(your password)"
506
+ }
507
+ ```
508
+
509
+ ## Response
510
+
511
+ The server responds with a zip stream containing build artifacts (`.apk`, `.aab`, `.ipa`, `.app`, `.exe`, etc.) and optional status files. By default the client extracts this into `./output/`. Use a non-`extract` mode value to save the raw response zip instead.
512
+
513
+ Every build also includes `wrapfully-status.json` with structured `success`, `warn`, and `error` events. The client prints these after extraction and exits with code 1 if any errors were reported, so build failures do not crash the server silently.
514
+
515
+ ## License
516
+
517
+ MIT