@padua/cli 1.0.0

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.
Files changed (34) hide show
  1. package/README.md +158 -0
  2. package/dist/commands/login/codeartifact.d.ts +11 -0
  3. package/dist/commands/login/codeartifact.d.ts.map +1 -0
  4. package/dist/commands/login/codeartifact.js +77 -0
  5. package/dist/commands/login/codeartifact.js.map +1 -0
  6. package/dist/commands/login/config.d.ts +11 -0
  7. package/dist/commands/login/config.d.ts.map +1 -0
  8. package/dist/commands/login/config.js +99 -0
  9. package/dist/commands/login/config.js.map +1 -0
  10. package/dist/commands/login/ecr.d.ts +11 -0
  11. package/dist/commands/login/ecr.d.ts.map +1 -0
  12. package/dist/commands/login/ecr.js +107 -0
  13. package/dist/commands/login/ecr.js.map +1 -0
  14. package/dist/commands/login/index.d.ts +6 -0
  15. package/dist/commands/login/index.d.ts.map +1 -0
  16. package/dist/commands/login/index.js +177 -0
  17. package/dist/commands/login/index.js.map +1 -0
  18. package/dist/commands/login/sso.d.ts +17 -0
  19. package/dist/commands/login/sso.d.ts.map +1 -0
  20. package/dist/commands/login/sso.js +87 -0
  21. package/dist/commands/login/sso.js.map +1 -0
  22. package/dist/commands/login/types.d.ts +100 -0
  23. package/dist/commands/login/types.d.ts.map +1 -0
  24. package/dist/commands/login/types.js +69 -0
  25. package/dist/commands/login/types.js.map +1 -0
  26. package/dist/commands/login/utils.d.ts +24 -0
  27. package/dist/commands/login/utils.d.ts.map +1 -0
  28. package/dist/commands/login/utils.js +93 -0
  29. package/dist/commands/login/utils.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +14 -0
  33. package/dist/index.js.map +1 -0
  34. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,158 @@
