@helix3/helix-cli 0.1.18-helix3.291 → 0.1.18-helix3.293
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +2 -0
- package/dist/config.js +31 -12
- package/dist/config.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +6 -0
- package/dist/lib.js +50 -0
- package/dist/lib.js.map +1 -1
- package/dist/publishDuplicateGuard.d.ts +73 -0
- package/dist/publishDuplicateGuard.js +94 -0
- package/dist/publishDuplicateGuard.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
package/dist/config.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type CliCredentials = {
|
|
|
4
4
|
expiresAt: string;
|
|
5
5
|
username: string;
|
|
6
6
|
};
|
|
7
|
+
export declare const CONFIG_DIR: string;
|
|
7
8
|
type HelixEnvName = 'staging' | 'helix3' | 'production';
|
|
8
9
|
export declare function resolveEnvironment(scope: string, override?: {
|
|
9
10
|
apiUrl?: string;
|
|
@@ -28,4 +29,5 @@ export declare function saveCredentials(creds: CliCredentials): void;
|
|
|
28
29
|
export declare function loadCredentials(): CliCredentials | null;
|
|
29
30
|
export declare function clearCredentials(): void;
|
|
30
31
|
export declare function jwtExpiresAtIso(token: string): string;
|
|
32
|
+
export declare function jwtSubject(token: string): string | null;
|
|
31
33
|
export {};
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_WEB_URL = exports.DEFAULT_API_URL = exports.HELIX_ENV = exports.HELIX_SCOPE = void 0;
|
|
3
|
+
exports.DEFAULT_WEB_URL = exports.DEFAULT_API_URL = exports.HELIX_ENV = exports.HELIX_SCOPE = exports.CONFIG_DIR = void 0;
|
|
4
4
|
exports.resolveEnvironment = resolveEnvironment;
|
|
5
5
|
exports.apiUrlMatchesEnv = apiUrlMatchesEnv;
|
|
6
6
|
exports.credsEnvMismatchWarning = credsEnvMismatchWarning;
|
|
@@ -8,12 +8,16 @@ exports.saveCredentials = saveCredentials;
|
|
|
8
8
|
exports.loadCredentials = loadCredentials;
|
|
9
9
|
exports.clearCredentials = clearCredentials;
|
|
10
10
|
exports.jwtExpiresAtIso = jwtExpiresAtIso;
|
|
11
|
+
exports.jwtSubject = jwtSubject;
|
|
11
12
|
const node_fs_1 = require("node:fs");
|
|
12
13
|
const node_os_1 = require("node:os");
|
|
13
14
|
const node_path_1 = require("node:path");
|
|
14
15
|
const browserLogin_1 = require("./browserLogin");
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
// Exported so other local-only CLI state (e.g. publishDuplicateGuard.ts's publish-history cache)
|
|
17
|
+
// lives beside credentials.json under the same per-machine directory, instead of each module
|
|
18
|
+
// inventing its own.
|
|
19
|
+
exports.CONFIG_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), '.helix');
|
|
20
|
+
const CREDENTIALS_FILE = (0, node_path_1.join)(exports.CONFIG_DIR, 'credentials.json');
|
|
17
21
|
// The npm scope this build was published under selects its default environment:
|
|
18
22
|
// non-prod lanes republish every @helix package under their scope (@helixdev = staging,
|
|
19
23
|
// @helix3 = helix3 — see publish-npm.mjs), production stays @hypersoniclabs. Read from our
|
|
@@ -90,7 +94,7 @@ function credsEnvMismatchWarning(credsApiUrl, env = {
|
|
|
90
94
|
`(Custom backend on purpose? Set HELIX_API_URL=${credsApiUrl} so this build targets it explicitly.)`);
|
|
91
95
|
}
|
|
92
96
|
function saveCredentials(creds) {
|
|
93
|
-
(0, node_fs_1.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
97
|
+
(0, node_fs_1.mkdirSync)(exports.CONFIG_DIR, { recursive: true });
|
|
94
98
|
(0, node_fs_1.writeFileSync)(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), {
|
|
95
99
|
mode: 0o600,
|
|
96
100
|
});
|
|
@@ -121,20 +125,35 @@ function clearCredentials() {
|
|
|
121
125
|
// nothing stored — already logged out.
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
+
// Decodes a JWT's payload claims without verifying its signature — every reader below only
|
|
129
|
+
// needs a friendly local value (an expiry to display, a subject to scope a query by), never an
|
|
130
|
+
// authorization decision, so an unverified read is the right tool: the server is still the one
|
|
131
|
+
// enforcing the token on every real request. Returns null for anything that isn't a
|
|
132
|
+
// three-segment, base64url-JSON token.
|
|
133
|
+
function decodeJwtPayload(token) {
|
|
128
134
|
try {
|
|
129
135
|
const payload = token.split('.')[1];
|
|
130
136
|
if (!payload)
|
|
131
|
-
return
|
|
137
|
+
return null;
|
|
132
138
|
const json = Buffer.from(payload, 'base64url').toString('utf8');
|
|
133
|
-
const
|
|
134
|
-
return typeof
|
|
139
|
+
const parsed = JSON.parse(json);
|
|
140
|
+
return typeof parsed === 'object' && parsed !== null ? parsed : null;
|
|
135
141
|
}
|
|
136
142
|
catch {
|
|
137
|
-
return
|
|
143
|
+
return null;
|
|
138
144
|
}
|
|
139
145
|
}
|
|
146
|
+
// Reads the `exp` (seconds) claim from a JWT — just to surface a friendly expiry to the user and
|
|
147
|
+
// to expire the stored credentials locally. Returns '' if the token is not a decodable JWT.
|
|
148
|
+
function jwtExpiresAtIso(token) {
|
|
149
|
+
const exp = decodeJwtPayload(token)?.exp;
|
|
150
|
+
return typeof exp === 'number' ? new Date(exp * 1000).toISOString() : '';
|
|
151
|
+
}
|
|
152
|
+
// Reads the `sub` (subject — the authenticated user/creator id) claim from a JWT. Used to scope a
|
|
153
|
+
// query to "items this account owns" without a dedicated `/me` lookup for every caller that needs
|
|
154
|
+
// it. Returns null if the token is not a decodable JWT or carries no string `sub`.
|
|
155
|
+
function jwtSubject(token) {
|
|
156
|
+
const sub = decodeJwtPayload(token)?.sub;
|
|
157
|
+
return typeof sub === 'string' && sub.trim() !== '' ? sub : null;
|
|
158
|
+
}
|
|
140
159
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1475,6 +1475,7 @@ item
|
|
|
1475
1475
|
.option('--ends-at <iso>', 'initial route end time (ISO-8601)')
|
|
1476
1476
|
.option('--tags <a,b,c>', 'comma-separated search keywords')
|
|
1477
1477
|
.option('--allow-oversize', 'relax the mesh size/polycount ceilings for a deliberately heavy asset')
|
|
1478
|
+
.option('--allow-duplicate', 'skip the add_on duplicate guard (refuses when you already have a live add-on with this exact title+slot, or this exact mesh)')
|
|
1478
1479
|
.option('--dry-run', 'validate everything locally and print what WOULD be sent; no upload, no fee')
|
|
1479
1480
|
.option('--quote', 'request the server-owned publish/issuance quote; no upload or fee')
|
|
1480
1481
|
.option('--json', 'machine-readable output')
|
|
@@ -1514,6 +1515,7 @@ item
|
|
|
1514
1515
|
initialDistribution: initialDistributionFromFlags(opts),
|
|
1515
1516
|
tags: opts.tags !== undefined ? (0, lib_1.parseTags)(opts.tags) : undefined,
|
|
1516
1517
|
allowOversize: opts.allowOversize === true,
|
|
1518
|
+
allowDuplicate: opts.allowDuplicate === true,
|
|
1517
1519
|
};
|
|
1518
1520
|
if (opts.dryRun && opts.quote)
|
|
1519
1521
|
fail('✖ choose --dry-run (offline) or --quote (server-owned fees), not both');
|