@norrix/cli 0.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/dist/cli.d.ts +2 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/amplify-config.d.ts +1 -0
- package/dist/lib/amplify-config.js +140 -0
- package/dist/lib/amplify-config.js.map +1 -0
- package/dist/lib/commands.d.ts +48 -0
- package/dist/lib/commands.js +788 -0
- package/dist/lib/commands.js.map +1 -0
- package/dist/lib/norrix-cli.d.ts +1 -0
- package/dist/lib/norrix-cli.js +4 -0
- package/dist/lib/norrix-cli.js.map +1 -0
- package/package.json +38 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { build, submit, update, buildStatus, submitStatus, updateStatus, signIn, signOut, uploadFile, currentUser, } from './lib/commands.js';
|
|
4
|
+
/**
|
|
5
|
+
* Norrix CLI
|
|
6
|
+
*
|
|
7
|
+
* Command-line interface to interact with the Norrix platform.
|
|
8
|
+
* All commands are routed through the Next.js API, which handles:
|
|
9
|
+
* - Authentication
|
|
10
|
+
* - Rate limiting
|
|
11
|
+
* - Input validation
|
|
12
|
+
*
|
|
13
|
+
* This CLI can be used in development workflows, CI/CD, and local tooling.
|
|
14
|
+
*/
|
|
15
|
+
const program = new Command();
|
|
16
|
+
program
|
|
17
|
+
.name('norrix')
|
|
18
|
+
.description('Norrix CLI - NativeScript build and deployment tool')
|
|
19
|
+
.version('0.0.1');
|
|
20
|
+
program
|
|
21
|
+
.command('build')
|
|
22
|
+
.description('Build your NativeScript app')
|
|
23
|
+
.action(build);
|
|
24
|
+
program
|
|
25
|
+
.command('build-status')
|
|
26
|
+
.description('Check the status of a build')
|
|
27
|
+
.argument('<buildId>', 'Build ID to check')
|
|
28
|
+
.action(buildStatus);
|
|
29
|
+
program
|
|
30
|
+
.command('submit')
|
|
31
|
+
.description('Submit your app to app stores')
|
|
32
|
+
.action(submit);
|
|
33
|
+
program
|
|
34
|
+
.command('submit-status')
|
|
35
|
+
.description('Check the status of a submission')
|
|
36
|
+
.argument('<submitId>', 'Submission ID to check')
|
|
37
|
+
.action(submitStatus);
|
|
38
|
+
program
|
|
39
|
+
.command('update')
|
|
40
|
+
.description('Publish over-the-air updates to deployed apps')
|
|
41
|
+
.action(update);
|
|
42
|
+
program
|
|
43
|
+
.command('update-status')
|
|
44
|
+
.description('Check the status of an update')
|
|
45
|
+
.argument('<updateId>', 'Update ID to check')
|
|
46
|
+
.action(updateStatus);
|
|
47
|
+
// Authentication commands
|
|
48
|
+
program
|
|
49
|
+
.command('sign-in')
|
|
50
|
+
.aliases(['login'])
|
|
51
|
+
.description('Authenticate with your Norrix account')
|
|
52
|
+
.action(signIn);
|
|
53
|
+
program
|
|
54
|
+
.command('sign-out')
|
|
55
|
+
.aliases(['logout'])
|
|
56
|
+
.description('Sign out of your Norrix account')
|
|
57
|
+
.action(signOut);
|
|
58
|
+
// Storage upload command
|
|
59
|
+
program
|
|
60
|
+
.command('upload')
|
|
61
|
+
.description('Upload a file to your Norrix storage bucket')
|
|
62
|
+
.argument('<filePath>', 'Path to the file to upload')
|
|
63
|
+
.option('-k, --key <key>', 'Custom S3 key (defaults to the file name)')
|
|
64
|
+
.action((filePath, options) => uploadFile(filePath, options));
|
|
65
|
+
// Current user info
|
|
66
|
+
program
|
|
67
|
+
.command('whoami')
|
|
68
|
+
.description('Show the currently signed-in user')
|
|
69
|
+
.action(currentUser);
|
|
70
|
+
program.parse();
|
|
71
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,KAAK,EACL,MAAM,EACN,MAAM,EACN,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,MAAM,EACN,OAAO,EACP,UAAU,EACV,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;GAUG;AAEH,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,qDAAqD,CAAC;KAClE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,KAAK,CAAC,CAAC;AAEjB,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;KAC1C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,MAAM,CAAC,CAAC;AAElB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,QAAQ,CAAC,YAAY,EAAE,wBAAwB,CAAC;KAChD,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,MAAM,CAAC,CAAC;AAElB,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;KAC5C,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,0BAA0B;AAC1B,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC;KAClB,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,MAAM,CAAC,CAAC;AAElB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;KACnB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,OAAO,CAAC,CAAC;AAEnB,yBAAyB;AACzB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,QAAQ,CAAC,YAAY,EAAE,4BAA4B,CAAC;KACpD,MAAM,CAAC,iBAAiB,EAAE,2CAA2C,CAAC;KACtE,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAEhE,oBAAoB;AACpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function configureAmplify(): void;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { config as dotenvConfig } from 'dotenv';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { cognitoUserPoolsTokenProvider } from 'aws-amplify/auth/cognito';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
// Load environment variables
|
|
8
|
+
// 1. Load .env (if present)
|
|
9
|
+
dotenvConfig();
|
|
10
|
+
// 2. If .env.local exists, load it and override existing variables
|
|
11
|
+
const envLocalPath = path.resolve(process.cwd(), '.env.local');
|
|
12
|
+
if (fs.existsSync(envLocalPath)) {
|
|
13
|
+
dotenvConfig({ path: envLocalPath, override: true });
|
|
14
|
+
}
|
|
15
|
+
// 3. Fallback: look for env files relative to this package (useful when running from monorepo root)
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirnameResolved = path.dirname(__filename);
|
|
18
|
+
const packageRoot = path.resolve(__dirnameResolved, '..', '..');
|
|
19
|
+
['.env', '.env.local'].forEach((file) => {
|
|
20
|
+
const fullPath = path.join(packageRoot, file);
|
|
21
|
+
if (fs.existsSync(fullPath)) {
|
|
22
|
+
dotenvConfig({ path: fullPath, override: true });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
import { Amplify } from 'aws-amplify';
|
|
26
|
+
// Amplify configuration tailored for the Norrix CLI
|
|
27
|
+
// Values are read from environment variables so that the CLI can be used in multiple environments
|
|
28
|
+
// For local development, you can create a .env file or export these variables in your shell.
|
|
29
|
+
//
|
|
30
|
+
// Environment variable precedence:
|
|
31
|
+
// 1. NORRIX_* variables (CLI-specific)
|
|
32
|
+
// 2. NEXT_PUBLIC_* variables (shared with next-app)
|
|
33
|
+
//
|
|
34
|
+
// Only the minimum settings required for email/password auth (Cognito) and S3 storage are included.
|
|
35
|
+
const amplifyConfig = {
|
|
36
|
+
Auth: {
|
|
37
|
+
Cognito: {
|
|
38
|
+
userPoolId: process.env.NORRIX_AUTH_COGNITO_USER_POOL_ID ||
|
|
39
|
+
process.env.NEXT_PUBLIC_AUTH_COGNITO_USER_POOL_ID ||
|
|
40
|
+
'',
|
|
41
|
+
userPoolClientId: process.env.NORRIX_AUTH_COGNITO_ID ||
|
|
42
|
+
process.env.NEXT_PUBLIC_AUTH_COGNITO_ID ||
|
|
43
|
+
'',
|
|
44
|
+
// Required for AWS credentials (S3 access)
|
|
45
|
+
identityPoolId: process.env.NORRIX_AUTH_COGNITO_IDENTITY_POOL_ID ||
|
|
46
|
+
process.env.NEXT_PUBLIC_AUTH_COGNITO_IDENTITY_POOL_ID ||
|
|
47
|
+
'',
|
|
48
|
+
region: process.env.NORRIX_AUTH_COGNITO_REGION ||
|
|
49
|
+
process.env.NEXT_PUBLIC_AUTH_COGNITO_REGION ||
|
|
50
|
+
'us-east-2',
|
|
51
|
+
// We only enable email login for the CLI
|
|
52
|
+
loginWith: {
|
|
53
|
+
email: true,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
Storage: {
|
|
58
|
+
S3: {
|
|
59
|
+
bucket: process.env.NORRIX_STORAGE_BUCKET_NAME ||
|
|
60
|
+
process.env.NEXT_PUBLIC_STORAGE_BUCKET_NAME ||
|
|
61
|
+
'',
|
|
62
|
+
region: process.env.NORRIX_STORAGE_BUCKET_REGION ||
|
|
63
|
+
process.env.NEXT_PUBLIC_STORAGE_BUCKET_REGION ||
|
|
64
|
+
'us-east-2',
|
|
65
|
+
defaultAccessLevel: 'private',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
// -----------------------------------------------------------------------------
|
|
70
|
+
// Persistent storage for AWS Amplify tokens (Node-only)
|
|
71
|
+
// -----------------------------------------------------------------------------
|
|
72
|
+
// Amplify JS defaults to an in-memory storage when running in a Node environment
|
|
73
|
+
// which means authentication tokens are lost when the process exits. The CLI,
|
|
74
|
+
// however, launches a **new** Node process for every command, so we need a
|
|
75
|
+
// storage layer that survives between invocations.
|
|
76
|
+
//
|
|
77
|
+
// The FileKeyValueStorage class implements Amplify’s `KeyValueStorageInterface`
|
|
78
|
+
// and stores the tokens in a simple JSON file under the user’s home directory
|
|
79
|
+
// (e.g. ~/.config/norrix/cli-auth.json).
|
|
80
|
+
// -----------------------------------------------------------------------------
|
|
81
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'norrix');
|
|
82
|
+
const STORAGE_FILE = path.join(CONFIG_DIR, 'cli-auth.json');
|
|
83
|
+
/**
|
|
84
|
+
* Minimal file-backed key/value store compatible with Amplify v6
|
|
85
|
+
*/
|
|
86
|
+
class FileKeyValueStorage {
|
|
87
|
+
/** Ensure ~/.config/norrix exists */
|
|
88
|
+
ensureDir() {
|
|
89
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
/** Read the entire JSON blob (returns empty object if missing / invalid) */
|
|
92
|
+
read() {
|
|
93
|
+
try {
|
|
94
|
+
if (fs.existsSync(STORAGE_FILE)) {
|
|
95
|
+
return JSON.parse(fs.readFileSync(STORAGE_FILE, 'utf-8'));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
/* ignore */
|
|
100
|
+
}
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
/** Write the supplied object back to disk */
|
|
104
|
+
write(data) {
|
|
105
|
+
this.ensureDir();
|
|
106
|
+
fs.writeFileSync(STORAGE_FILE, JSON.stringify(data, null, 2), 'utf-8');
|
|
107
|
+
}
|
|
108
|
+
async getItem(key) {
|
|
109
|
+
const data = this.read();
|
|
110
|
+
return Object.prototype.hasOwnProperty.call(data, key) ? data[key] : null;
|
|
111
|
+
}
|
|
112
|
+
async setItem(key, value) {
|
|
113
|
+
const data = this.read();
|
|
114
|
+
data[key] = value;
|
|
115
|
+
this.write(data);
|
|
116
|
+
}
|
|
117
|
+
async removeItem(key) {
|
|
118
|
+
const data = this.read();
|
|
119
|
+
delete data[key];
|
|
120
|
+
this.write(data);
|
|
121
|
+
}
|
|
122
|
+
async clear() {
|
|
123
|
+
this.write({});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Instantiate the storage once so every command in the same process reuses it.
|
|
127
|
+
const persistentStorage = new FileKeyValueStorage();
|
|
128
|
+
export function configureAmplify() {
|
|
129
|
+
// Configure is idempotent; calling it multiple times is safe
|
|
130
|
+
Amplify.configure({
|
|
131
|
+
...amplifyConfig,
|
|
132
|
+
// Expose the storage at the root level as well (belt & suspenders)
|
|
133
|
+
storage: persistentStorage,
|
|
134
|
+
});
|
|
135
|
+
// Point the token provider at the same storage *after* configuration. The
|
|
136
|
+
// Amplify Auth category re-initialises its providers during `configure()`,
|
|
137
|
+
// so setting the storage afterwards guarantees our implementation sticks.
|
|
138
|
+
cognitoUserPoolsTokenProvider.setKeyValueStorage(persistentStorage);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=amplify-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amplify-config.js","sourceRoot":"","sources":["../../src/lib/amplify-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build command implementation
|
|
3
|
+
* Uploads project to S3 and triggers build via the Next.js API gateway -> WarpBuild
|
|
4
|
+
*/
|
|
5
|
+
export declare function build(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Submit command implementation
|
|
8
|
+
* Submits the built app to app stores via the Next.js API gateway
|
|
9
|
+
*/
|
|
10
|
+
export declare function submit(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Update command implementation
|
|
13
|
+
* Publishes over-the-air updates to deployed apps via the Next.js API gateway
|
|
14
|
+
*/
|
|
15
|
+
export declare function update(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Build Status command implementation
|
|
18
|
+
* Checks the status of a build via the Next.js API gateway
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildStatus(buildId: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Submit Status command implementation
|
|
23
|
+
* Checks the status of a submission via the Next.js API gateway
|
|
24
|
+
*/
|
|
25
|
+
export declare function submitStatus(submitId: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Update Status command implementation
|
|
28
|
+
* Checks the status of an update via the Next.js API gateway
|
|
29
|
+
*/
|
|
30
|
+
export declare function updateStatus(updateId: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Sign-In command implementation (email / password via Cognito)
|
|
33
|
+
*/
|
|
34
|
+
export declare function signIn(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Sign-Out command implementation
|
|
37
|
+
*/
|
|
38
|
+
export declare function signOut(): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Upload a file to S3 via Amplify Storage
|
|
41
|
+
*/
|
|
42
|
+
export declare function uploadFile(filePath: string, options: {
|
|
43
|
+
key?: string;
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Current User command implementation
|
|
47
|
+
*/
|
|
48
|
+
export declare function currentUser(): Promise<void>;
|
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import archiver from 'archiver';
|
|
8
|
+
// import FormData from 'form-data';
|
|
9
|
+
import { configureAmplify } from './amplify-config.js';
|
|
10
|
+
import { signIn as amplifySignIn, signOut as amplifySignOut, getCurrentUser, fetchAuthSession, } from 'aws-amplify/auth';
|
|
11
|
+
import { uploadData } from 'aws-amplify/storage';
|
|
12
|
+
import crypto from 'crypto';
|
|
13
|
+
// Initialize Amplify once at startup
|
|
14
|
+
configureAmplify();
|
|
15
|
+
/**
|
|
16
|
+
* Return Authorization header containing the current Cognito ID token (if signed in).
|
|
17
|
+
*/
|
|
18
|
+
async function getAuthHeaders() {
|
|
19
|
+
try {
|
|
20
|
+
const session = await fetchAuthSession();
|
|
21
|
+
const idToken = session.tokens?.idToken?.toString();
|
|
22
|
+
if (idToken) {
|
|
23
|
+
return { Authorization: `Bearer ${idToken}` };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (_) {
|
|
27
|
+
/* not signed in */
|
|
28
|
+
}
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Norrix CLI Command Implementations
|
|
33
|
+
*
|
|
34
|
+
* All commands send requests through the Next.js API gateway, which handles:
|
|
35
|
+
* - Authentication
|
|
36
|
+
* - Rate limiting
|
|
37
|
+
* - Input validation
|
|
38
|
+
*
|
|
39
|
+
* The Next.js API then dispatches validated build/submit/update tasks to WarpBuild
|
|
40
|
+
* (GitHub Actions) for heavyweight processing.
|
|
41
|
+
*/
|
|
42
|
+
// Config (will be moved to a config file/env variables later)
|
|
43
|
+
const API_URL = process.env.NORRIX_API_URL || 'http://localhost:3000/api';
|
|
44
|
+
// Get dirname equivalent in ESM
|
|
45
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
46
|
+
const __dirname = path.dirname(__filename);
|
|
47
|
+
function readOptionalFileAsBase64(filePathInput) {
|
|
48
|
+
if (!filePathInput)
|
|
49
|
+
return undefined;
|
|
50
|
+
const resolved = path.resolve(process.cwd(), filePathInput);
|
|
51
|
+
if (!fs.existsSync(resolved))
|
|
52
|
+
return undefined;
|
|
53
|
+
const buf = fs.readFileSync(resolved);
|
|
54
|
+
return buf.toString('base64');
|
|
55
|
+
}
|
|
56
|
+
function encryptSecretsIfConfigured(secrets) {
|
|
57
|
+
const publicKeyPem = process.env.NORRIX_BUILD_PUBLIC_KEY;
|
|
58
|
+
const shouldEncrypt = !!publicKeyPem && process.env.NORRIX_ENCRYPT_SECRETS !== '0';
|
|
59
|
+
if (!shouldEncrypt)
|
|
60
|
+
return {};
|
|
61
|
+
const nodeCrypto = crypto;
|
|
62
|
+
const aesKey = nodeCrypto.randomBytes(32); // AES-256
|
|
63
|
+
const iv = nodeCrypto.randomBytes(12); // GCM nonce
|
|
64
|
+
const cipher = nodeCrypto.createCipheriv('aes-256-gcm', aesKey, iv);
|
|
65
|
+
const plaintext = Buffer.from(JSON.stringify(secrets), 'utf8');
|
|
66
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
67
|
+
const tag = cipher.getAuthTag();
|
|
68
|
+
const encryptedKey = nodeCrypto.publicEncrypt({ key: publicKeyPem, oaepHash: 'sha256' }, aesKey);
|
|
69
|
+
return {
|
|
70
|
+
encryptedSecrets: {
|
|
71
|
+
algorithm: 'aes-256-gcm+rsa-oaep-2048',
|
|
72
|
+
key: encryptedKey.toString('base64'),
|
|
73
|
+
iv: iv.toString('base64'),
|
|
74
|
+
tag: tag.toString('base64'),
|
|
75
|
+
ciphertext: ciphertext.toString('base64'),
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the current NativeScript project's name from package.json
|
|
81
|
+
*/
|
|
82
|
+
async function getProjectName() {
|
|
83
|
+
try {
|
|
84
|
+
// Check if package.json exists in current directory
|
|
85
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
86
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
87
|
+
throw new Error('No package.json found. Are you in a NativeScript project directory?');
|
|
88
|
+
}
|
|
89
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
90
|
+
return packageJson.name || 'unnamed-project';
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw new Error(`Failed to get project name: ${error.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Creates a zip file of the current directory (NativeScript project)
|
|
98
|
+
*/
|
|
99
|
+
async function zipProject(projectName, isUpdate = false) {
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
const outputPath = path.join(process.cwd(), `${projectName}.zip`);
|
|
102
|
+
const output = fs.createWriteStream(outputPath);
|
|
103
|
+
const archive = archiver('zip', {
|
|
104
|
+
zlib: { level: 9 }, // Compression level
|
|
105
|
+
});
|
|
106
|
+
// Listen for all archive data to be written
|
|
107
|
+
output.on('close', () => {
|
|
108
|
+
resolve(outputPath);
|
|
109
|
+
});
|
|
110
|
+
// Listen for warnings and errors
|
|
111
|
+
archive.on('warning', (err) => {
|
|
112
|
+
if (err.code === 'ENOENT') {
|
|
113
|
+
console.warn('Archive warning:', err);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
reject(err);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
archive.on('error', (err) => {
|
|
120
|
+
reject(err);
|
|
121
|
+
});
|
|
122
|
+
// Pipe archive data to the file
|
|
123
|
+
archive.pipe(output);
|
|
124
|
+
// Check if we have a src/app directory
|
|
125
|
+
const srcAppDir = path.join(process.cwd(), 'src', 'app');
|
|
126
|
+
const appDir = path.join(process.cwd(), 'app');
|
|
127
|
+
if (fs.existsSync(srcAppDir) && fs.statSync(srcAppDir).isDirectory()) {
|
|
128
|
+
console.log('Found src/app directory in project');
|
|
129
|
+
}
|
|
130
|
+
else if (fs.existsSync(appDir) && fs.statSync(appDir).isDirectory()) {
|
|
131
|
+
console.log('Found app directory in project');
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.warn('Warning: app directory not found at /Users/owencarey/Documents/nativescript-browser/app');
|
|
135
|
+
console.log('Creating an empty app directory in the zip');
|
|
136
|
+
}
|
|
137
|
+
// For both builds/updates, include App_Resources and exclude node_modules
|
|
138
|
+
archive.glob('**/*', {
|
|
139
|
+
cwd: process.cwd(),
|
|
140
|
+
ignore: [
|
|
141
|
+
'node_modules/**', // Always exclude node_modules
|
|
142
|
+
'*.zip', // Exclude existing zip files
|
|
143
|
+
'platforms/**', // Exclude platform-specific directories
|
|
144
|
+
'hooks/**', // Exclude hooks directory
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
// Finalize the archive
|
|
148
|
+
archive.finalize();
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Build command implementation
|
|
153
|
+
* Uploads project to S3 and triggers build via the Next.js API gateway -> WarpBuild
|
|
154
|
+
*/
|
|
155
|
+
export async function build() {
|
|
156
|
+
try {
|
|
157
|
+
const spinner = ora('Preparing app for building...').start();
|
|
158
|
+
// 1. Get project info
|
|
159
|
+
const projectName = await getProjectName();
|
|
160
|
+
// 2. Ask for platform
|
|
161
|
+
spinner.stop();
|
|
162
|
+
const { platform, version, configuration } = await inquirer.prompt([
|
|
163
|
+
{
|
|
164
|
+
type: 'list',
|
|
165
|
+
name: 'platform',
|
|
166
|
+
message: 'Select target platform:',
|
|
167
|
+
choices: ['android', 'ios'],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'input',
|
|
171
|
+
name: 'version',
|
|
172
|
+
message: 'App version (optional):',
|
|
173
|
+
default: '',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
type: 'list',
|
|
177
|
+
name: 'configuration',
|
|
178
|
+
message: 'Build configuration:',
|
|
179
|
+
choices: ['debug', 'release'],
|
|
180
|
+
default: 'debug',
|
|
181
|
+
},
|
|
182
|
+
]);
|
|
183
|
+
// 2.5 For release builds, collect signing credentials
|
|
184
|
+
let iosCredentials;
|
|
185
|
+
let androidCredentials;
|
|
186
|
+
if (configuration === 'release') {
|
|
187
|
+
spinner.stop();
|
|
188
|
+
if (platform === 'ios') {
|
|
189
|
+
const iosAnswers = await inquirer.prompt([
|
|
190
|
+
{
|
|
191
|
+
type: 'input',
|
|
192
|
+
name: 'p12Path',
|
|
193
|
+
message: 'Path to iOS .p12 certificate (optional):',
|
|
194
|
+
default: '',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
type: 'password',
|
|
198
|
+
name: 'p12Password',
|
|
199
|
+
message: 'Password for .p12 (if any):',
|
|
200
|
+
mask: '*',
|
|
201
|
+
default: '',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: 'input',
|
|
205
|
+
name: 'mobileprovisionPath',
|
|
206
|
+
message: 'Path to provisioning profile .mobileprovision (optional):',
|
|
207
|
+
default: '',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
type: 'confirm',
|
|
211
|
+
name: 'hasAscKey',
|
|
212
|
+
message: 'Provide App Store Connect API Key? (optional, for App Store operations)',
|
|
213
|
+
default: false,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
type: 'input',
|
|
217
|
+
name: 'ascApiKeyId',
|
|
218
|
+
message: 'ASC API Key ID (optional):',
|
|
219
|
+
default: '',
|
|
220
|
+
when: (a) => a.hasAscKey,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: 'input',
|
|
224
|
+
name: 'ascIssuerId',
|
|
225
|
+
message: 'ASC Issuer ID (optional):',
|
|
226
|
+
default: '',
|
|
227
|
+
when: (a) => a.hasAscKey,
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
type: 'input',
|
|
231
|
+
name: 'ascPrivateKeyPath',
|
|
232
|
+
message: 'Path to ASC private key .p8 (optional):',
|
|
233
|
+
default: '',
|
|
234
|
+
when: (a) => a.hasAscKey,
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
type: 'input',
|
|
238
|
+
name: 'ascTeamId',
|
|
239
|
+
message: 'Apple Developer Team ID (optional, required for API-key provisioning):',
|
|
240
|
+
default: '',
|
|
241
|
+
when: (a) => a.hasAscKey,
|
|
242
|
+
},
|
|
243
|
+
]);
|
|
244
|
+
iosCredentials = {
|
|
245
|
+
p12Base64: readOptionalFileAsBase64(iosAnswers.p12Path),
|
|
246
|
+
p12Password: iosAnswers.p12Password || undefined,
|
|
247
|
+
mobileprovisionBase64: readOptionalFileAsBase64(iosAnswers.mobileprovisionPath),
|
|
248
|
+
ascApiKeyId: iosAnswers.ascApiKeyId || undefined,
|
|
249
|
+
ascIssuerId: iosAnswers.ascIssuerId || undefined,
|
|
250
|
+
ascPrivateKey: readOptionalFileAsBase64(iosAnswers.ascPrivateKeyPath),
|
|
251
|
+
ascTeamId: iosAnswers.ascTeamId || undefined,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
else if (platform === 'android') {
|
|
255
|
+
const androidAnswers = await inquirer.prompt([
|
|
256
|
+
{
|
|
257
|
+
type: 'input',
|
|
258
|
+
name: 'keystorePath',
|
|
259
|
+
message: 'Path to Android keystore .jks/.keystore (optional):',
|
|
260
|
+
default: '',
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
type: 'password',
|
|
264
|
+
name: 'keystorePassword',
|
|
265
|
+
message: 'Keystore password (optional):',
|
|
266
|
+
mask: '*',
|
|
267
|
+
default: '',
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
type: 'input',
|
|
271
|
+
name: 'keyAlias',
|
|
272
|
+
message: 'Key alias (optional):',
|
|
273
|
+
default: '',
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
type: 'password',
|
|
277
|
+
name: 'keyPassword',
|
|
278
|
+
message: 'Key password (optional):',
|
|
279
|
+
mask: '*',
|
|
280
|
+
default: '',
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
type: 'confirm',
|
|
284
|
+
name: 'hasPlayJson',
|
|
285
|
+
message: 'Provide Google Play service account JSON? (optional, for Play operations)',
|
|
286
|
+
default: false,
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
type: 'input',
|
|
290
|
+
name: 'playJsonPath',
|
|
291
|
+
message: 'Path to Google Play service account JSON (optional):',
|
|
292
|
+
default: '',
|
|
293
|
+
when: (a) => a.hasPlayJson,
|
|
294
|
+
},
|
|
295
|
+
]);
|
|
296
|
+
androidCredentials = {
|
|
297
|
+
keystoreBase64: readOptionalFileAsBase64(androidAnswers.keystorePath),
|
|
298
|
+
keystorePassword: androidAnswers.keystorePassword || undefined,
|
|
299
|
+
keyAlias: androidAnswers.keyAlias || undefined,
|
|
300
|
+
keyPassword: androidAnswers.keyPassword || undefined,
|
|
301
|
+
playServiceAccountJson: readOptionalFileAsBase64(androidAnswers.playJsonPath),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
spinner.start('Creating project archive...');
|
|
305
|
+
}
|
|
306
|
+
spinner.start('Creating project archive...');
|
|
307
|
+
// 3. Zip the project
|
|
308
|
+
const zipPath = await zipProject(projectName, false);
|
|
309
|
+
spinner.text = 'Project archive created';
|
|
310
|
+
// 4. Upload the project zip to S3
|
|
311
|
+
spinner.text = 'Uploading project to Norrix cloud storage...';
|
|
312
|
+
const fileBuffer = fs.readFileSync(zipPath);
|
|
313
|
+
const s3Key = `builds/${projectName}-${Date.now()}.zip`;
|
|
314
|
+
await uploadData({
|
|
315
|
+
key: s3Key,
|
|
316
|
+
data: fileBuffer,
|
|
317
|
+
}).result;
|
|
318
|
+
spinner.text = 'Upload complete. Starting build...';
|
|
319
|
+
// 5. Call the Next.js API with the S3 key and build parameters
|
|
320
|
+
// 5. Call the Next.js API with the S3 key, build parameters, and signing data (release only)
|
|
321
|
+
const secrets = iosCredentials || androidCredentials
|
|
322
|
+
? { iosCredentials, androidCredentials }
|
|
323
|
+
: undefined;
|
|
324
|
+
const { encryptedSecrets } = secrets
|
|
325
|
+
? encryptSecretsIfConfigured(secrets)
|
|
326
|
+
: { encryptedSecrets: undefined };
|
|
327
|
+
const response = await axios.post(`${API_URL}/build`, {
|
|
328
|
+
projectName,
|
|
329
|
+
platform,
|
|
330
|
+
version: version || '',
|
|
331
|
+
configuration,
|
|
332
|
+
s3Key,
|
|
333
|
+
// Only include raw credentials if not encrypted
|
|
334
|
+
...(encryptedSecrets ? { encryptedSecrets } : {}),
|
|
335
|
+
...(!encryptedSecrets && iosCredentials ? { iosCredentials } : {}),
|
|
336
|
+
...(!encryptedSecrets && androidCredentials
|
|
337
|
+
? { androidCredentials }
|
|
338
|
+
: {}),
|
|
339
|
+
}, {
|
|
340
|
+
headers: {
|
|
341
|
+
'Content-Type': 'application/json',
|
|
342
|
+
...(await getAuthHeaders()),
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
// 6. Clean up the zip file
|
|
346
|
+
fs.unlinkSync(zipPath);
|
|
347
|
+
const buildId = response.data.id;
|
|
348
|
+
spinner.succeed('Build started successfully!');
|
|
349
|
+
console.log('✅ Your app is being built on Norrix servers.');
|
|
350
|
+
console.log(` Build ID: ${buildId}`);
|
|
351
|
+
console.log(` You can check the status with: norrix build-status ${buildId}`);
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
ora().fail(`Build failed: ${error.message}`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Submit command implementation
|
|
359
|
+
* Submits the built app to app stores via the Next.js API gateway
|
|
360
|
+
*/
|
|
361
|
+
export async function submit() {
|
|
362
|
+
try {
|
|
363
|
+
const spinner = ora('Preparing app for submission...').start();
|
|
364
|
+
// 1. Get available builds to show in prompt
|
|
365
|
+
spinner.text = 'Fetching available builds...';
|
|
366
|
+
let availableBuilds = [];
|
|
367
|
+
try {
|
|
368
|
+
const buildsResponse = await axios.get(`${API_URL}/build`, {
|
|
369
|
+
headers: await getAuthHeaders(),
|
|
370
|
+
});
|
|
371
|
+
if (buildsResponse.data.builds &&
|
|
372
|
+
Array.isArray(buildsResponse.data.builds)) {
|
|
373
|
+
// Filter for successful builds
|
|
374
|
+
availableBuilds = buildsResponse.data.builds
|
|
375
|
+
.filter((build) => build.status === 'success')
|
|
376
|
+
.map((build) => ({
|
|
377
|
+
name: `${build.projectName} (${build.platform} - ${build.id})`,
|
|
378
|
+
value: build.id,
|
|
379
|
+
platform: build.platform,
|
|
380
|
+
}));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
spinner.warn("Could not fetch builds. You'll need to enter the Build ID manually.");
|
|
385
|
+
}
|
|
386
|
+
// 2. Gather submission details from user
|
|
387
|
+
spinner.stop();
|
|
388
|
+
// Ask for build ID
|
|
389
|
+
let buildId;
|
|
390
|
+
if (availableBuilds.length > 0) {
|
|
391
|
+
const buildIdAnswer = await inquirer.prompt([
|
|
392
|
+
{
|
|
393
|
+
type: 'list',
|
|
394
|
+
name: 'buildId',
|
|
395
|
+
message: 'Select the build to submit:',
|
|
396
|
+
choices: availableBuilds,
|
|
397
|
+
},
|
|
398
|
+
]);
|
|
399
|
+
buildId = buildIdAnswer.buildId;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
const buildIdAnswer = await inquirer.prompt([
|
|
403
|
+
{
|
|
404
|
+
type: 'input',
|
|
405
|
+
name: 'buildId',
|
|
406
|
+
message: 'Enter the Build ID to submit:',
|
|
407
|
+
validate: (input) => input.length > 0 || 'Build ID is required',
|
|
408
|
+
},
|
|
409
|
+
]);
|
|
410
|
+
buildId = buildIdAnswer.buildId;
|
|
411
|
+
}
|
|
412
|
+
// Get the platform for the selected build
|
|
413
|
+
const selectedBuild = availableBuilds.find((build) => build.value === buildId);
|
|
414
|
+
const defaultPlatform = selectedBuild ? selectedBuild.platform : null;
|
|
415
|
+
let platform;
|
|
416
|
+
if (defaultPlatform) {
|
|
417
|
+
platform = defaultPlatform;
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
const platformAnswer = await inquirer.prompt([
|
|
421
|
+
{
|
|
422
|
+
type: 'list',
|
|
423
|
+
name: 'platform',
|
|
424
|
+
message: 'Select target platform:',
|
|
425
|
+
choices: ['android', 'ios'],
|
|
426
|
+
},
|
|
427
|
+
]);
|
|
428
|
+
platform = platformAnswer.platform;
|
|
429
|
+
}
|
|
430
|
+
// Common configuration for both platforms
|
|
431
|
+
const { track } = await inquirer.prompt([
|
|
432
|
+
{
|
|
433
|
+
type: 'list',
|
|
434
|
+
name: 'track',
|
|
435
|
+
message: 'Select release track:',
|
|
436
|
+
choices: [
|
|
437
|
+
{ name: 'Production', value: 'production' },
|
|
438
|
+
{ name: 'Beta', value: 'beta' },
|
|
439
|
+
{ name: 'Alpha', value: 'alpha' },
|
|
440
|
+
{ name: 'Internal testing', value: 'internal' },
|
|
441
|
+
],
|
|
442
|
+
default: 'production',
|
|
443
|
+
},
|
|
444
|
+
]);
|
|
445
|
+
// Platform-specific configuration
|
|
446
|
+
let credentials = {};
|
|
447
|
+
// For iOS, ask for App Store account
|
|
448
|
+
if (platform === 'ios') {
|
|
449
|
+
const iosConfig = await inquirer.prompt([
|
|
450
|
+
{
|
|
451
|
+
type: 'input',
|
|
452
|
+
name: 'appleId',
|
|
453
|
+
message: 'App Store Connect username (optional):',
|
|
454
|
+
default: '',
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
type: 'input',
|
|
458
|
+
name: 'apiKeyPath',
|
|
459
|
+
message: 'Path to App Store Connect API key (optional):',
|
|
460
|
+
default: '',
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
type: 'confirm',
|
|
464
|
+
name: 'generateCertificate',
|
|
465
|
+
message: 'Auto-generate iOS certificates?',
|
|
466
|
+
default: true,
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
type: 'input',
|
|
470
|
+
name: 'notes',
|
|
471
|
+
message: 'Release notes (optional):',
|
|
472
|
+
default: '',
|
|
473
|
+
},
|
|
474
|
+
]);
|
|
475
|
+
credentials = {
|
|
476
|
+
appleId: iosConfig.appleId,
|
|
477
|
+
apiKeyPath: iosConfig.apiKeyPath,
|
|
478
|
+
generateCertificate: iosConfig.generateCertificate,
|
|
479
|
+
notes: iosConfig.notes,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
// For Android, ask for Play Store account
|
|
483
|
+
if (platform === 'android') {
|
|
484
|
+
const androidConfig = await inquirer.prompt([
|
|
485
|
+
{
|
|
486
|
+
type: 'input',
|
|
487
|
+
name: 'serviceAccountKeyPath',
|
|
488
|
+
message: 'Path to Google Play service account key (optional):',
|
|
489
|
+
default: '',
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
type: 'confirm',
|
|
493
|
+
name: 'generateKeystore',
|
|
494
|
+
message: 'Auto-generate Android keystore?',
|
|
495
|
+
default: true,
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
type: 'input',
|
|
499
|
+
name: 'notes',
|
|
500
|
+
message: 'Release notes (optional):',
|
|
501
|
+
default: '',
|
|
502
|
+
},
|
|
503
|
+
]);
|
|
504
|
+
credentials = {
|
|
505
|
+
serviceAccountKeyPath: androidConfig.serviceAccountKeyPath,
|
|
506
|
+
generateKeystore: androidConfig.generateKeystore,
|
|
507
|
+
notes: androidConfig.notes,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
spinner.start(`Submitting build to ${platform === 'android' ? 'Google Play' : 'App Store'}...`);
|
|
511
|
+
// 3. Call the Next.js API
|
|
512
|
+
const response = await axios.post(`${API_URL}/submit`, {
|
|
513
|
+
buildId,
|
|
514
|
+
platform,
|
|
515
|
+
track,
|
|
516
|
+
...credentials,
|
|
517
|
+
}, { headers: await getAuthHeaders() });
|
|
518
|
+
const submitId = response.data.id;
|
|
519
|
+
spinner.succeed('Submission started successfully!');
|
|
520
|
+
console.log('✅ Your app is being submitted to the app stores.');
|
|
521
|
+
console.log(` Submission ID: ${submitId}`);
|
|
522
|
+
console.log(` Platform: ${platform === 'android' ? 'Google Play' : 'App Store'}`);
|
|
523
|
+
console.log(` Track: ${track}`);
|
|
524
|
+
console.log(` You can check the status with: norrix submit-status ${submitId}`);
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
ora().fail(`Submission failed: ${error.message}`);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Update command implementation
|
|
532
|
+
* Publishes over-the-air updates to deployed apps via the Next.js API gateway
|
|
533
|
+
*/
|
|
534
|
+
export async function update() {
|
|
535
|
+
try {
|
|
536
|
+
const spinner = ora('Preparing over-the-air update...').start();
|
|
537
|
+
// Ask for app ID and other details
|
|
538
|
+
spinner.stop();
|
|
539
|
+
const { appId, version, notes } = await inquirer.prompt([
|
|
540
|
+
{
|
|
541
|
+
type: 'input',
|
|
542
|
+
name: 'appId',
|
|
543
|
+
message: 'Enter the App ID to update:',
|
|
544
|
+
validate: (input) => input.length > 0 || 'App ID is required',
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
type: 'input',
|
|
548
|
+
name: 'version',
|
|
549
|
+
message: 'Update version:',
|
|
550
|
+
validate: (input) => input.length > 0 || 'Version is required',
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
type: 'input',
|
|
554
|
+
name: 'notes',
|
|
555
|
+
message: 'Release notes (optional):',
|
|
556
|
+
default: '',
|
|
557
|
+
},
|
|
558
|
+
]);
|
|
559
|
+
// Check the app directory structure before packaging
|
|
560
|
+
const srcAppDir = path.join(process.cwd(), 'src', 'app');
|
|
561
|
+
const appDir = path.join(process.cwd(), 'app');
|
|
562
|
+
if (fs.existsSync(srcAppDir) && fs.statSync(srcAppDir).isDirectory()) {
|
|
563
|
+
spinner.info('Found src/app directory - will include this in the update bundle');
|
|
564
|
+
}
|
|
565
|
+
else if (fs.existsSync(appDir) && fs.statSync(appDir).isDirectory()) {
|
|
566
|
+
spinner.info('Found app directory - will include this in the update bundle');
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
spinner.warn('Warning: app directory not found in the project. The update may be incomplete.');
|
|
570
|
+
spinner.warn('Expected app at either:\n- ' + appDir + '\n- ' + srcAppDir);
|
|
571
|
+
}
|
|
572
|
+
spinner.start('Packaging JavaScript bundle for over-the-air update...');
|
|
573
|
+
// Create the update bundle - pass true to include node_modules for updates
|
|
574
|
+
const projectName = await getProjectName();
|
|
575
|
+
const zipPath = await zipProject(projectName, true);
|
|
576
|
+
spinner.text = 'Uploading update to Norrix cloud storage...';
|
|
577
|
+
const fileBuffer = fs.readFileSync(zipPath);
|
|
578
|
+
const s3Key = `updates/${appId}-${version}-${Date.now()}.zip`;
|
|
579
|
+
await uploadData({
|
|
580
|
+
key: s3Key,
|
|
581
|
+
data: fileBuffer,
|
|
582
|
+
}).result;
|
|
583
|
+
spinner.text = 'Upload complete. Starting update...';
|
|
584
|
+
const response = await axios.post(`${API_URL}/update`, {
|
|
585
|
+
appId,
|
|
586
|
+
version,
|
|
587
|
+
releaseNotes: notes,
|
|
588
|
+
s3Key,
|
|
589
|
+
}, {
|
|
590
|
+
headers: {
|
|
591
|
+
'Content-Type': 'application/json',
|
|
592
|
+
...(await getAuthHeaders()),
|
|
593
|
+
},
|
|
594
|
+
});
|
|
595
|
+
// Clean up the zip file
|
|
596
|
+
fs.unlinkSync(zipPath);
|
|
597
|
+
const updateId = response.data.id;
|
|
598
|
+
spinner.succeed('Update published successfully!');
|
|
599
|
+
console.log('✅ Your update has been published.');
|
|
600
|
+
console.log(` Update ID: ${updateId}`);
|
|
601
|
+
console.log(` You can check the status with: norrix update-status ${updateId}`);
|
|
602
|
+
}
|
|
603
|
+
catch (error) {
|
|
604
|
+
ora().fail(`Update failed: ${error.message}`);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Build Status command implementation
|
|
609
|
+
* Checks the status of a build via the Next.js API gateway
|
|
610
|
+
*/
|
|
611
|
+
export async function buildStatus(buildId) {
|
|
612
|
+
try {
|
|
613
|
+
const spinner = ora(`Checking status of build ${buildId}...`).start();
|
|
614
|
+
const response = await axios.get(`${API_URL}/build/${buildId}`, {
|
|
615
|
+
headers: await getAuthHeaders(),
|
|
616
|
+
});
|
|
617
|
+
spinner.stop();
|
|
618
|
+
console.log('\nBuild Status:');
|
|
619
|
+
console.log(`ID: ${response.data.id}`);
|
|
620
|
+
console.log(`Project: ${response.data.projectName}`);
|
|
621
|
+
console.log(`Platform: ${response.data.platform}`);
|
|
622
|
+
console.log(`Status: ${response.data.status}`);
|
|
623
|
+
console.log(`Message: ${response.data.message}`);
|
|
624
|
+
if (response.data.logs) {
|
|
625
|
+
console.log('\nBuild Logs:');
|
|
626
|
+
console.log(response.data.logs);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
catch (error) {
|
|
630
|
+
ora().fail(`Failed to check build status: ${error.message}`);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Submit Status command implementation
|
|
635
|
+
* Checks the status of a submission via the Next.js API gateway
|
|
636
|
+
*/
|
|
637
|
+
export async function submitStatus(submitId) {
|
|
638
|
+
try {
|
|
639
|
+
const spinner = ora(`Checking status of submission ${submitId}...`).start();
|
|
640
|
+
const response = await axios.get(`${API_URL}/submit/${submitId}`, {
|
|
641
|
+
headers: await getAuthHeaders(),
|
|
642
|
+
});
|
|
643
|
+
spinner.stop();
|
|
644
|
+
console.log('\nSubmission Status:');
|
|
645
|
+
console.log(`ID: ${response.data.id}`);
|
|
646
|
+
console.log(`Build ID: ${response.data.buildId}`);
|
|
647
|
+
console.log(`Platform: ${response.data.platform}`);
|
|
648
|
+
console.log(`Status: ${response.data.status}`);
|
|
649
|
+
console.log(`Message: ${response.data.message}`);
|
|
650
|
+
}
|
|
651
|
+
catch (error) {
|
|
652
|
+
ora().fail(`Failed to check submission status: ${error.message}`);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Update Status command implementation
|
|
657
|
+
* Checks the status of an update via the Next.js API gateway
|
|
658
|
+
*/
|
|
659
|
+
export async function updateStatus(updateId) {
|
|
660
|
+
try {
|
|
661
|
+
const spinner = ora(`Checking status of update ${updateId}...`).start();
|
|
662
|
+
const response = await axios.get(`${API_URL}/update/${updateId}`, {
|
|
663
|
+
headers: await getAuthHeaders(),
|
|
664
|
+
});
|
|
665
|
+
spinner.stop();
|
|
666
|
+
console.log('\nUpdate Status:');
|
|
667
|
+
console.log(`ID: ${response.data.id}`);
|
|
668
|
+
console.log(`App ID: ${response.data.appId}`);
|
|
669
|
+
console.log(`Version: ${response.data.version}`);
|
|
670
|
+
console.log(`Status: ${response.data.status}`);
|
|
671
|
+
console.log(`Message: ${response.data.message}`);
|
|
672
|
+
}
|
|
673
|
+
catch (error) {
|
|
674
|
+
ora().fail(`Failed to check update status: ${error.message}`);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Sign-In command implementation (email / password via Cognito)
|
|
679
|
+
*/
|
|
680
|
+
export async function signIn() {
|
|
681
|
+
try {
|
|
682
|
+
const answers = await inquirer.prompt([
|
|
683
|
+
{
|
|
684
|
+
type: 'input',
|
|
685
|
+
name: 'email',
|
|
686
|
+
message: 'Email:',
|
|
687
|
+
validate: (input) => input.length > 0 || 'Email is required',
|
|
688
|
+
},
|
|
689
|
+
{
|
|
690
|
+
type: 'password',
|
|
691
|
+
name: 'password',
|
|
692
|
+
message: 'Password:',
|
|
693
|
+
mask: '*',
|
|
694
|
+
validate: (input) => input.length > 0 || 'Password is required',
|
|
695
|
+
},
|
|
696
|
+
]);
|
|
697
|
+
const spinner = ora('Signing in...').start();
|
|
698
|
+
await amplifySignIn({
|
|
699
|
+
username: answers.email,
|
|
700
|
+
password: answers.password,
|
|
701
|
+
});
|
|
702
|
+
// Force the library to fetch (and therefore persist) the auth session
|
|
703
|
+
// right after signing in. Without this call, tokens may remain only in
|
|
704
|
+
// memory in some runtimes and will not survive across separate CLI
|
|
705
|
+
// executions.
|
|
706
|
+
await fetchAuthSession();
|
|
707
|
+
spinner.succeed(`Signed in as ${answers.email}`);
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
ora().fail(`Sign-in failed: ${error.message}`);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Sign-Out command implementation
|
|
715
|
+
*/
|
|
716
|
+
export async function signOut() {
|
|
717
|
+
try {
|
|
718
|
+
const spinner = ora('Signing out...').start();
|
|
719
|
+
await amplifySignOut();
|
|
720
|
+
spinner.succeed('Signed out successfully');
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
ora().fail(`Sign-out failed: ${error.message}`);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Upload a file to S3 via Amplify Storage
|
|
728
|
+
*/
|
|
729
|
+
export async function uploadFile(filePath, options) {
|
|
730
|
+
try {
|
|
731
|
+
const resolvedPath = path.resolve(process.cwd(), filePath);
|
|
732
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
733
|
+
throw new Error(`File not found at ${resolvedPath}`);
|
|
734
|
+
}
|
|
735
|
+
const key = options?.key || path.basename(resolvedPath);
|
|
736
|
+
const fileBuffer = fs.readFileSync(resolvedPath);
|
|
737
|
+
const spinner = ora(`Uploading ${key} to storage...`).start();
|
|
738
|
+
await uploadData({
|
|
739
|
+
key: key,
|
|
740
|
+
data: fileBuffer,
|
|
741
|
+
}).result;
|
|
742
|
+
spinner.succeed(`Uploaded ${key} successfully`);
|
|
743
|
+
}
|
|
744
|
+
catch (error) {
|
|
745
|
+
ora().fail(`Upload failed: ${error.message}`);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Current User command implementation
|
|
750
|
+
*/
|
|
751
|
+
export async function currentUser() {
|
|
752
|
+
try {
|
|
753
|
+
const spinner = ora('Fetching current user...').start();
|
|
754
|
+
let user;
|
|
755
|
+
try {
|
|
756
|
+
user = await getCurrentUser();
|
|
757
|
+
}
|
|
758
|
+
catch {
|
|
759
|
+
// Attempt to refresh session
|
|
760
|
+
await fetchAuthSession();
|
|
761
|
+
try {
|
|
762
|
+
user = await getCurrentUser();
|
|
763
|
+
}
|
|
764
|
+
catch {
|
|
765
|
+
/* ignored */
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
spinner.stop();
|
|
769
|
+
if (!user) {
|
|
770
|
+
console.log('⚠️ No user is currently signed in.');
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
console.log('Signed-in user info:');
|
|
774
|
+
console.log(`Username (sub): ${user.userId}`);
|
|
775
|
+
console.log(`Username: ${user.username ?? 'N/A'}`);
|
|
776
|
+
console.log(`Sign-in provider: ${user.signInDetails?.loginId ?? 'email'}`);
|
|
777
|
+
}
|
|
778
|
+
catch (error) {
|
|
779
|
+
if (error.name === 'UserNotAuthenticatedException' ||
|
|
780
|
+
error.name === 'Error' ||
|
|
781
|
+
error.message?.includes('authenticated')) {
|
|
782
|
+
console.log('⚠️ No user is currently signed in.');
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
ora().fail(`Failed to fetch current user: ${error.message}`);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/lib/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function norrixCli(): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"norrix-cli.js","sourceRoot":"","sources":["../../src/lib/norrix-cli.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS;IACvB,OAAO,YAAY,CAAC;AACtB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@norrix/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
".": {
|
|
11
|
+
"development": "./src/index.ts",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"norrix": "./dist/cli.js",
|
|
19
|
+
"nox": "./dist/cli.js"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"!**/*.tsbuildinfo"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.lib.json",
|
|
27
|
+
"postbuild": "chmod +x ./dist/cli.js"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"archiver": "^7.0.0",
|
|
31
|
+
"aws-amplify": "^6.15.2",
|
|
32
|
+
"axios": "^1.8.4",
|
|
33
|
+
"commander": "^11.1.0",
|
|
34
|
+
"dotenv": "^16.4.5",
|
|
35
|
+
"inquirer": "^9.3.7",
|
|
36
|
+
"ora": "^6.3.1"
|
|
37
|
+
}
|
|
38
|
+
}
|