1
+ # Padua CLI
2
+
3
+ A unified CLI for AWS infrastructure management—authentication, tunneling, and container tools in one place.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @padua/cli
9
+ ```
10
+
11
+ ### Prerequisites
12
+
13
+ - [Node.js](https://nodejs.org/) v18+
14
+ - [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
15
+ - [Session Manager Plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html) (for tunneling)
16
+ - [Docker](https://www.docker.com/) (optional, for ECR)
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ # 1. Create config file
22
+ cp padua.config.example.json padua.config.json
23
+
24
+ # 2. Edit with your AWS account details
25
+ # 3. Run login
26
+ padua login
27
+ ```
28
+
29
+ ## Features
30
+
31
+ | Category | Feature | Description |
32
+ |----------|---------|-------------|
33
+ | **Auth** | SSO Login | AWS SSO authentication and session management |
34
+ | | Profiles | Multiple AWS CLI profile management |
35
+ | | CodeArtifact | Automatic npm registry authentication |
36
+ | | ECR | Docker registry authentication |
37
+ | **Tunnel** | RDS/Aurora | PostgreSQL & MySQL via Session Manager |
38
+ | | OpenSearch | Kibana dashboard access |
39
+ | | EC2 | Direct SSM sessions to instances |
40
+ | **ECS** | Exec | Container command execution with pre-flight checks |
41
+
42
+ ## Login Command
43
+
44
+ Authenticate to AWS SSO, CodeArtifact (npm), and ECR (Docker) with a single command.
45
+
46
+ ### Basic Usage
47
+
48
+ ```bash
49
+ padua login # Full login (SSO + CodeArtifact + ECR)
50
+ padua login --profile staging # Use specific AWS profile
51
+ padua login --sso-only # SSO only, skip CodeArtifact and ECR
52
+ ```
53
+
54
+ ### Options
55
+
56
+ | Flag | Description |
57
+ |------|-------------|
58
+ | `-p, --profile <name>` | AWS SSO profile to use |
59
+ | `--sso-only` | Only authenticate to SSO |
60
+ | `-v, --verbose` | Show detailed output |
61
+ | `-q, --quiet` | Suppress non-error output |
62
+ | `--no-color` | Disable colored output |
63
+
64
+ ### Exit Codes
65
+
66
+ | Code | Meaning |
67
+ |------|---------|
68
+ | 0 | Success (SSO + at least one other service) |
69
+ | 1 | SSO succeeded but CodeArtifact and ECR both failed |
70
+ | 2 | SSO failed (other services not attempted) |
71
+
72
+ ### What `padua login` replaces
73
+
74
+ ```bash
75
+ # Before: 3 separate commands
76
+ aws sso login --profile development
77
+ aws codeartifact login --tool npm --repository npm-repo --domain my-domain \
78
+ --domain-owner 123456789012 --region ap-southeast-2 --profile development
79
+ aws ecr get-login-password --region ap-southeast-2 | \
80
+ docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com
81
+
82
+ # After: 1 command
83
+ padua login
84
+ ```
85
+
86
+ ### Example Output
87
+
88
+ ```
89
+ [1/3] AWS SSO ...
90
+ ✓ authenticated (profile: development)
91
+ [2/3] CodeArtifact (npm) ...
92
+ ✓ configured
93
+ [3/3] ECR (Docker) ...
94
+ ✓ configured
95
+
96
+ === Login Results ===
97
+ SSO: ✓ OK
98
+ CodeArtifact: ✓ OK
99
+ ECR: ✓ OK
100
+
101
+ Total: 3/3 services authenticated
102
+ ```
103
+
104
+ ## Configuration
105
+
106
+ Create a `padua.config.json` file in your project root or `~/.padua/`:
107
+
108
+ ```json
109
+ {
110
+ "defaultProfile": "development",
111
+ "region": "ap-southeast-2",
112
+ "codeartifact": {
113
+ "domain": "my-domain",
114
+ "domainOwner": "123456789012",
115
+ "repository": "npm-repo"
116
+ },
117
+ "ecr": {
118
+ "accountId": "123456789012",
119
+ "region": "ap-southeast-2"
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### Config Priority
125
+
126
+ 1. CLI flags (`--profile`)
127
+ 2. Environment variables (`PADUA_PROFILE`)
128
+ 3. `padua.config.json` in current directory
129
+ 4. `~/.padua/padua.config.json`
130
+ 5. Default values
131
+
132
+ ## Other Commands
133
+
134
+ ```bash
135
+ padua tunnel rds # RDS PostgreSQL via jumpbox
136
+ padua tunnel aurora # Aurora PostgreSQL via jumpbox
137
+ padua tunnel rds --legacy # MySQL via bastion-host (roma)
138
+ padua tunnel opensearch # OpenSearch/Kibana dashboard
139
+ padua tunnel ec2 <name> # SSM session to EC2 instance
140
+
141
+ padua ecs exec <cluster> <task> # Execute in ECS container
142
+ ```
143
+
144
+ ## Development
145
+
146
+ ```bash
147
+ git clone <repository-url>
148
+ cd padua-cli
149
+ npm install
150
+ npm run build
151
+ npm link # Makes 'padua' available globally
152
+ npm test # Run tests
153
+ npm run test:coverage # Run tests with coverage
154
+ ```
155
+
156
+ ## License
157
+
158
+ MIT
@@ -0,0 +1,11 @@
1
+ import { ServiceResult, LoginOptions, CodeArtifactConfig } from './types';
2
+ /**
3
+ * Configure npm to use CodeArtifact registry
4
+ *
5
+ * @param config - CodeArtifact configuration
6
+ * @param profile - AWS profile to use
7
+ * @param options - Login command options
8
+ * @returns ServiceResult indicating success/failure
9
+ */
10
+ export declare function configureCodeArtifact(config: CodeArtifactConfig, profile: string, options: LoginOptions): Promise<ServiceResult>;
11
+ //# sourceMappingURL=codeartifact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeartifact.d.ts","sourceRoot":"","sources":["../../../src/commands/login/codeartifact.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAK1E;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CAuExB"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureCodeArtifact = configureCodeArtifact;
4
+ const child_process_1 = require("child_process");
5
+ const utils_1 = require("./utils");
6
+ const CODEARTIFACT_TIMEOUT_MS = 30000; // 30 seconds
7
+ /**
8
+ * Configure npm to use CodeArtifact registry
9
+ *
10
+ * @param config - CodeArtifact configuration
11
+ * @param profile - AWS profile to use
12
+ * @param options - Login command options
13
+ * @returns ServiceResult indicating success/failure
14
+ */
15
+ async function configureCodeArtifact(config, profile, options) {
16
+ (0, utils_1.validateProfileName)(profile);
17
+ if (options.verbose) {
18
+ console.log(` [verbose] Configuring CodeArtifact: ${config.domain}/${config.repository}`);
19
+ }
20
+ // Use aws codeartifact login which handles token and npm config
21
+ const args = [
22
+ 'codeartifact', 'login',
23
+ '--tool', 'npm',
24
+ '--repository', config.repository,
25
+ '--domain', config.domain,
26
+ '--domain-owner', config.domainOwner,
27
+ '--profile', profile,
28
+ ];
29
+ if (options.verbose) {
30
+ console.log(` [verbose] Running: aws ${args.join(' ')}`);
31
+ }
32
+ const result = (0, child_process_1.spawnSync)('aws', args, {
33
+ shell: false,
34
+ timeout: CODEARTIFACT_TIMEOUT_MS,
35
+ maxBuffer: 1024 * 1024,
36
+ stdio: ['pipe', 'pipe', 'pipe'],
37
+ env: {
38
+ ...(0, utils_1.getSubprocessEnv)(),
39
+ AWS_PROFILE: profile,
40
+ },
41
+ });
42
+ if (result.error) {
43
+ if (result.error.message.includes('ENOENT')) {
44
+ throw new Error('AWS CLI not found. Please install AWS CLI v2.');
45
+ }
46
+ if (result.error.message.includes('ETIMEDOUT')) {
47
+ throw new Error('CodeArtifact login timed out.');
48
+ }
49
+ throw new Error((0, utils_1.sanitizeOutput)(result.error.message));
50
+ }
51
+ if (result.status !== 0) {
52
+ const stderr = result.stderr?.toString() || '';
53
+ const stdout = result.stdout?.toString() || '';
54
+ // Parse common error conditions
55
+ if (stderr.includes('ResourceNotFoundException')) {
56
+ throw new Error(`CodeArtifact domain '${config.domain}' or repository '${config.repository}' not found.`);
57
+ }
58
+ if (stderr.includes('AccessDeniedException')) {
59
+ throw new Error(`Access denied to CodeArtifact. Check IAM permissions for profile '${profile}'.`);
60
+ }
61
+ if (stderr.includes('ExpiredTokenException') || stderr.includes('credentials')) {
62
+ throw new Error('AWS credentials expired. SSO session may have ended.');
63
+ }
64
+ const errorOutput = (0, utils_1.sanitizeOutput)(stderr || stdout || 'Unknown error');
65
+ throw new Error(`CodeArtifact login failed: ${errorOutput}`);
66
+ }
67
+ if (options.verbose) {
68
+ const stdout = result.stdout?.toString() || '';
69
+ console.log(` [verbose] CodeArtifact configured: ${(0, utils_1.sanitizeOutput)(stdout)}`);
70
+ }
71
+ return {
72
+ success: true,
73
+ skipped: false,
74
+ duration: 0,
75
+ };
76
+ }
77
+ //# sourceMappingURL=codeartifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeartifact.js","sourceRoot":"","sources":["../../../src/commands/login/codeartifact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { PaduaConfig } from './types';
2
+ /**
3
+ * Load configuration from padua.config.json
4
+ * Returns null if no config file found
5
+ */
6
+ export declare function loadConfig(): Promise<PaduaConfig | null>;
7
+ /**
8
+ * Save configuration to padua.config.json
9
+ */
10
+ export declare function saveConfig(config: PaduaConfig, location?: 'local' | 'global'): Promise<void>;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/commands/login/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAwBtC;;;GAGG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAc9D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,GAAE,OAAO,GAAG,QAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB3G"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ exports.saveConfig = saveConfig;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const os = __importStar(require("os"));
41
+ const CONFIG_FILENAME = 'padua.config.json';
42
+ /**
43
+ * Get the path to the config file
44
+ * Priority: 1) Current directory, 2) ~/.padua/
45
+ */
46
+ function getConfigPath() {
47
+ // Check current directory first
48
+ const localPath = path.join(process.cwd(), CONFIG_FILENAME);
49
+ if (fs.existsSync(localPath)) {
50
+ return localPath;
51
+ }
52
+ // Check ~/.padua/ directory
53
+ const globalPath = path.join(os.homedir(), '.padua', CONFIG_FILENAME);
54
+ if (fs.existsSync(globalPath)) {
55
+ return globalPath;
56
+ }
57
+ return null;
58
+ }
59
+ /**
60
+ * Load configuration from padua.config.json
61
+ * Returns null if no config file found
62
+ */
63
+ async function loadConfig() {
64
+ const configPath = getConfigPath();
65
+ if (!configPath) {
66
+ return null;
67
+ }
68
+ try {
69
+ const content = fs.readFileSync(configPath, 'utf-8');
70
+ const config = JSON.parse(content);
71
+ return config;
72
+ }
73
+ catch (error) {
74
+ throw new Error(`Failed to load config from ${configPath}: ${error.message}`);
75
+ }
76
+ }
77
+ /**
78
+ * Save configuration to padua.config.json
79
+ */
80
+ async function saveConfig(config, location = 'local') {
81
+ let configPath;
82
+ if (location === 'global') {
83
+ const paduaDir = path.join(os.homedir(), '.padua');
84
+ if (!fs.existsSync(paduaDir)) {
85
+ fs.mkdirSync(paduaDir, { recursive: true });
86
+ }
87
+ configPath = path.join(paduaDir, CONFIG_FILENAME);
88
+ }
89
+ else {
90
+ configPath = path.join(process.cwd(), CONFIG_FILENAME);
91
+ }
92
+ try {
93
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
94
+ }
95
+ catch (error) {
96
+ throw new Error(`Failed to save config to ${configPath}: ${error.message}`);
97
+ }
98
+ }
99
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/commands/login/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,gCAcC;AAKD,gCAkBC;AApED,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAGzB,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAE5C;;;GAGG;AACH,SAAS,aAAa;IACpB,gCAAgC;IAChC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IAC5D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,4BAA4B;IAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACtE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,UAAU;IAC9B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAClD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,MAAmB,EAAE,WAA+B,OAAO;IAC1F,IAAI,UAAkB,CAAC;IAEvB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,4BAA4B,UAAU,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { ServiceResult, LoginOptions, EcrConfig } from './types';
2
+ /**
3
+ * Configure Docker to use ECR registry
4
+ *
5
+ * @param config - ECR configuration
6
+ * @param profile - AWS profile to use
7
+ * @param options - Login command options
8
+ * @returns ServiceResult indicating success/failure
9
+ */
10
+ export declare function configureECR(config: EcrConfig, profile: string, options: LoginOptions): Promise<ServiceResult>;
11
+ //# sourceMappingURL=ecr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecr.d.ts","sourceRoot":"","sources":["../../../src/commands/login/ecr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAKjE;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CA6GxB"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureECR = configureECR;
4
+ const child_process_1 = require("child_process");
5
+ const utils_1 = require("./utils");
6
+ const ECR_TIMEOUT_MS = 30000; // 30 seconds
7
+ /**
8
+ * Configure Docker to use ECR registry
9
+ *
10
+ * @param config - ECR configuration
11
+ * @param profile - AWS profile to use
12
+ * @param options - Login command options
13
+ * @returns ServiceResult indicating success/failure
14
+ */
15
+ async function configureECR(config, profile, options) {
16
+ (0, utils_1.validateProfileName)(profile);
17
+ const registryUrl = `${config.accountId}.dkr.ecr.${config.region}.amazonaws.com`;
18
+ if (options.verbose) {
19
+ console.log(` [verbose] Configuring ECR: ${registryUrl}`);
20
+ }
21
+ // Check if Docker is running
22
+ const dockerCheck = (0, child_process_1.spawnSync)('docker', ['info'], {
23
+ shell: false,
24
+ timeout: 5000,
25
+ stdio: ['pipe', 'pipe', 'pipe'],
26
+ env: (0, utils_1.getSubprocessEnv)(),
27
+ });
28
+ if (dockerCheck.status !== 0) {
29
+ throw new Error('Docker is not running. Please start Docker Desktop or Docker daemon.');
30
+ }
31
+ // Get ECR login password
32
+ if (options.verbose) {
33
+ console.log(` [verbose] Running: aws ecr get-login-password --region ${config.region} --profile ${profile}`);
34
+ }
35
+ const getPasswordResult = (0, child_process_1.spawnSync)('aws', [
36
+ 'ecr', 'get-login-password',
37
+ '--region', config.region,
38
+ '--profile', profile,
39
+ ], {
40
+ shell: false,
41
+ timeout: ECR_TIMEOUT_MS,
42
+ maxBuffer: 1024 * 1024,
43
+ stdio: ['pipe', 'pipe', 'pipe'],
44
+ env: {
45
+ ...(0, utils_1.getSubprocessEnv)(),
46
+ AWS_PROFILE: profile,
47
+ },
48
+ });
49
+ if (getPasswordResult.error) {
50
+ if (getPasswordResult.error.message.includes('ENOENT')) {
51
+ throw new Error('AWS CLI not found. Please install AWS CLI v2.');
52
+ }
53
+ if (getPasswordResult.error.message.includes('ETIMEDOUT')) {
54
+ throw new Error('ECR get-login-password timed out.');
55
+ }
56
+ throw new Error((0, utils_1.sanitizeOutput)(getPasswordResult.error.message));
57
+ }
58
+ if (getPasswordResult.status !== 0) {
59
+ const stderr = getPasswordResult.stderr?.toString() || '';
60
+ if (stderr.includes('ExpiredTokenException') || stderr.includes('credentials')) {
61
+ throw new Error('AWS credentials expired. SSO session may have ended.');
62
+ }
63
+ if (stderr.includes('AccessDeniedException')) {
64
+ throw new Error(`Access denied to ECR. Check IAM permissions for profile '${profile}'.`);
65
+ }
66
+ const errorOutput = (0, utils_1.sanitizeOutput)(stderr || 'Unknown error');
67
+ throw new Error(`ECR get-login-password failed: ${errorOutput}`);
68
+ }
69
+ const password = getPasswordResult.stdout?.toString().trim();
70
+ if (!password) {
71
+ throw new Error('ECR returned empty password.');
72
+ }
73
+ // Docker login using the password
74
+ if (options.verbose) {
75
+ console.log(` [verbose] Running: docker login --username AWS --password-stdin ${registryUrl}`);
76
+ }
77
+ const dockerLoginResult = (0, child_process_1.spawnSync)('docker', [
78
+ 'login',
79
+ '--username', 'AWS',
80
+ '--password-stdin',
81
+ registryUrl,
82
+ ], {
83
+ shell: false,
84
+ timeout: ECR_TIMEOUT_MS,
85
+ maxBuffer: 1024 * 1024,
86
+ input: password,
87
+ stdio: ['pipe', 'pipe', 'pipe'],
88
+ env: (0, utils_1.getSubprocessEnv)(),
89
+ });
90
+ if (dockerLoginResult.error) {
91
+ throw new Error((0, utils_1.sanitizeOutput)(dockerLoginResult.error.message));
92
+ }
93
+ if (dockerLoginResult.status !== 0) {
94
+ const stderr = dockerLoginResult.stderr?.toString() || '';
95
+ const errorOutput = (0, utils_1.sanitizeOutput)(stderr || 'Unknown error');
96
+ throw new Error(`Docker login failed: ${errorOutput}`);
97
+ }
98
+ if (options.verbose) {
99
+ console.log(' [verbose] ECR authentication successful');
100
+ }
101
+ return {
102
+ success: true,
103
+ skipped: false,
104
+ duration: 0,
105
+ };
106
+ }
107
+ //# sourceMappingURL=ecr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecr.js","sourceRoot":"","sources":["../../../src/commands/login/ecr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Main login command that orchestrates SSO, CodeArtifact, and ECR authentication
4
+ */
5
+ export declare const loginCommand: Command;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;GAEG;AACH,eAAO,MAAM,YAAY,SAOH,CAAC"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loginCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const config_1 = require("./config");
10
+ const sso_1 = require("./sso");
11
+ const codeartifact_1 = require("./codeartifact");
12
+ const ecr_1 = require("./ecr");
13
+ const types_1 = require("./types");
14
+ /**
15
+ * Main login command that orchestrates SSO, CodeArtifact, and ECR authentication
16
+ */
17
+ exports.loginCommand = new commander_1.Command('login')
18
+ .description('Authenticate to AWS SSO, CodeArtifact (npm), and ECR (Docker)')
19
+ .option('-p, --profile <name>', 'AWS SSO profile to use')
20
+ .option('--sso-only', 'Only authenticate to SSO, skip CodeArtifact and ECR')
21
+ .option('--no-color', 'Disable colored output')
22
+ .option('-q, --quiet', 'Suppress non-error output')
23
+ .option('-v, --verbose', 'Show detailed output')
24
+ .action(handleLogin);
25
+ /**
26
+ * Handle the login command execution
27
+ */
28
+ async function handleLogin(options) {
29
+ const config = await (0, config_1.loadConfig)();
30
+ const profile = (0, types_1.getEffectiveProfile)(options, config ?? undefined);
31
+ const result = {
32
+ sso: { success: false, skipped: false, duration: 0 },
33
+ codeartifact: { success: false, skipped: false, duration: 0 },
34
+ ecr: { success: false, skipped: false, duration: 0 },
35
+ };
36
+ // Step 1: SSO Authentication (REQUIRED)
37
+ if (!options.quiet) {
38
+ console.log(chalk_1.default.blue(`[1/3] AWS SSO ...`));
39
+ }
40
+ const ssoStart = Date.now();
41
+ try {
42
+ result.sso = await (0, sso_1.authenticateSSO)(profile, options);
43
+ result.sso.duration = Date.now() - ssoStart;
44
+ if (!options.quiet) {
45
+ console.log(chalk_1.default.green(` ✓ authenticated (profile: ${profile})`));
46
+ }
47
+ }
48
+ catch (error) {
49
+ result.sso = {
50
+ success: false,
51
+ skipped: false,
52
+ error: error.message,
53
+ duration: Date.now() - ssoStart,
54
+ };
55
+ // SSO failed - skip remaining services
56
+ result.codeartifact = { success: false, skipped: true, duration: 0 };
57
+ result.ecr = { success: false, skipped: true, duration: 0 };
58
+ reportResults(result, options);
59
+ process.exit(2); // Exit code 2 = SSO failure
60
+ }
61
+ // Check if --sso-only flag is set
62
+ if (options.ssoOnly) {
63
+ result.codeartifact = { success: false, skipped: true, duration: 0 };
64
+ result.ecr = { success: false, skipped: true, duration: 0 };
65
+ reportResults(result, options);
66
+ process.exit(0);
67
+ }
68
+ // Step 2: CodeArtifact (npm) - depends on SSO
69
+ if (!options.quiet) {
70
+ console.log(chalk_1.default.blue(`[2/3] CodeArtifact (npm) ...`));
71
+ }
72
+ if (config && (0, types_1.hasCodeArtifactConfig)(config)) {
73
+ const caStart = Date.now();
74
+ try {
75
+ result.codeartifact = await (0, codeartifact_1.configureCodeArtifact)(config.codeartifact, profile, options);
76
+ result.codeartifact.duration = Date.now() - caStart;
77
+ if (!options.quiet) {
78
+ console.log(chalk_1.default.green(` ✓ configured`));
79
+ }
80
+ }
81
+ catch (error) {
82
+ result.codeartifact = {
83
+ success: false,
84
+ skipped: false,
85
+ error: error.message,
86
+ duration: Date.now() - caStart,
87
+ };
88
+ if (!options.quiet) {
89
+ console.log(chalk_1.default.yellow(` ⚠ failed: ${error.message}`));
90
+ }
91
+ }
92
+ }
93
+ else {
94
+ result.codeartifact = { success: false, skipped: true, duration: 0 };
95
+ if (!options.quiet) {
96
+ console.log(chalk_1.default.gray(` ○ skipped (not configured)`));
97
+ }
98
+ }
99
+ // Step 3: ECR (Docker) - depends on SSO, independent of CodeArtifact
100
+ if (!options.quiet) {
101
+ console.log(chalk_1.default.blue(`[3/3] ECR (Docker) ...`));
102
+ }
103
+ if (config && (0, types_1.hasEcrConfig)(config)) {
104
+ const ecrStart = Date.now();
105
+ try {
106
+ result.ecr = await (0, ecr_1.configureECR)(config.ecr, profile, options);
107
+ result.ecr.duration = Date.now() - ecrStart;
108
+ if (!options.quiet) {
109
+ console.log(chalk_1.default.green(` ✓ configured`));
110
+ }
111
+ }
112
+ catch (error) {
113
+ result.ecr = {
114
+ success: false,
115
+ skipped: false,
116
+ error: error.message,
117
+ duration: Date.now() - ecrStart,
118
+ };
119
+ if (!options.quiet) {
120
+ console.log(chalk_1.default.yellow(` ⚠ failed: ${error.message}`));
121
+ }
122
+ }
123
+ }
124
+ else {
125
+ result.ecr = { success: false, skipped: true, duration: 0 };
126
+ if (!options.quiet) {
127
+ console.log(chalk_1.default.gray(` ○ skipped (not configured)`));
128
+ }
129
+ }
130
+ reportResults(result, options);
131
+ // Exit codes:
132
+ // 0 = SSO succeeded + at least one of (CodeArtifact, ECR) succeeded or was skipped intentionally
133
+ // 1 = SSO succeeded but both CodeArtifact and ECR failed (not skipped)
134
+ const caOk = result.codeartifact.success || result.codeartifact.skipped;
135
+ const ecrOk = result.ecr.success || result.ecr.skipped;
136
+ const postSsoSuccess = caOk || ecrOk;
137
+ process.exit(postSsoSuccess ? 0 : 1);
138
+ }
139
+ /**
140
+ * Report login results to console
141
+ */
142
+ function reportResults(result, options) {
143
+ if (options.quiet)
144
+ return;
145
+ console.log('');
146
+ console.log('=== Login Results ===');
147
+ const services = [
148
+ { name: 'SSO', result: result.sso },
149
+ { name: 'CodeArtifact', result: result.codeartifact },
150
+ { name: 'ECR', result: result.ecr },
151
+ ];
152
+ let successCount = 0;
153
+ let skippedCount = 0;
154
+ for (const service of services) {
155
+ let status;
156
+ if (service.result.skipped) {
157
+ status = chalk_1.default.gray('○ SKIPPED');
158
+ skippedCount++;
159
+ }
160
+ else if (service.result.success) {
161
+ status = chalk_1.default.green('✓ OK');
162
+ successCount++;
163
+ }
164
+ else {
165
+ status = chalk_1.default.red('✗ FAILED');
166
+ }
167
+ console.log(`${service.name}: ${status}`);
168
+ if (!service.result.success && !service.result.skipped && service.result.error) {
169
+ console.log(chalk_1.default.red(` → ${service.result.error}`));
170
+ }
171
+ }
172
+ const total = services.length - skippedCount;
173
+ console.log('');
174
+ console.log(`Total: ${successCount}/${total} services authenticated`);
175
+ console.log('');
176
+ }
177
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/login/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { ServiceResult, LoginOptions } from './types';
2
+ /**
3
+ * Authenticate to AWS SSO using the AWS CLI
4
+ *
5
+ * @param profile - AWS profile name to authenticate with
6
+ * @param options - Login command options
7
+ * @returns ServiceResult indicating success/failure
8
+ */
9
+ export declare function authenticateSSO(profile: string, options: LoginOptions): Promise<ServiceResult>;
10
+ /**
11
+ * Check if SSO session is valid for the given profile
12
+ *
13
+ * @param profile - AWS profile name to check
14
+ * @returns true if session is valid, false otherwise
15
+ */
16
+ export declare function checkSSOSession(profile: string): Promise<boolean>;
17
+ //# sourceMappingURL=sso.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../../../src/commands/login/sso.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKtD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CA2DxB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAevE"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authenticateSSO = authenticateSSO;
4
+ exports.checkSSOSession = checkSSOSession;
5
+ const child_process_1 = require("child_process");
6
+ const utils_1 = require("./utils");
7
+ const SSO_TIMEOUT_MS = 60000; // 60 seconds for browser interaction
8
+ /**
9
+ * Authenticate to AWS SSO using the AWS CLI
10
+ *
11
+ * @param profile - AWS profile name to authenticate with
12
+ * @param options - Login command options
13
+ * @returns ServiceResult indicating success/failure
14
+ */
15
+ async function authenticateSSO(profile, options) {
16
+ // Validate profile name to prevent injection
17
+ (0, utils_1.validateProfileName)(profile);
18
+ if (options.verbose) {
19
+ console.log(` [verbose] Running: aws sso login --profile ${profile}`);
20
+ }
21
+ const result = (0, child_process_1.spawnSync)('aws', ['sso', 'login', '--profile', profile], {
22
+ shell: false,
23
+ timeout: SSO_TIMEOUT_MS,
24
+ maxBuffer: 1024 * 1024,
25
+ stdio: ['inherit', 'pipe', 'pipe'], // inherit stdin for browser interaction
26
+ env: {
27
+ ...(0, utils_1.getSubprocessEnv)(),
28
+ AWS_PROFILE: profile,
29
+ },
30
+ });
31
+ if (result.error) {
32
+ // Handle spawn errors (command not found, timeout, etc.)
33
+ if (result.error.message.includes('ENOENT')) {
34
+ throw new Error('AWS CLI not found. Please install AWS CLI v2: https://aws.amazon.com/cli/');
35
+ }
36
+ if (result.error.message.includes('ETIMEDOUT')) {
37
+ throw new Error('SSO login timed out. Please try again.');
38
+ }
39
+ throw new Error((0, utils_1.sanitizeOutput)(result.error.message));
40
+ }
41
+ if (result.status !== 0) {
42
+ const stderr = result.stderr?.toString() || '';
43
+ const stdout = result.stdout?.toString() || '';
44
+ // Parse common error conditions
45
+ if (stderr.includes('profile') && stderr.includes('not found')) {
46
+ throw new Error(`Profile '${profile}' not found. Run: aws configure list-profiles`);
47
+ }
48
+ if (stderr.includes('Token has expired')) {
49
+ throw new Error('SSO session expired. Browser authentication required.');
50
+ }
51
+ if (stderr.includes('No SSO configuration')) {
52
+ throw new Error(`Profile '${profile}' is not configured for SSO. Check ~/.aws/config`);
53
+ }
54
+ // Generic error with sanitized output
55
+ const errorOutput = (0, utils_1.sanitizeOutput)(stderr || stdout || 'Unknown error');
56
+ throw new Error(`SSO login failed: ${errorOutput}`);
57
+ }
58
+ if (options.verbose) {
59
+ console.log(' [verbose] SSO authentication successful');
60
+ }
61
+ return {
62
+ success: true,
63
+ skipped: false,
64
+ duration: 0, // Will be set by caller
65
+ };
66
+ }
67
+ /**
68
+ * Check if SSO session is valid for the given profile
69
+ *
70
+ * @param profile - AWS profile name to check
71
+ * @returns true if session is valid, false otherwise
72
+ */
73
+ async function checkSSOSession(profile) {
74
+ (0, utils_1.validateProfileName)(profile);
75
+ const result = (0, child_process_1.spawnSync)('aws', ['sts', 'get-caller-identity', '--profile', profile], {
76
+ shell: false,
77
+ timeout: 10000,
78
+ maxBuffer: 1024 * 1024,
79
+ stdio: ['pipe', 'pipe', 'pipe'],
80
+ env: {
81
+ ...(0, utils_1.getSubprocessEnv)(),
82
+ AWS_PROFILE: profile,
83
+ },
84
+ });
85
+ return result.status === 0;
86
+ }
87
+ //# sourceMappingURL=sso.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.js","sourceRoot":"","sources":["../../../src/commands/login/sso.ts"],"names":[],"mappings":";;AAaA,0CA8DC;AAQD,0CAeC;AAlGD,iDAA0C;AAE1C,mCAAgF;AAEhF,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,qCAAqC;AAEnE;;;;;;GAMG;AACI,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,OAAqB;IAErB,6CAA6C;IAC7C,IAAA,2BAAmB,EAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,gDAAgD,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;QACtE,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,cAAc;QACvB,SAAS,EAAE,IAAI,GAAG,IAAI;QACtB,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,wCAAwC;QAC5E,GAAG,EAAE;YACH,GAAG,IAAA,wBAAgB,GAAE;YACrB,WAAW,EAAE,OAAO;SACrB;KACF,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,yDAAyD;QACzD,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,IAAA,sBAAc,EAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAE/C,gCAAgC;QAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,+CAA+C,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,YAAY,OAAO,kDAAkD,CAAC,CAAC;QACzF,CAAC;QAED,sCAAsC;QACtC,MAAM,WAAW,GAAG,IAAA,sBAAc,EAAC,MAAM,IAAI,MAAM,IAAI,eAAe,CAAC,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,CAAC,EAAE,wBAAwB;KACtC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CAAC,OAAe;IACnD,IAAA,2BAAmB,EAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,MAAM,GAAG,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;QACpF,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,KAAK;QACd,SAAS,EAAE,IAAI,GAAG,IAAI;QACtB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,GAAG,EAAE;YACH,GAAG,IAAA,wBAAgB,GAAE;YACrB,WAAW,EAAE,OAAO;SACrB;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Data Models for Full Login Feature
3
+ *
4
+ * Defines TypeScript interfaces for the Padua CLI login workflow including:
5
+ * - Configuration schema (padua.config.json)
6
+ * - Authentication service results
7
+ * - Login command outcomes
8
+ * - CLI command options
9
+ */
10
+ /**
11
+ * PaduaConfig - Main configuration object persisted to padua.config.json
12
+ */
13
+ export interface PaduaConfig {
14
+ /** Default AWS SSO profile to use if not specified via CLI flag */
15
+ defaultProfile?: string;
16
+ /** Default AWS region for all service operations (default: "us-east-1") */
17
+ region?: string;
18
+ /** CodeArtifact repository configuration for npm authentication */
19
+ codeartifact?: CodeArtifactConfig;
20
+ /** ECR registry configuration for Docker authentication */
21
+ ecr?: EcrConfig;
22
+ }
23
+ /**
24
+ * CodeArtifactConfig - Configuration for AWS CodeArtifact npm repository access
25
+ */
26
+ export interface CodeArtifactConfig {
27
+ /** CodeArtifact domain name (1-127 chars, alphanumeric with hyphens) */
28
+ domain: string;
29
+ /** AWS account ID owning the CodeArtifact domain (12-digit) */
30
+ domainOwner: string;
31
+ /** Repository name within the CodeArtifact domain */
32
+ repository: string;
33
+ }
34
+ /**
35
+ * EcrConfig - Configuration for AWS ECR Docker registry access
36
+ */
37
+ export interface EcrConfig {
38
+ /** AWS account ID containing the ECR registry (12-digit) */
39
+ accountId: string;
40
+ /** AWS region containing the ECR registry */
41
+ region: string;
42
+ }
43
+ /**
44
+ * ServiceResult - Outcome of authenticating to a single service
45
+ */
46
+ export interface ServiceResult {
47
+ /** Whether authentication succeeded */
48
+ success: boolean;
49
+ /** Whether this service was skipped (not attempted) */
50
+ skipped: boolean;
51
+ /** Error message if authentication failed */
52
+ error?: string;
53
+ /** Time in milliseconds for this authentication operation */
54
+ duration: number;
55
+ }
56
+ /**
57
+ * LoginResult - Aggregated outcome of the full login operation
58
+ */
59
+ export interface LoginResult {
60
+ /** AWS SSO authentication result */
61
+ sso: ServiceResult;
62
+ /** CodeArtifact npm repository authentication result */
63
+ codeartifact: ServiceResult;
64
+ /** ECR Docker registry authentication result */
65
+ ecr: ServiceResult;
66
+ }
67
+ /**
68
+ * LoginOptions - Command-line options and flags for `padua login`
69
+ */
70
+ export interface LoginOptions {
71
+ /** AWS SSO profile to authenticate with */
72
+ profile?: string;
73
+ /** Authenticate to SSO only, skip CodeArtifact and ECR */
74
+ ssoOnly?: boolean;
75
+ /** Disable colored output in terminal */
76
+ noColor?: boolean;
77
+ /** Suppress all output except errors */
78
+ quiet?: boolean;
79
+ /** Enable verbose output with debugging information */
80
+ verbose?: boolean;
81
+ }
82
+ /** Check if a value is a valid AWS account ID (12-digit string) */
83
+ export declare function isValidAccountId(value: string): boolean;
84
+ /** Check if a value is a valid AWS region code */
85
+ export declare function isValidRegion(value: string): boolean;
86
+ /** Check if a value is a valid profile name (alphanumeric, hyphens, underscores) */
87
+ export declare function isValidProfileName(value: string): boolean;
88
+ /** Check if a value is a valid domain name (alphanumeric, hyphens) */
89
+ export declare function isValidDomainName(value: string): boolean;
90
+ /** Check if a value is a valid repository name (lowercase alphanumeric, hyphens) */
91
+ export declare function isValidRepositoryName(value: string): boolean;
92
+ /** Check if configuration has CodeArtifact configured */
93
+ export declare function hasCodeArtifactConfig(config: PaduaConfig): boolean;
94
+ /** Check if configuration has ECR configured */
95
+ export declare function hasEcrConfig(config: PaduaConfig): boolean;
96
+ /** Get the effective profile to use (preference order: options, config, default) */
97
+ export declare function getEffectiveProfile(options: LoginOptions, config?: PaduaConfig): string;
98
+ /** Get the effective region to use (preference order: config, default) */
99
+ export declare function getEffectiveRegion(config?: PaduaConfig): string;
100
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/login/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,mEAAmE;IACnE,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAElC,2DAA2D;IAC3D,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IAEf,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IAEpB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAElB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IAEjB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,GAAG,EAAE,aAAa,CAAC;IAEnB,wDAAwD;IACxD,YAAY,EAAE,aAAa,CAAC;IAE5B,gDAAgD;IAChD,GAAG,EAAE,aAAa,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,wCAAwC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAapD;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAElE;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAEzD;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAEvF;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAE/D"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ /**
3
+ * Data Models for Full Login Feature
4
+ *
5
+ * Defines TypeScript interfaces for the Padua CLI login workflow including:
6
+ * - Configuration schema (padua.config.json)
7
+ * - Authentication service results
8
+ * - Login command outcomes
9
+ * - CLI command options
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isValidAccountId = isValidAccountId;
13
+ exports.isValidRegion = isValidRegion;
14
+ exports.isValidProfileName = isValidProfileName;
15
+ exports.isValidDomainName = isValidDomainName;
16
+ exports.isValidRepositoryName = isValidRepositoryName;
17
+ exports.hasCodeArtifactConfig = hasCodeArtifactConfig;
18
+ exports.hasEcrConfig = hasEcrConfig;
19
+ exports.getEffectiveProfile = getEffectiveProfile;
20
+ exports.getEffectiveRegion = getEffectiveRegion;
21
+ // Type Guards
22
+ /** Check if a value is a valid AWS account ID (12-digit string) */
23
+ function isValidAccountId(value) {
24
+ return /^\d{12}$/.test(value);
25
+ }
26
+ /** Check if a value is a valid AWS region code */
27
+ function isValidRegion(value) {
28
+ const validRegions = [
29
+ 'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2',
30
+ 'eu-west-1', 'eu-west-2', 'eu-west-3', 'eu-central-1', 'eu-north-1',
31
+ 'ap-northeast-1', 'ap-northeast-2', 'ap-northeast-3',
32
+ 'ap-southeast-1', 'ap-southeast-2',
33
+ 'ap-south-1',
34
+ 'ca-central-1',
35
+ 'sa-east-1',
36
+ 'af-south-1',
37
+ 'me-south-1',
38
+ ];
39
+ return validRegions.includes(value);
40
+ }
41
+ /** Check if a value is a valid profile name (alphanumeric, hyphens, underscores) */
42
+ function isValidProfileName(value) {
43
+ return /^[a-zA-Z0-9\-_]{1,128}$/.test(value);
44
+ }
45
+ /** Check if a value is a valid domain name (alphanumeric, hyphens) */
46
+ function isValidDomainName(value) {
47
+ return /^[a-z0-9\-]{1,127}$/.test(value) && !value.startsWith('-') && !value.endsWith('-');
48
+ }
49
+ /** Check if a value is a valid repository name (lowercase alphanumeric, hyphens) */
50
+ function isValidRepositoryName(value) {
51
+ return /^[a-z0-9\-]{1,100}$/.test(value) && !value.startsWith('-') && !value.endsWith('-');
52
+ }
53
+ /** Check if configuration has CodeArtifact configured */
54
+ function hasCodeArtifactConfig(config) {
55
+ return !!(config.codeartifact?.domain && config.codeartifact?.domainOwner && config.codeartifact?.repository);
56
+ }
57
+ /** Check if configuration has ECR configured */
58
+ function hasEcrConfig(config) {
59
+ return !!(config.ecr?.accountId && config.ecr?.region);
60
+ }
61
+ /** Get the effective profile to use (preference order: options, config, default) */
62
+ function getEffectiveProfile(options, config) {
63
+ return options.profile || config?.defaultProfile || 'default';
64
+ }
65
+ /** Get the effective region to use (preference order: config, default) */
66
+ function getEffectiveRegion(config) {
67
+ return config?.region || 'us-east-1';
68
+ }
69
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/commands/login/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAkGH,4CAEC;AAGD,sCAaC;AAGD,gDAEC;AAGD,8CAEC;AAGD,sDAEC;AAGD,sDAEC;AAGD,oCAEC;AAGD,kDAEC;AAGD,gDAEC;AAxDD,cAAc;AAEd,mEAAmE;AACnE,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,kDAAkD;AAClD,SAAgB,aAAa,CAAC,KAAa;IACzC,MAAM,YAAY,GAAG;QACnB,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW;QAClD,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY;QACnE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB;QACpD,gBAAgB,EAAE,gBAAgB;QAClC,YAAY;QACZ,cAAc;QACd,WAAW;QACX,YAAY;QACZ,YAAY;KACb,CAAC;IACF,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,oFAAoF;AACpF,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,OAAO,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,sEAAsE;AACtE,SAAgB,iBAAiB,CAAC,KAAa;IAC7C,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED,oFAAoF;AACpF,SAAgB,qBAAqB,CAAC,KAAa;IACjD,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC;AAED,yDAAyD;AACzD,SAAgB,qBAAqB,CAAC,MAAmB;IACvD,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,WAAW,IAAI,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAChH,CAAC;AAED,gDAAgD;AAChD,SAAgB,YAAY,CAAC,MAAmB;IAC9C,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC;AAED,oFAAoF;AACpF,SAAgB,mBAAmB,CAAC,OAAqB,EAAE,MAAoB;IAC7E,OAAO,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,cAAc,IAAI,SAAS,CAAC;AAChE,CAAC;AAED,0EAA0E;AAC1E,SAAgB,kBAAkB,CAAC,MAAoB;IACrD,OAAO,MAAM,EAAE,MAAM,IAAI,WAAW,CAAC;AACvC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Validate profile name before using in subprocess
3
+ * Throws if invalid to prevent injection attacks
4
+ */
5
+ export declare function validateProfileName(profile: string): void;
6
+ /**
7
+ * Sanitize tokens and credentials from output
8
+ * Removes AWS access keys, session tokens, and other sensitive data
9
+ */
10
+ export declare function sanitizeOutput(output: string): string;
11
+ /**
12
+ * Sanitize error messages before displaying to user
13
+ */
14
+ export declare function sanitizeErrorMessage(error: string): string;
15
+ /**
16
+ * Get environment variables safe to pass to subprocesses
17
+ * Only passes necessary variables to minimize exposure
18
+ */
19
+ export declare function getSubprocessEnv(): NodeJS.ProcessEnv;
20
+ /**
21
+ * Format duration in milliseconds to human readable string
22
+ */
23
+ export declare function formatDuration(ms: number): string;
24
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/commands/login/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBrD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,UAAU,CAqCpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAKjD"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateProfileName = validateProfileName;
4
+ exports.sanitizeOutput = sanitizeOutput;
5
+ exports.sanitizeErrorMessage = sanitizeErrorMessage;
6
+ exports.getSubprocessEnv = getSubprocessEnv;
7
+ exports.formatDuration = formatDuration;
8
+ const types_1 = require("./types");
9
+ /**
10
+ * Validate profile name before using in subprocess
11
+ * Throws if invalid to prevent injection attacks
12
+ */
13
+ function validateProfileName(profile) {
14
+ if (!(0, types_1.isValidProfileName)(profile)) {
15
+ throw new Error(`Invalid profile name: ${profile}. Profile names must be alphanumeric with hyphens/underscores (1-128 chars).`);
16
+ }
17
+ }
18
+ /**
19
+ * Sanitize tokens and credentials from output
20
+ * Removes AWS access keys, session tokens, and other sensitive data
21
+ */
22
+ function sanitizeOutput(output) {
23
+ // Remove AWS access key IDs (AKIA...)
24
+ let sanitized = output.replace(/AKIA[A-Z0-9]{16}/g, '[REDACTED_ACCESS_KEY]');
25
+ // Remove AWS secret access keys (40 char base64)
26
+ sanitized = sanitized.replace(/[A-Za-z0-9/+=]{40}/g, (match) => {
27
+ // Only redact if it looks like a secret key (contains mixed case and special chars)
28
+ if (/[A-Z]/.test(match) && /[a-z]/.test(match) && /[/+=]/.test(match)) {
29
+ return '[REDACTED_SECRET]';
30
+ }
31
+ return match;
32
+ });
33
+ // Remove session tokens (long base64 strings)
34
+ sanitized = sanitized.replace(/[A-Za-z0-9/+=]{100,}/g, '[REDACTED_TOKEN]');
35
+ // Remove password-like patterns after common keywords
36
+ sanitized = sanitized.replace(/(password|token|secret|credential)[\s:=]+\S+/gi, '$1=[REDACTED]');
37
+ return sanitized;
38
+ }
39
+ /**
40
+ * Sanitize error messages before displaying to user
41
+ */
42
+ function sanitizeErrorMessage(error) {
43
+ return sanitizeOutput(error);
44
+ }
45
+ /**
46
+ * Get environment variables safe to pass to subprocesses
47
+ * Only passes necessary variables to minimize exposure
48
+ */
49
+ function getSubprocessEnv() {
50
+ const safeEnv = {};
51
+ // Whitelist of environment variables to pass
52
+ const whitelist = [
53
+ 'PATH',
54
+ 'HOME',
55
+ 'USER',
56
+ 'SHELL',
57
+ 'TERM',
58
+ 'AWS_PROFILE',
59
+ 'AWS_DEFAULT_REGION',
60
+ 'AWS_CONFIG_FILE',
61
+ 'AWS_SHARED_CREDENTIALS_FILE',
62
+ // Required for Windows
63
+ 'SYSTEMROOT',
64
+ 'COMSPEC',
65
+ 'PATHEXT',
66
+ 'APPDATA',
67
+ 'LOCALAPPDATA',
68
+ 'USERPROFILE',
69
+ 'TEMP',
70
+ 'TMP',
71
+ 'HOMEDRIVE',
72
+ 'HOMEPATH',
73
+ // Required for macOS/Linux
74
+ 'TMPDIR',
75
+ 'XDG_CONFIG_HOME',
76
+ ];
77
+ for (const key of whitelist) {
78
+ if (process.env[key]) {
79
+ safeEnv[key] = process.env[key];
80
+ }
81
+ }
82
+ return safeEnv;
83
+ }
84
+ /**
85
+ * Format duration in milliseconds to human readable string
86
+ */
87
+ function formatDuration(ms) {
88
+ if (ms < 1000) {
89
+ return `${ms}ms`;
90
+ }
91
+ return `${(ms / 1000).toFixed(1)}s`;
92
+ }
93
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/commands/login/utils.ts"],"names":[],"mappings":";;AAMA,kDAIC;AAMD,wCAoBC;AAKD,oDAEC;AAMD,4CAqCC;AAKD,wCAKC;AAhGD,mCAA6C;AAE7C;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,OAAe;IACjD,IAAI,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,8EAA8E,CAAC,CAAC;IAClI,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,MAAc;IAC3C,sCAAsC;IACtC,IAAI,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;IAE7E,iDAAiD;IACjD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC7D,oFAAoF;QACpF,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,8CAA8C;IAC9C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;IAE3E,sDAAsD;IACtD,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,gDAAgD,EAAE,eAAe,CAAC,CAAC;IAEjG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,KAAa;IAChD,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,6CAA6C;IAC7C,MAAM,SAAS,GAAG;QAChB,MAAM;QACN,MAAM;QACN,MAAM;QACN,OAAO;QACP,MAAM;QACN,aAAa;QACb,oBAAoB;QACpB,iBAAiB;QACjB,6BAA6B;QAC7B,uBAAuB;QACvB,YAAY;QACZ,SAAS;QACT,SAAS;QACT,SAAS;QACT,cAAc;QACd,aAAa;QACb,MAAM;QACN,KAAK;QACL,WAAW;QACX,UAAU;QACV,2BAA2B;QAC3B,QAAQ;QACR,iBAAiB;KAClB,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QACd,OAAO,GAAG,EAAE,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const login_1 = require("./commands/login");
6
+ const program = new commander_1.Command();
7
+ program
8
+ .name('padua')
9
+ .description('Unified AWS infrastructure management CLI')
10
+ .version('1.0.0');
11
+ // Register commands
12
+ program.addCommand(login_1.loginCommand);
13
+ program.parse();
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAEhD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,2CAA2C,CAAC;KACxD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,oBAAY,CAAC,CAAC;AAEjC,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@padua/cli",
3
+ "version": "1.0.0",
4
+ "description": "Unified AWS infrastructure management CLI",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "padua": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "lint": "eslint src --ext .ts",
15
+ "type-check": "tsc --noEmit",
16
+ "test": "jest",
17
+ "test:watch": "jest --watch",
18
+ "test:coverage": "jest --coverage",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "keywords": [
28
+ "aws",
29
+ "sso",
30
+ "cli",
31
+ "codeartifact",
32
+ "ecr",
33
+ "authentication"
34
+ ],
35
+ "author": "",
36
+ "license": "MIT",
37
+ "dependencies": {
38
+ "commander": "^12.1.0",
39
+ "chalk": "^4.1.2"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.10.0",
43
+ "typescript": "^5.3.0",
44
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
45
+ "@typescript-eslint/parser": "^6.13.0",
46
+ "eslint": "^8.55.0",
47
+ "jest": "^29.7.0",
48
+ "@types/jest": "^29.5.0",
49
+ "ts-jest": "^29.1.0"
50
+ }
51
+ }