@norrix/cli 0.0.32 → 0.0.34
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 +63 -0
- package/dist/lib/commands.js +35 -7
- package/dist/lib/commands.js.map +1 -1
- package/dist/lib/config.js +38 -10
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/fingerprinting.d.ts +45 -0
- package/dist/lib/fingerprinting.js +352 -5
- package/dist/lib/fingerprinting.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# @norrix/cli
|
|
2
|
+
|
|
3
|
+
Cloud build, OTA updates, and app store submissions for NativeScript apps.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @norrix/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Sign in to your account
|
|
15
|
+
norrix sign-in
|
|
16
|
+
|
|
17
|
+
# Build your app
|
|
18
|
+
norrix build android release
|
|
19
|
+
norrix build ios release appstore
|
|
20
|
+
norrix build visionos release appstore
|
|
21
|
+
|
|
22
|
+
# Publish OTA updates
|
|
23
|
+
norrix update android
|
|
24
|
+
norrix update ios
|
|
25
|
+
norrix update visionos
|
|
26
|
+
|
|
27
|
+
# Submit to app stores
|
|
28
|
+
norrix submit android production
|
|
29
|
+
norrix submit ios
|
|
30
|
+
norrix submit visionos
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
| Command | Description |
|
|
36
|
+
|---------|-------------|
|
|
37
|
+
| `build` | Build your app in the cloud |
|
|
38
|
+
| `update` | Publish OTA updates |
|
|
39
|
+
| `submit` | Submit to App Store / Google Play |
|
|
40
|
+
| `fingerprint` | Print or compare native fingerprints |
|
|
41
|
+
| `env` | Manage build environment variables |
|
|
42
|
+
| `orgs` | Manage organizations |
|
|
43
|
+
| `sign-in` | Authenticate with Norrix |
|
|
44
|
+
| `sign-out` | Sign out |
|
|
45
|
+
| `whoami` | Show current user |
|
|
46
|
+
|
|
47
|
+
## Global Options
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
--env <env> Target environment (prod, dev)
|
|
51
|
+
--dev Shortcut for --env dev
|
|
52
|
+
--verbose Enable verbose output
|
|
53
|
+
--help Display help
|
|
54
|
+
--version Display version
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Documentation
|
|
58
|
+
|
|
59
|
+
Full CLI reference and guides: **[docs.norrix.net/cli](https://docs.norrix.net/cli/)**
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT
|
package/dist/lib/commands.js
CHANGED
|
@@ -8,7 +8,7 @@ import { fileURLToPath } from 'url';
|
|
|
8
8
|
import archiver from 'archiver';
|
|
9
9
|
// import FormData from 'form-data';
|
|
10
10
|
import { configureAmplify, loadCliEnvFiles } from './amplify-config.js';
|
|
11
|
-
import { computeFingerprint,
|
|
11
|
+
import { computeFingerprint, embedFingerprintInNativeResources, embedVersionInNativeResources } from './fingerprinting.js';
|
|
12
12
|
import { loadNorrixConfig, hasNorrixConfig, saveNorrixConfig } from './config.js';
|
|
13
13
|
import { detectWorkspaceContext, getNxProjectDependencies, getWorkspaceDependenciesFallback, createWorkspaceManifest, logWorkspaceContext, isAtWorkspaceRoot, discoverNativeScriptApps, getWorkspaceContextForApp, detectNxBuildConfigurations, } from './workspace.js';
|
|
14
14
|
import { signIn as amplifySignIn, signOut as amplifySignOut, getCurrentUser, fetchAuthSession, } from 'aws-amplify/auth';
|
|
@@ -205,14 +205,16 @@ async function ensureOrgSelected(params) {
|
|
|
205
205
|
export async function orgsList(verbose = false) {
|
|
206
206
|
ensureInitialized();
|
|
207
207
|
try {
|
|
208
|
-
const { organizations
|
|
208
|
+
const { organizations } = await fetchOrganizations(verbose);
|
|
209
209
|
if (!organizations.length) {
|
|
210
210
|
console.log('No organizations found.');
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
|
+
// Use locally stored org selection (same source as orgsCurrent)
|
|
214
|
+
const localSelectedOrgId = CURRENT_ORG_ID || getSelectedOrgId(CURRENT_ENV, API_URL);
|
|
213
215
|
console.log('Organizations:');
|
|
214
216
|
for (const o of organizations) {
|
|
215
|
-
const selectedMark =
|
|
217
|
+
const selectedMark = localSelectedOrgId && o.id === localSelectedOrgId ? ' (selected)' : '';
|
|
216
218
|
console.log(`- ${o.name} [${o.role}] ${o.id}${selectedMark}`);
|
|
217
219
|
}
|
|
218
220
|
}
|
|
@@ -1424,9 +1426,9 @@ export async function build(cliPlatformArg, cliConfigurationArg, cliDistribution
|
|
|
1424
1426
|
]);
|
|
1425
1427
|
platform = chosenPlatform;
|
|
1426
1428
|
}
|
|
1427
|
-
// 2.1 Determine configuration (CLI arg preferred, otherwise prompt)
|
|
1429
|
+
// 2.1 Determine configuration (CLI arg preferred, then config, otherwise prompt)
|
|
1428
1430
|
const validConfigurations = ['debug', 'release'];
|
|
1429
|
-
let configuration = (cliConfigurationArg || '').toLowerCase();
|
|
1431
|
+
let configuration = (cliConfigurationArg || norrixConfig.defaultConfiguration || '').toLowerCase();
|
|
1430
1432
|
if (!validConfigurations.includes(configuration)) {
|
|
1431
1433
|
if (opts.nonInteractive) {
|
|
1432
1434
|
// Default to 'debug' in non-interactive mode if not specified
|
|
@@ -1440,7 +1442,7 @@ export async function build(cliPlatformArg, cliConfigurationArg, cliDistribution
|
|
|
1440
1442
|
name: 'configuration',
|
|
1441
1443
|
message: 'Build configuration:',
|
|
1442
1444
|
choices: validConfigurations,
|
|
1443
|
-
default: 'debug',
|
|
1445
|
+
default: norrixConfig.defaultConfiguration || 'debug',
|
|
1444
1446
|
},
|
|
1445
1447
|
]);
|
|
1446
1448
|
configuration = answer.configuration;
|
|
@@ -1908,7 +1910,33 @@ export async function build(cliPlatformArg, cliConfigurationArg, cliDistribution
|
|
|
1908
1910
|
projectRoot,
|
|
1909
1911
|
platform,
|
|
1910
1912
|
});
|
|
1911
|
-
|
|
1913
|
+
// Embed fingerprint in native resources (Info.plist for iOS, app.gradle for Android)
|
|
1914
|
+
// This ensures the fingerprint is baked into the binary and cannot diverge from
|
|
1915
|
+
// what's recorded in the database. The fingerprint in native resources is the
|
|
1916
|
+
// single source of truth that the client SDK will read at runtime.
|
|
1917
|
+
const embeddedPaths = embedFingerprintInNativeResources(projectRoot, fingerprint, platform);
|
|
1918
|
+
if (verbose) {
|
|
1919
|
+
if (embeddedPaths.infoPlistPath) {
|
|
1920
|
+
console.log(`[fingerprint] Embedded hash in Info.plist: ${embeddedPaths.infoPlistPath}`);
|
|
1921
|
+
}
|
|
1922
|
+
if (embeddedPaths.appGradlePath) {
|
|
1923
|
+
console.log(`[fingerprint] Embedded hash in app.gradle: ${embeddedPaths.appGradlePath}`);
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
// Embed version and build number in native resources
|
|
1927
|
+
// This ensures the binary (IPA/APK/AAB) reflects the version specified at build time.
|
|
1928
|
+
// The fingerprint remains stable because version fields are normalized out during hashing.
|
|
1929
|
+
if (version && buildNumber) {
|
|
1930
|
+
const versionEmbedPaths = embedVersionInNativeResources(projectRoot, version, buildNumber, platform);
|
|
1931
|
+
if (verbose) {
|
|
1932
|
+
if (versionEmbedPaths.infoPlistPath) {
|
|
1933
|
+
console.log(`[version] Embedded v${version} (${buildNumber}) in Info.plist: ${versionEmbedPaths.infoPlistPath}`);
|
|
1934
|
+
}
|
|
1935
|
+
if (versionEmbedPaths.appGradlePath) {
|
|
1936
|
+
console.log(`[version] Embedded v${version} (${buildNumber}) in app.gradle: ${versionEmbedPaths.appGradlePath}`);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1912
1940
|
spinner.start('Creating project archive...');
|
|
1913
1941
|
// 3. Zip the project (workspace-aware)
|
|
1914
1942
|
const { zipPath, workspaceContext } = await zipProject(projectName, workspaceCtx, false, verbose);
|