@auraindustry/aurajs 0.1.1 → 0.1.5
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 +7 -0
- package/benchmarks/perf-thresholds.json +27 -0
- package/package.json +6 -1
- package/src/ai-guidance.mjs +302 -0
- package/src/asset-pack.mjs +2 -1
- package/src/authored-project.mjs +498 -2
- package/src/authored-runtime.mjs +14 -0
- package/src/bin-integrity.mjs +33 -26
- package/src/build-contract/capabilities.mjs +87 -1
- package/src/build-contract/constants.mjs +1 -0
- package/src/build-contract.mjs +2 -0
- package/src/bundler.mjs +143 -13
- package/src/cli.mjs +681 -13
- package/src/commands/packs.mjs +741 -0
- package/src/commands/project-authoring.mjs +128 -1
- package/src/conformance/cases/app-and-ui-runtime-cases.mjs +1 -2
- package/src/conformance/cases/core-runtime-cases.mjs +6 -2
- package/src/conformance/cases/scene3d-and-media-cases.mjs +238 -0
- package/src/conformance/cases/systems-and-gameplay-cases.mjs +1126 -10
- package/src/conformance-mobile.mjs +166 -0
- package/src/conformance.mjs +89 -30
- package/src/evidence-bundle.mjs +242 -0
- package/src/external-package-surface.mjs +1 -1
- package/src/headless-test/runtime-coordinator.mjs +186 -33
- package/src/headless-test.mjs +2 -0
- package/src/helpers/2d/index.mjs +183 -0
- package/src/helpers/index.mjs +26 -0
- package/src/helpers/starter-utils/adventure-objectives.js +102 -0
- package/src/helpers/starter-utils/adventure-world-2d.js +221 -0
- package/src/helpers/starter-utils/animation-2d.js +337 -0
- package/src/helpers/starter-utils/animation-packaging-2d.js +203 -0
- package/src/helpers/starter-utils/atlas-assets-2d.js +111 -0
- package/src/helpers/starter-utils/autoplay-debug-2d.js +215 -0
- package/src/helpers/starter-utils/avatar-3d.js +404 -0
- package/src/helpers/starter-utils/combat-feedback-2d.js +320 -0
- package/src/helpers/starter-utils/combat-runtime-2d.js +290 -0
- package/src/helpers/starter-utils/core.js +150 -0
- package/src/helpers/starter-utils/dialogue-2d.js +351 -0
- package/src/helpers/starter-utils/enemy-archetypes-2d.js +68 -0
- package/src/helpers/starter-utils/index.js +26 -0
- package/src/helpers/starter-utils/inventory-2d.js +268 -0
- package/src/helpers/starter-utils/journal-2d.js +267 -0
- package/src/helpers/starter-utils/platformer-3d.js +132 -0
- package/src/helpers/starter-utils/scene-audio-2d.js +236 -0
- package/src/helpers/starter-utils/streamed-world-2d.js +378 -0
- package/src/helpers/starter-utils/tilemap-nav-2d.js +499 -0
- package/src/helpers/starter-utils/tilemap-world-2d.js +205 -0
- package/src/helpers/starter-utils/triggers.js +662 -0
- package/src/helpers/starter-utils/tween-2d.js +615 -0
- package/src/helpers/starter-utils/wave-director.js +101 -0
- package/src/helpers/starter-utils/world-compositor-2d.js +253 -0
- package/src/helpers/starter-utils/world-persistence-2d.js +180 -0
- package/src/mobile/android/build.mjs +606 -0
- package/src/mobile/android/host-artifact.mjs +280 -0
- package/src/mobile/ios/build.mjs +1323 -0
- package/src/mobile/ios/host-artifact.mjs +819 -0
- package/src/mobile/shared/capabilities.mjs +174 -0
- package/src/package-integrity.mjs +18 -4
- package/src/packs/catalog.mjs +259 -0
- package/src/perf-benchmark-runner.mjs +17 -12
- package/src/perf-benchmark.mjs +408 -4
- package/src/publish-command.mjs +434 -17
- package/src/publish-validation.mjs +22 -11
- package/src/replay-runtime.mjs +257 -0
- package/src/scaffold/config.mjs +2 -0
- package/src/scaffold/fs.mjs +8 -1
- package/src/scaffold/project-docs.mjs +101 -41
- package/src/scaffold.mjs +4 -0
- package/src/session-runtime.mjs +4 -3
- package/src/web-conformance.mjs +0 -36
- package/templates/create/2d/src/runtime/app.js +4 -0
- package/templates/create/2d-adventure/config/gameplay/adventure.config.js +9 -6
- package/templates/create/2d-adventure/content/gameplay/dialogue.js +85 -0
- package/templates/create/2d-adventure/content/gameplay/world.js +32 -36
- package/templates/create/2d-adventure/content/gameplay/world.tilemap.json +273 -0
- package/templates/create/2d-adventure/docs/design/loop.md +4 -3
- package/templates/create/2d-adventure/prefabs/relic.prefab.js +10 -10
- package/templates/create/2d-adventure/prefabs/world.prefab.js +127 -74
- package/templates/create/2d-adventure/scenes/gameplay.scene.js +603 -112
- package/templates/create/2d-adventure/src/runtime/capabilities.js +16 -0
- package/templates/create/2d-adventure/ui/hud.screen.js +187 -4
- package/templates/create/2d-adventure/ui/journal.screen.js +183 -0
- package/templates/create/2d-survivor/src/runtime/app.js +4 -0
- package/templates/create/3d/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d/src/runtime/app.js +4 -0
- package/templates/create/3d/src/runtime/capabilities.js +5 -0
- package/templates/create/3d/src/runtime/materials.js +10 -0
- package/templates/create/3d-adventure/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d-adventure/src/runtime/capabilities.js +5 -0
- package/templates/create/3d-adventure/src/runtime/materials.js +11 -0
- package/templates/create/3d-collectathon/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d-collectathon/src/runtime/app.js +4 -0
- package/templates/create/3d-collectathon/src/runtime/capabilities.js +5 -0
- package/templates/create/3d-collectathon/src/runtime/materials.js +10 -0
- package/templates/create/blank/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/create/blank/assets/splash/bg.webp +0 -0
- package/templates/create/blank/assets/splash/boot-loop.wav +0 -0
- package/templates/create/blank/assets/splash/boot-sting.wav +0 -0
- package/templates/create/blank/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/create/blank/assets/splash/logoholo.webp +0 -0
- package/templates/create/blank/src/main.js +5 -1
- package/templates/create/blank/src/runtime/splash.js +305 -0
- package/templates/create/local-multiplayer/scenes/gameplay.scene.js +186 -12
- package/templates/create/local-multiplayer/src/runtime/capabilities.js +8 -1
- package/templates/create/shared/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/create/shared/assets/splash/bg.webp +0 -0
- package/templates/create/shared/assets/splash/boot-loop.wav +0 -0
- package/templates/create/shared/assets/splash/boot-sting.wav +0 -0
- package/templates/create/shared/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/create/shared/assets/splash/logoholo.webp +0 -0
- package/templates/create/shared/src/runtime/splash.js +305 -0
- package/templates/create/shared/src/runtime/ui-forms.js +552 -0
- package/templates/create/shared/src/starter-utils/adventure-world-2d.js +221 -0
- package/templates/create/shared/src/starter-utils/animation-packaging-2d.js +203 -0
- package/templates/create/shared/src/starter-utils/atlas-assets-2d.js +111 -0
- package/templates/create/shared/src/starter-utils/autoplay-debug-2d.js +215 -0
- package/templates/create/shared/src/starter-utils/combat-runtime-2d.js +290 -0
- package/templates/create/shared/src/starter-utils/dialogue-2d.js +351 -0
- package/templates/create/shared/src/starter-utils/index.js +15 -1
- package/templates/create/shared/src/starter-utils/inventory-2d.js +268 -0
- package/templates/create/shared/src/starter-utils/journal-2d.js +267 -0
- package/templates/create/shared/src/starter-utils/scene-audio-2d.js +236 -0
- package/templates/create/shared/src/starter-utils/streamed-world-2d.js +378 -0
- package/templates/create/shared/src/starter-utils/tilemap-nav-2d.js +499 -0
- package/templates/create/shared/src/starter-utils/tilemap-world-2d.js +205 -0
- package/templates/create/shared/src/starter-utils/world-compositor-2d.js +253 -0
- package/templates/create/shared/src/starter-utils/world-persistence-2d.js +180 -0
- package/templates/create/video-cutscene/src/runtime/app.js +4 -0
- package/templates/create-bin/play.js +148 -7
- package/templates/skills/auramaxx/SKILL.md +46 -0
- package/templates/skills/auramaxx/project-requirements.md +68 -0
- package/templates/skills/auramaxx/starter-recipes.md +104 -0
- package/templates/skills/auramaxx/validation-checklist.md +49 -0
- package/templates/starter/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/starter/assets/splash/bg.webp +0 -0
- package/templates/starter/assets/splash/boot-loop.wav +0 -0
- package/templates/starter/assets/splash/boot-sting.wav +0 -0
- package/templates/starter/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/starter/assets/splash/logoholo.webp +0 -0
- package/templates/starter/src/main.js +4 -0
- package/templates/starter/src/runtime/splash.js +305 -0
- package/templates/skills/aurajs/SKILL.md +0 -96
- package/templates/skills/aurajs/api-contract-3d.md +0 -7
- package/templates/skills/aurajs/api-contract.md +0 -7
package/src/publish-command.mjs
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import {
|
|
2
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { basename, join, resolve } from 'node:path';
|
|
4
5
|
|
|
5
6
|
import { preparePublishPackageSurface } from './external-package-surface.mjs';
|
|
6
7
|
import {
|
|
7
8
|
PACKAGE_INTEGRITY_PUBLISH_FILES,
|
|
8
9
|
writeSignedPackageIntegrityArtifacts,
|
|
9
10
|
} from './package-integrity.mjs';
|
|
11
|
+
import { canPromptInteractively, promptInput, promptSelect } from './terminal-ui.mjs';
|
|
10
12
|
import { resolvePublishEnvExampleSurface } from './publish-env-example.mjs';
|
|
11
13
|
import { validatePublishProject } from './publish-validation.mjs';
|
|
14
|
+
import { formatBytes } from './external-asset-policy.mjs';
|
|
15
|
+
|
|
16
|
+
const SEMVER_RE = /^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z-.]+)?$/;
|
|
17
|
+
const SCOPED_PACKAGE_RE = /^@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/;
|
|
18
|
+
const UNSCOPED_PACKAGE_RE = /^[a-z0-9][a-z0-9._-]*$/;
|
|
12
19
|
|
|
13
20
|
export function isNpmPublishLifecycleInvocation(env = process.env) {
|
|
14
21
|
return env.npm_lifecycle_event === 'publish' && env.npm_command === 'publish';
|
|
@@ -18,7 +25,237 @@ export function hasOption(commandArgs, optionName) {
|
|
|
18
25
|
return commandArgs.some((arg) => arg === optionName || arg.startsWith(`${optionName}=`));
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
function stripOption(commandArgs, optionName) {
|
|
29
|
+
const nextArgs = [];
|
|
30
|
+
for (let index = 0; index < commandArgs.length; index += 1) {
|
|
31
|
+
const current = commandArgs[index];
|
|
32
|
+
if (current === optionName) {
|
|
33
|
+
index += 1;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (current.startsWith(`${optionName}=`)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
nextArgs.push(current);
|
|
40
|
+
}
|
|
41
|
+
return nextArgs;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function sanitizePackageSlug(value) {
|
|
45
|
+
const compact = String(value || '')
|
|
46
|
+
.trim()
|
|
47
|
+
.toLowerCase()
|
|
48
|
+
.replace(/^@[^/]+\//, '')
|
|
49
|
+
.replace(/\s+/g, '-')
|
|
50
|
+
.replace(/[^a-z0-9._-]/g, '-')
|
|
51
|
+
.replace(/-+/g, '-')
|
|
52
|
+
.replace(/^[-._]+|[-._]+$/g, '');
|
|
53
|
+
if (!compact) {
|
|
54
|
+
throw new Error(`Cannot derive package slug from "${value}".`);
|
|
55
|
+
}
|
|
56
|
+
return compact;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildDefaultPackageName(projectRoot) {
|
|
60
|
+
return `@aurajs/${sanitizePackageSlug(basename(projectRoot))}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function ensureScopedPackageName(value) {
|
|
64
|
+
const trimmed = String(value || '').trim();
|
|
65
|
+
if (!trimmed) {
|
|
66
|
+
throw new Error('Package name cannot be empty.');
|
|
67
|
+
}
|
|
68
|
+
if (/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$/.test(trimmed)) {
|
|
69
|
+
return `@${trimmed}`;
|
|
70
|
+
}
|
|
71
|
+
return trimmed;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isValidPackageName(value) {
|
|
75
|
+
const normalized = String(value || '').trim();
|
|
76
|
+
if (!normalized) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const candidate = ensureScopedPackageName(normalized);
|
|
81
|
+
return SCOPED_PACKAGE_RE.test(candidate) || UNSCOPED_PACKAGE_RE.test(candidate);
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function validatePackageName(value) {
|
|
88
|
+
const normalized = ensureScopedPackageName(value);
|
|
89
|
+
if (!SCOPED_PACKAGE_RE.test(normalized) && !UNSCOPED_PACKAGE_RE.test(normalized)) {
|
|
90
|
+
throw new Error(`Invalid npm package name "${value}".`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function normalizeVersion(value) {
|
|
95
|
+
return String(value || '').trim().replace(/^v/i, '');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isValidVersion(value) {
|
|
99
|
+
return SEMVER_RE.test(String(value || '').trim());
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function validateVersion(value) {
|
|
103
|
+
if (!isValidVersion(value)) {
|
|
104
|
+
throw new Error(`Invalid version "${value}". Expected semver like 1.2.3 or 1.2.3-beta.1.`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function bumpVersion(currentVersion, bumpKind) {
|
|
109
|
+
const match = normalizeVersion(currentVersion).match(SEMVER_RE);
|
|
110
|
+
if (!match) {
|
|
111
|
+
throw new Error(`Current version "${currentVersion}" is not valid semver.`);
|
|
112
|
+
}
|
|
113
|
+
const major = Number.parseInt(match[1], 10);
|
|
114
|
+
const minor = Number.parseInt(match[2], 10);
|
|
115
|
+
const patch = Number.parseInt(match[3], 10);
|
|
116
|
+
const prerelease = match[4] || '';
|
|
117
|
+
|
|
118
|
+
if (bumpKind === 'major') return `${major + 1}.0.0${prerelease}`;
|
|
119
|
+
if (bumpKind === 'minor') return `${major}.${minor + 1}.0${prerelease}`;
|
|
120
|
+
return `${major}.${minor}.${patch + 1}${prerelease}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function extractInternalPublishOptions(commandArgs) {
|
|
124
|
+
const sanitizedArgs = [];
|
|
125
|
+
let explicitName = null;
|
|
126
|
+
let explicitVersion = null;
|
|
127
|
+
let yes = false;
|
|
128
|
+
|
|
129
|
+
for (let index = 0; index < commandArgs.length; index += 1) {
|
|
130
|
+
const current = commandArgs[index];
|
|
131
|
+
if (current === '--yes' || current === '-y') {
|
|
132
|
+
yes = true;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (current === '--name') {
|
|
136
|
+
explicitName = commandArgs[index + 1] || '';
|
|
137
|
+
index += 1;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (current.startsWith('--name=')) {
|
|
141
|
+
explicitName = current.slice('--name='.length);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (current === '--version') {
|
|
145
|
+
explicitVersion = commandArgs[index + 1] || '';
|
|
146
|
+
index += 1;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (current.startsWith('--version=')) {
|
|
150
|
+
explicitVersion = current.slice('--version='.length);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
sanitizedArgs.push(current);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
sanitizedArgs,
|
|
158
|
+
explicitName,
|
|
159
|
+
explicitVersion,
|
|
160
|
+
yes,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function extractPublishToken(commandArgs, env = process.env) {
|
|
165
|
+
let explicitToken = null;
|
|
166
|
+
|
|
167
|
+
for (let index = 0; index < commandArgs.length; index += 1) {
|
|
168
|
+
const current = commandArgs[index];
|
|
169
|
+
if (current === '--token') {
|
|
170
|
+
explicitToken = commandArgs[index + 1] || '';
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
if (current.startsWith('--token=')) {
|
|
174
|
+
explicitToken = current.slice('--token='.length);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const envToken = typeof env.NODE_AUTH_TOKEN === 'string' && env.NODE_AUTH_TOKEN.trim().length > 0
|
|
180
|
+
? env.NODE_AUTH_TOKEN.trim()
|
|
181
|
+
: null;
|
|
182
|
+
const normalizedToken = typeof explicitToken === 'string' && explicitToken.trim().length > 0
|
|
183
|
+
? explicitToken.trim()
|
|
184
|
+
: envToken;
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
publishArgs: stripOption(commandArgs, '--token'),
|
|
188
|
+
publishEnv: normalizedToken
|
|
189
|
+
? {
|
|
190
|
+
...env,
|
|
191
|
+
NODE_AUTH_TOKEN: normalizedToken,
|
|
192
|
+
}
|
|
193
|
+
: env,
|
|
194
|
+
publishToken: normalizedToken,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function normalizeRegistryUrl(registryValue) {
|
|
199
|
+
const normalizedValue = String(registryValue || '').trim();
|
|
200
|
+
if (!normalizedValue) {
|
|
201
|
+
return 'https://registry.npmjs.org/';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
const registryUrl = new URL(normalizedValue);
|
|
206
|
+
if (!registryUrl.pathname.endsWith('/')) {
|
|
207
|
+
registryUrl.pathname = `${registryUrl.pathname}/`;
|
|
208
|
+
}
|
|
209
|
+
return registryUrl.toString();
|
|
210
|
+
} catch {
|
|
211
|
+
return 'https://registry.npmjs.org/';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function buildRegistryAuthLine(token, registryUrl) {
|
|
216
|
+
const parsedUrl = new URL(registryUrl);
|
|
217
|
+
const registryPath = parsedUrl.pathname === '/' ? '' : parsedUrl.pathname.replace(/\/$/, '');
|
|
218
|
+
return `//${parsedUrl.host}${registryPath}/:_authToken=${token}`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function createPublishTokenEnv(token, env = process.env) {
|
|
222
|
+
if (!token) {
|
|
223
|
+
return {
|
|
224
|
+
env,
|
|
225
|
+
cleanup() {},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const registryUrl = normalizeRegistryUrl(env.npm_config_registry || env.NPM_CONFIG_REGISTRY);
|
|
230
|
+
const userConfigDir = mkdtempSync(join(tmpdir(), 'aurajs-npm-auth-'));
|
|
231
|
+
const userConfigPath = join(userConfigDir, '.npmrc');
|
|
232
|
+
writeFileSync(
|
|
233
|
+
userConfigPath,
|
|
234
|
+
[
|
|
235
|
+
`registry=${registryUrl}`,
|
|
236
|
+
'always-auth=true',
|
|
237
|
+
buildRegistryAuthLine(token, registryUrl),
|
|
238
|
+
'',
|
|
239
|
+
].join('\n'),
|
|
240
|
+
'utf8',
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
env: {
|
|
245
|
+
...env,
|
|
246
|
+
NODE_AUTH_TOKEN: token,
|
|
247
|
+
NPM_CONFIG_USERCONFIG: userConfigPath,
|
|
248
|
+
npm_config_userconfig: userConfigPath,
|
|
249
|
+
NPM_CONFIG_REGISTRY: registryUrl,
|
|
250
|
+
npm_config_registry: registryUrl,
|
|
251
|
+
},
|
|
252
|
+
cleanup() {
|
|
253
|
+
rmSync(userConfigDir, { recursive: true, force: true });
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function readProjectPackageManifest(projectRoot = process.cwd()) {
|
|
22
259
|
const packagePath = resolve(projectRoot, 'package.json');
|
|
23
260
|
if (!existsSync(packagePath)) {
|
|
24
261
|
throw new Error('aura publish requires a package.json in the current project root.');
|
|
@@ -34,9 +271,6 @@ export function readProjectPackage(projectRoot = process.cwd()) {
|
|
|
34
271
|
const packageName = typeof projectPackage?.name === 'string' && projectPackage.name.trim().length > 0
|
|
35
272
|
? projectPackage.name.trim()
|
|
36
273
|
: null;
|
|
37
|
-
if (!packageName) {
|
|
38
|
-
throw new Error('aura publish requires package.json -> name to be set.');
|
|
39
|
-
}
|
|
40
274
|
|
|
41
275
|
return {
|
|
42
276
|
packagePath,
|
|
@@ -45,9 +279,162 @@ export function readProjectPackage(projectRoot = process.cwd()) {
|
|
|
45
279
|
};
|
|
46
280
|
}
|
|
47
281
|
|
|
282
|
+
export function readProjectPackage(projectRoot = process.cwd()) {
|
|
283
|
+
const projectPackage = readProjectPackageManifest(projectRoot);
|
|
284
|
+
if (!projectPackage.packageName) {
|
|
285
|
+
throw new Error('aura publish requires package.json -> name to be set.');
|
|
286
|
+
}
|
|
287
|
+
return projectPackage;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async function resolvePublishPackageName(
|
|
291
|
+
commandArgs,
|
|
292
|
+
{
|
|
293
|
+
projectRoot = process.cwd(),
|
|
294
|
+
canPromptInteractivelyImpl = canPromptInteractively,
|
|
295
|
+
promptInputImpl = promptInput,
|
|
296
|
+
} = {},
|
|
297
|
+
) {
|
|
298
|
+
const { packagePath, projectPackage, packageName: currentPackageName } = readProjectPackageManifest(projectRoot);
|
|
299
|
+
const { sanitizedArgs, explicitName, yes } = extractInternalPublishOptions(commandArgs);
|
|
300
|
+
const defaultPackageName = buildDefaultPackageName(projectRoot);
|
|
301
|
+
const currentValidPackageName = currentPackageName && isValidPackageName(currentPackageName)
|
|
302
|
+
? ensureScopedPackageName(currentPackageName)
|
|
303
|
+
: null;
|
|
304
|
+
|
|
305
|
+
let targetPackageName = currentPackageName;
|
|
306
|
+
|
|
307
|
+
if (explicitName !== null) {
|
|
308
|
+
targetPackageName = ensureScopedPackageName(explicitName);
|
|
309
|
+
validatePackageName(targetPackageName);
|
|
310
|
+
} else if (yes) {
|
|
311
|
+
targetPackageName = currentPackageName || defaultPackageName;
|
|
312
|
+
validatePackageName(targetPackageName);
|
|
313
|
+
} else if (canPromptInteractivelyImpl()) {
|
|
314
|
+
const fallbackPackageName = currentValidPackageName || defaultPackageName;
|
|
315
|
+
const fallbackDisplay = fallbackPackageName.startsWith('@')
|
|
316
|
+
? fallbackPackageName.slice(1)
|
|
317
|
+
: fallbackPackageName;
|
|
318
|
+
const input = await promptInputImpl(` Package name (default: ${fallbackDisplay})`);
|
|
319
|
+
targetPackageName = ensureScopedPackageName(input || fallbackPackageName);
|
|
320
|
+
validatePackageName(targetPackageName);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (targetPackageName && projectPackage.name !== targetPackageName) {
|
|
324
|
+
projectPackage.name = targetPackageName;
|
|
325
|
+
writeFileSync(packagePath, `${JSON.stringify(projectPackage, null, 2)}\n`, 'utf8');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return {
|
|
329
|
+
publishArgs: sanitizedArgs,
|
|
330
|
+
packageName: targetPackageName,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async function resolvePublishVersion(
|
|
335
|
+
commandArgs,
|
|
336
|
+
{
|
|
337
|
+
projectRoot = process.cwd(),
|
|
338
|
+
canPromptInteractivelyImpl = canPromptInteractively,
|
|
339
|
+
promptSelectImpl = promptSelect,
|
|
340
|
+
promptInputImpl = promptInput,
|
|
341
|
+
} = {},
|
|
342
|
+
) {
|
|
343
|
+
const { packagePath, projectPackage } = readProjectPackage(projectRoot);
|
|
344
|
+
const { sanitizedArgs, explicitVersion, yes } = extractInternalPublishOptions(commandArgs);
|
|
345
|
+
const packageVersion = typeof projectPackage?.version === 'string' && projectPackage.version.trim().length > 0
|
|
346
|
+
? normalizeVersion(projectPackage.version)
|
|
347
|
+
: null;
|
|
348
|
+
const currentVersion = isValidVersion(packageVersion || '') ? packageVersion : null;
|
|
349
|
+
|
|
350
|
+
let targetVersion = packageVersion;
|
|
351
|
+
|
|
352
|
+
if (explicitVersion !== null) {
|
|
353
|
+
const normalized = normalizeVersion(explicitVersion);
|
|
354
|
+
validateVersion(normalized);
|
|
355
|
+
targetVersion = normalized;
|
|
356
|
+
} else if (yes) {
|
|
357
|
+
if (packageVersion) {
|
|
358
|
+
validateVersion(packageVersion);
|
|
359
|
+
targetVersion = packageVersion;
|
|
360
|
+
} else {
|
|
361
|
+
targetVersion = '0.1.0';
|
|
362
|
+
}
|
|
363
|
+
} else if (canPromptInteractivelyImpl()) {
|
|
364
|
+
if (currentVersion) {
|
|
365
|
+
const choice = await promptSelectImpl(
|
|
366
|
+
' Version selection',
|
|
367
|
+
[
|
|
368
|
+
{ value: 'current', label: `Current (${currentVersion})`, aliases: ['c', 'keep'] },
|
|
369
|
+
{ value: 'bump', label: 'Bump version', aliases: ['b'] },
|
|
370
|
+
{ value: 'custom', label: 'Custom version', aliases: ['x'] },
|
|
371
|
+
],
|
|
372
|
+
'current',
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
if (choice === 'bump') {
|
|
376
|
+
const bumpKind = await promptSelectImpl(
|
|
377
|
+
' Bump type',
|
|
378
|
+
[
|
|
379
|
+
{ value: 'patch', label: `Patch (${bumpVersion(currentVersion, 'patch')})`, aliases: ['p'] },
|
|
380
|
+
{ value: 'minor', label: `Minor (${bumpVersion(currentVersion, 'minor')})`, aliases: ['m'] },
|
|
381
|
+
{ value: 'major', label: `Major (${bumpVersion(currentVersion, 'major')})`, aliases: ['M'] },
|
|
382
|
+
],
|
|
383
|
+
'patch',
|
|
384
|
+
);
|
|
385
|
+
targetVersion = bumpVersion(currentVersion, bumpKind);
|
|
386
|
+
} else if (choice === 'custom') {
|
|
387
|
+
while (true) {
|
|
388
|
+
const input = normalizeVersion(await promptInputImpl(' Custom version (semver)'));
|
|
389
|
+
if (!input) {
|
|
390
|
+
console.error(' Version is required.');
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
if (!isValidVersion(input)) {
|
|
394
|
+
console.error(' Invalid version format. Use semver like 1.2.3 or 1.2.3-beta.1');
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
targetVersion = input;
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
const defaultVersion = packageVersion ? '' : '0.1.0';
|
|
403
|
+
const promptLabel = defaultVersion
|
|
404
|
+
? ` Package version (semver, default: ${defaultVersion})`
|
|
405
|
+
: ' Package version (semver)';
|
|
406
|
+
while (true) {
|
|
407
|
+
const input = normalizeVersion(await promptInputImpl(promptLabel));
|
|
408
|
+
const candidate = input || defaultVersion;
|
|
409
|
+
if (!candidate) {
|
|
410
|
+
console.error(' Version is required.');
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
if (!isValidVersion(candidate)) {
|
|
414
|
+
console.error(' Invalid version format. Use semver like 1.2.3 or 1.2.3-beta.1');
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
targetVersion = candidate;
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (targetVersion && projectPackage.version !== targetVersion) {
|
|
424
|
+
projectPackage.version = targetVersion;
|
|
425
|
+
writeFileSync(packagePath, `${JSON.stringify(projectPackage, null, 2)}\n`, 'utf8');
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return {
|
|
429
|
+
publishArgs: sanitizedArgs,
|
|
430
|
+
packageVersion: targetVersion,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
|
|
48
434
|
export function buildPublishArgs(commandArgs, { packageName } = {}) {
|
|
49
|
-
const
|
|
50
|
-
|
|
435
|
+
const sanitizedArgs = stripOption(commandArgs, '--token');
|
|
436
|
+
const publishArgs = ['publish', ...sanitizedArgs];
|
|
437
|
+
if (String(packageName || '').startsWith('@') && !hasOption(sanitizedArgs, '--access')) {
|
|
51
438
|
publishArgs.push('--access', 'public');
|
|
52
439
|
}
|
|
53
440
|
return publishArgs;
|
|
@@ -68,13 +455,10 @@ function spawnPublish(commandArgs, { projectRoot, env, stdout, stderr }) {
|
|
|
68
455
|
return new Promise((resolveRun, rejectRun) => {
|
|
69
456
|
const child = spawn(resolveNpmCommand(), commandArgs, {
|
|
70
457
|
cwd: projectRoot,
|
|
71
|
-
stdio:
|
|
458
|
+
stdio: 'inherit',
|
|
72
459
|
env,
|
|
73
460
|
});
|
|
74
461
|
|
|
75
|
-
pipeChildStream(child.stdout, stdout);
|
|
76
|
-
pipeChildStream(child.stderr, stderr);
|
|
77
|
-
|
|
78
462
|
child.on('error', (error) => {
|
|
79
463
|
rejectRun(error);
|
|
80
464
|
});
|
|
@@ -107,6 +491,9 @@ export async function runPublishCommand(
|
|
|
107
491
|
stdout = process.stdout,
|
|
108
492
|
stderr = process.stderr,
|
|
109
493
|
validateProject = validatePublishProject,
|
|
494
|
+
canPromptInteractivelyImpl = canPromptInteractively,
|
|
495
|
+
promptSelectImpl = promptSelect,
|
|
496
|
+
promptInputImpl = promptInput,
|
|
110
497
|
} = {},
|
|
111
498
|
) {
|
|
112
499
|
if (isNpmPublishLifecycleInvocation(env)) {
|
|
@@ -121,6 +508,19 @@ export async function runPublishCommand(
|
|
|
121
508
|
};
|
|
122
509
|
}
|
|
123
510
|
|
|
511
|
+
await resolvePublishPackageName(commandArgs, {
|
|
512
|
+
projectRoot,
|
|
513
|
+
canPromptInteractivelyImpl,
|
|
514
|
+
promptInputImpl,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
const publishVersionResolution = await resolvePublishVersion(commandArgs, {
|
|
518
|
+
projectRoot,
|
|
519
|
+
canPromptInteractivelyImpl,
|
|
520
|
+
promptSelectImpl,
|
|
521
|
+
promptInputImpl,
|
|
522
|
+
});
|
|
523
|
+
|
|
124
524
|
let validation;
|
|
125
525
|
try {
|
|
126
526
|
validation = await validateProject({
|
|
@@ -134,9 +534,13 @@ export async function runPublishCommand(
|
|
|
134
534
|
const assetBytes = Number.isFinite(error?.details?.assetBytes) ? error.details.assetBytes : null;
|
|
135
535
|
const thresholdBytes = Number.isFinite(error?.details?.thresholdBytes) ? error.details.thresholdBytes : null;
|
|
136
536
|
if (assetBytes !== null && thresholdBytes !== null) {
|
|
137
|
-
stdout?.write(` Asset payload: ${assetBytes}
|
|
537
|
+
stdout?.write(` Asset payload: ${formatBytes(assetBytes)} (${assetBytes} bytes)\n`);
|
|
538
|
+
stdout?.write(` Threshold: ${formatBytes(thresholdBytes)} (${thresholdBytes} bytes)\n`);
|
|
138
539
|
}
|
|
139
|
-
stdout?.write('
|
|
540
|
+
stdout?.write(' This package is too large for npm-first publish.\n');
|
|
541
|
+
stdout?.write(' Self-host for now: upload the heavy assets to your own public HTTPS host, then generate the external asset config.\n');
|
|
542
|
+
stdout?.write(' Command: auramaxx external-assets generate --public-base-url https://cdn.example.com/my-game\n');
|
|
543
|
+
stdout?.write(' Docs: https://www.aurajs.gg/docs/publishing-and-large-assets\n');
|
|
140
544
|
}
|
|
141
545
|
if (error?.reportPath) {
|
|
142
546
|
stdout?.write(` Validation report: ${error.reportPath}\n\n`);
|
|
@@ -146,8 +550,13 @@ export async function runPublishCommand(
|
|
|
146
550
|
|
|
147
551
|
const packageName = validation.packageName;
|
|
148
552
|
const { projectPackage } = readProjectPackage(projectRoot);
|
|
149
|
-
const publishArgs
|
|
150
|
-
|
|
553
|
+
const { publishArgs: sanitizedCommandArgs, publishEnv, publishToken } = extractPublishToken(
|
|
554
|
+
publishVersionResolution.publishArgs,
|
|
555
|
+
env,
|
|
556
|
+
);
|
|
557
|
+
const publishArgs = buildPublishArgs(sanitizedCommandArgs, { packageName });
|
|
558
|
+
const publishTokenEnv = createPublishTokenEnv(publishToken, publishEnv);
|
|
559
|
+
const dryRun = hasOption(sanitizedCommandArgs, '--dry-run');
|
|
151
560
|
const envExampleSurface = resolvePublishEnvExampleSurface({ projectRoot });
|
|
152
561
|
const packageSurface = preparePublishPackageSurface({
|
|
153
562
|
projectRoot,
|
|
@@ -162,9 +571,15 @@ export async function runPublishCommand(
|
|
|
162
571
|
packageRoot: packageSurface.publishRoot,
|
|
163
572
|
signerProjectRoot: projectRoot,
|
|
164
573
|
buildMetadata: validation?.report?.validation?.build || null,
|
|
574
|
+
includedRelativePaths: Array.isArray(validation?.report?.validation?.pack?.files)
|
|
575
|
+
? validation.report.validation.pack.files.map((entry) => entry?.path).filter(Boolean)
|
|
576
|
+
: null,
|
|
165
577
|
});
|
|
166
578
|
stdout?.write(`\n aura publish: ${dryRun ? 'dry-run' : 'npm-first publish'}\n`);
|
|
167
579
|
stdout?.write(` Package: ${packageName}\n`);
|
|
580
|
+
if (publishVersionResolution.packageVersion) {
|
|
581
|
+
stdout?.write(` Version: ${publishVersionResolution.packageVersion}\n`);
|
|
582
|
+
}
|
|
168
583
|
stdout?.write(` Validation report: ${validation.reportPath}\n`);
|
|
169
584
|
if (Number.isFinite(validation?.report?.validation?.assets?.assetBytes)) {
|
|
170
585
|
const assets = validation.report.validation.assets;
|
|
@@ -176,11 +591,12 @@ export async function runPublishCommand(
|
|
|
176
591
|
try {
|
|
177
592
|
await spawnPublish(publishArgs, {
|
|
178
593
|
projectRoot: packageSurface.publishRoot,
|
|
179
|
-
env,
|
|
594
|
+
env: publishTokenEnv.env,
|
|
180
595
|
stdout,
|
|
181
596
|
stderr,
|
|
182
597
|
});
|
|
183
598
|
} finally {
|
|
599
|
+
publishTokenEnv.cleanup();
|
|
184
600
|
packageSurface.cleanup();
|
|
185
601
|
}
|
|
186
602
|
|
|
@@ -189,6 +605,7 @@ export async function runPublishCommand(
|
|
|
189
605
|
skipped: false,
|
|
190
606
|
reasonCode: dryRun ? 'publish_dry_run_ok' : 'publish_ok',
|
|
191
607
|
packageName,
|
|
608
|
+
packageVersion: publishVersionResolution.packageVersion || validation.packageVersion || null,
|
|
192
609
|
reportPath: validation.reportPath,
|
|
193
610
|
publishArgs,
|
|
194
611
|
};
|
|
@@ -401,12 +401,16 @@ export async function validatePublishProject(
|
|
|
401
401
|
);
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
+
const expectedAurajsVersion = typeof projectPackage?.dependencies?.['@auraindustry/aurajs'] === 'string'
|
|
405
|
+
? projectPackage.dependencies['@auraindustry/aurajs'].trim()
|
|
406
|
+
: null;
|
|
407
|
+
|
|
404
408
|
const binIntegrity = assertProjectBinIntegrity({
|
|
405
409
|
projectRoot,
|
|
406
410
|
projectPackage,
|
|
407
411
|
packageName,
|
|
408
412
|
aurajsPackageRoot: DEFAULT_AURAJS_PACKAGE_ROOT,
|
|
409
|
-
expectedAurajsVersion
|
|
413
|
+
expectedAurajsVersion,
|
|
410
414
|
enforceExactAurajsDependency: true,
|
|
411
415
|
});
|
|
412
416
|
report.validation.binIntegrity = {
|
|
@@ -566,20 +570,11 @@ export async function validatePublishProject(
|
|
|
566
570
|
);
|
|
567
571
|
}
|
|
568
572
|
|
|
569
|
-
|
|
573
|
+
let packageIntegrity = writeSignedPackageIntegrityArtifacts({
|
|
570
574
|
packageRoot: packageSurface.publishRoot,
|
|
571
575
|
signerProjectRoot: projectRoot,
|
|
572
576
|
buildMetadata,
|
|
573
577
|
});
|
|
574
|
-
report.validation.packageIntegrity = {
|
|
575
|
-
reasonCode: 'publish_package_integrity_ok',
|
|
576
|
-
manifestPath: packageIntegrity.manifestPath,
|
|
577
|
-
signaturePath: packageIntegrity.signaturePath,
|
|
578
|
-
schema: packageIntegrity.schema,
|
|
579
|
-
fileCount: packageIntegrity.fileCount,
|
|
580
|
-
signerFingerprint: packageIntegrity.signerFingerprint,
|
|
581
|
-
publishedMetadata: packageIntegrity.publishedMetadata,
|
|
582
|
-
};
|
|
583
578
|
|
|
584
579
|
assetThresholdRecord.packageSurfaceMode = packageSurface.mode;
|
|
585
580
|
assetThresholdRecord.assetPackaging = packageSurface.mode === SELF_HOSTED_PACKAGE_SURFACE_MODE
|
|
@@ -664,6 +659,22 @@ export async function validatePublishProject(
|
|
|
664
659
|
files: packFiles,
|
|
665
660
|
};
|
|
666
661
|
|
|
662
|
+
packageIntegrity = writeSignedPackageIntegrityArtifacts({
|
|
663
|
+
packageRoot: packageSurface.publishRoot,
|
|
664
|
+
signerProjectRoot: projectRoot,
|
|
665
|
+
buildMetadata,
|
|
666
|
+
includedRelativePaths: packFiles.map((entry) => entry.path),
|
|
667
|
+
});
|
|
668
|
+
report.validation.packageIntegrity = {
|
|
669
|
+
reasonCode: 'publish_package_integrity_ok',
|
|
670
|
+
manifestPath: packageIntegrity.manifestPath,
|
|
671
|
+
signaturePath: packageIntegrity.signaturePath,
|
|
672
|
+
schema: packageIntegrity.schema,
|
|
673
|
+
fileCount: packageIntegrity.fileCount,
|
|
674
|
+
signerFingerprint: packageIntegrity.signerFingerprint,
|
|
675
|
+
publishedMetadata: packageIntegrity.publishedMetadata,
|
|
676
|
+
};
|
|
677
|
+
|
|
667
678
|
report.summary = {
|
|
668
679
|
pass: true,
|
|
669
680
|
reasonCode: 'publish_validation_ok',
|