switch-profile 1.1.0 → 2.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/README.md +197 -94
- package/dist/cli.js +7921 -0
- package/index.js +12 -409
- package/package.json +31 -25
- package/.eslintrc.json +0 -39
- package/CHANGELOG.md +0 -120
- package/docs/architecture.md +0 -199
- package/docs/aws-profile-management.md +0 -325
- package/docs/cli-interface.md +0 -304
- package/docs/configuration-files.md +0 -240
- package/docs/development-guide.md +0 -168
- package/docs/gotchas.md +0 -82
- package/skills-lock.json +0 -73
- package/src/aws/index.js +0 -574
- package/src/aws/regions.js +0 -103
- package/src/core.js +0 -64
- package/src/fileHelper.js +0 -433
package/docs/cli-interface.md
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
# CLI Interface
|
|
2
|
-
|
|
3
|
-
This document provides a detailed walkthrough of every menu, prompt, and user flow in `switch-profile`.
|
|
4
|
-
|
|
5
|
-
## Invocation
|
|
6
|
-
|
|
7
|
-
```shell
|
|
8
|
-
npx switch-profile # Run via npx (no install)
|
|
9
|
-
switch-profile # If installed globally
|
|
10
|
-
npx switch-profile switch # Explicit command (same as default)
|
|
11
|
-
npx switch-profile --version # Print version number
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
The `switch` command is the only command and runs automatically when no arguments are provided.
|
|
15
|
-
|
|
16
|
-
## Main Flow
|
|
17
|
-
|
|
18
|
-
### Step 1: AWS CLI Check
|
|
19
|
-
|
|
20
|
-
Before anything else, the tool verifies AWS CLI v2+ is installed. If not found, it prints platform-specific installation instructions:
|
|
21
|
-
|
|
22
|
-
- **macOS:** `brew install awscli && brew link --overwrite awscli`
|
|
23
|
-
- **Linux:** curl + unzip instructions for the AWS CLI v2 installer
|
|
24
|
-
- **Windows:** "Not installed" message with a link to the AWS CLI MSI installer download page
|
|
25
|
-
|
|
26
|
-
### Step 2: Default Profile Status
|
|
27
|
-
|
|
28
|
-
If a default profile is set, it displays the current status with color-coded information:
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Current default profile: sso-dev
|
|
32
|
-
INFO: This profile expires in 45.23 minutes # Cyan - healthy
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
Current default profile: sso-dev
|
|
37
|
-
WARNING: Expires in less than 2 minutes # Yellow - expiring soon
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
Current default profile: sso-dev
|
|
42
|
-
WARNING: Expired # Yellow - expired
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
Current default profile: unknown (pick one up in the list below...) # No profile set
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
The expiry time is calculated in minutes to two decimal places.
|
|
50
|
-
|
|
51
|
-
### Step 3: Profile List
|
|
52
|
-
|
|
53
|
-
If profiles exist, the main selection menu appears:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
? Choose one of the following 3 profiles:
|
|
57
|
-
More options
|
|
58
|
-
Abort
|
|
59
|
-
──────────────
|
|
60
|
-
1. sso-dev (SSO [role:Admin - account:123456789012])
|
|
61
|
-
2. sso-prod (SSO [role:ReadOnly - account:987654321098])
|
|
62
|
-
3. my-standard-profile
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
- **SSO profiles** include role and account info in their display name.
|
|
66
|
-
- **Standard profiles** show just the profile name.
|
|
67
|
-
- The list supports up to 20 items per page.
|
|
68
|
-
|
|
69
|
-
If no profiles exist, you get:
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
? There no profiles yet. Do you wish to create one now? (Y/n)
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Step 4a: Select a Profile
|
|
76
|
-
|
|
77
|
-
Selecting a profile from the list sets it as the `default`. For SSO profiles, this may:
|
|
78
|
-
|
|
79
|
-
1. Open your browser for SSO authentication (if the session expired).
|
|
80
|
-
2. Wait for you to complete the login (up to 5 minutes).
|
|
81
|
-
3. Retrieve temporary credentials from the AWS CLI cache.
|
|
82
|
-
|
|
83
|
-
On success:
|
|
84
|
-
|
|
85
|
-
**Linux / macOS:**
|
|
86
|
-
```
|
|
87
|
-
AWS profile sso-dev successfully set up as default. # Green
|
|
88
|
-
|
|
89
|
-
┌─────────────────────────────────────────────────────────┐
|
|
90
|
-
│ To lock this profile to this terminal session, run: │ # Cyan
|
|
91
|
-
│ │
|
|
92
|
-
│ export AWS_PROFILE=sso-dev │ # Cyan + Bold
|
|
93
|
-
│ │
|
|
94
|
-
│ This prevents other terminals from affecting this one. │
|
|
95
|
-
└─────────────────────────────────────────────────────────┘
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**Windows:**
|
|
99
|
-
```
|
|
100
|
-
AWS profile sso-dev successfully set up as default. # Green
|
|
101
|
-
|
|
102
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
103
|
-
│ To lock this profile to this terminal session, run: │ # Cyan
|
|
104
|
-
│ │
|
|
105
|
-
│ PowerShell: $env:AWS_PROFILE = "sso-dev" │ # Cyan + Bold
|
|
106
|
-
│ CMD: set AWS_PROFILE=sso-dev │ # Cyan + Bold
|
|
107
|
-
│ │
|
|
108
|
-
│ This prevents other terminals from affecting this one. │
|
|
109
|
-
└──────────────────────────────────────────────────────────────┘
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
This hint appears after every successful profile switch, refresh, or new profile set as default. Running the displayed command sets the `AWS_PROFILE` environment variable in the current terminal only, enabling per-terminal profile isolation.
|
|
113
|
-
|
|
114
|
-
### Step 4b: More Options
|
|
115
|
-
|
|
116
|
-
Selecting "More options" opens a submenu:
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
? Options:
|
|
120
|
-
Refresh default profile sso-dev # Only shown when expired
|
|
121
|
-
Create profile
|
|
122
|
-
Delete profiles
|
|
123
|
-
Abort
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Create Profile Flow
|
|
127
|
-
|
|
128
|
-
### Step 1: Profile Name
|
|
129
|
-
|
|
130
|
-
```
|
|
131
|
-
? Enter a profile name (alphanumerical lowercase and '-' characters only):
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**Validation rules:**
|
|
135
|
-
- Cannot be empty.
|
|
136
|
-
- Only lowercase letters, numbers, dashes (`-`), and underscores (`_`).
|
|
137
|
-
- Minimum 2 characters.
|
|
138
|
-
- Cannot duplicate an existing profile name.
|
|
139
|
-
|
|
140
|
-
Invalid input produces a red error and re-prompts.
|
|
141
|
-
|
|
142
|
-
### Step 2: Profile Type
|
|
143
|
-
|
|
144
|
-
```
|
|
145
|
-
? Choose an AWS profile type:
|
|
146
|
-
standard
|
|
147
|
-
sso
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Step 3a: Standard Profile
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
? Enter the profile's access key: AKIA...
|
|
154
|
-
? Enter the profile's access secret key: wJal...
|
|
155
|
-
? Select a region: (type to search)
|
|
156
|
-
us-east-2 - US East (Ohio)
|
|
157
|
-
us-east-1 - US East (N. Virginia)
|
|
158
|
-
us-west-1 - US West (N. California)
|
|
159
|
-
...
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
The region picker supports autocomplete - type to filter the list of 24 regions.
|
|
163
|
-
|
|
164
|
-
### Step 3b: SSO Profile
|
|
165
|
-
|
|
166
|
-
Selecting "sso" first displays an SSO Setup Guide with guidance on the prompts you're about to see:
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
┌─────────────────────────────────────────────────────────────────────┐
|
|
170
|
-
│ SSO Profile Setup Guide │
|
|
171
|
-
├─────────────────────────────────────────────────────────────────────┤
|
|
172
|
-
│ │
|
|
173
|
-
│ You're about to run 'aws configure sso'. Here's what to expect: │
|
|
174
|
-
│ │
|
|
175
|
-
│ 1. SSO session name │
|
|
176
|
-
│ Provide a name (e.g., "my-company-sso"). │
|
|
177
|
-
│ This enables token reuse across profiles and automatic refresh. │
|
|
178
|
-
│ Skipping this uses the legacy format (no auto-refresh). │
|
|
179
|
-
│ │
|
|
180
|
-
│ 2. SSO start URL │
|
|
181
|
-
│ Your AWS SSO portal URL (e.g., https://my-co.awsapps.com/start) │
|
|
182
|
-
│ Ask your AWS administrator if you don't have it. │
|
|
183
|
-
│ │
|
|
184
|
-
│ 3. SSO region │
|
|
185
|
-
│ The region where your SSO instance is configured. │
|
|
186
|
-
│ WARNING: This is NOT your deployment region. │
|
|
187
|
-
│ Using the wrong region causes "invalid_grant" errors. │
|
|
188
|
-
│ │
|
|
189
|
-
│ Docs: https://docs.aws.amazon.com/cli/latest/userguide/ │
|
|
190
|
-
│ cli-configure-sso.html │
|
|
191
|
-
│ │
|
|
192
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
Then it spawns the interactive `aws configure sso` command, which takes over the terminal:
|
|
196
|
-
|
|
197
|
-
```
|
|
198
|
-
SSO session name (Recommended): my-session
|
|
199
|
-
SSO start URL [None]: https://my-company.awsapps.com/start
|
|
200
|
-
SSO region [None]: us-east-1
|
|
201
|
-
SSO registration scopes [sso:account:access]:
|
|
202
|
-
...
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
This is the standard AWS CLI SSO setup flow. The user completes it directly. If the `aws configure sso` command fails (non-zero exit code), the error is reported and the profile is not marked as created.
|
|
206
|
-
|
|
207
|
-
### Step 4: Set as Default
|
|
208
|
-
|
|
209
|
-
After creation, you're asked:
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
? Do you wish to set this new profile as the default? (Y/n)
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
If yes, the profile is immediately set as the `default` (triggering SSO login if needed). If the profile is not found in `~/.aws/config` (e.g., because the creation partially failed), a clear error message is shown instead of crashing.
|
|
216
|
-
|
|
217
|
-
## Delete Profiles Flow
|
|
218
|
-
|
|
219
|
-
### Step 1: Select Profiles
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
? Select the profiles you which to delete:
|
|
223
|
-
◯ 1. sso-dev (SSO [role:Admin - account:123456789012])
|
|
224
|
-
◯ 2. sso-prod (SSO [role:ReadOnly - account:987654321098])
|
|
225
|
-
◯ 3. my-standard-profile
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
This is a checkbox selection - you can select multiple profiles.
|
|
229
|
-
|
|
230
|
-
### Step 2: Confirmation
|
|
231
|
-
|
|
232
|
-
```
|
|
233
|
-
? Are you sure you want to delete those 2 profiles? (Y/n)
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Step 3: Validation
|
|
237
|
-
|
|
238
|
-
If you try to delete the current default profile:
|
|
239
|
-
|
|
240
|
-
```
|
|
241
|
-
ERROR - Fail to delete profiles. Profile sso-dev is the current default.
|
|
242
|
-
Set another profile as the default, then try deleting again.
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
You must switch to a different profile first.
|
|
246
|
-
|
|
247
|
-
### Step 4: Success
|
|
248
|
-
|
|
249
|
-
```
|
|
250
|
-
AWS profiles successfully deleted. # Green
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## Refresh Default Profile
|
|
254
|
-
|
|
255
|
-
This option only appears in the "More options" submenu when the current default profile is expired.
|
|
256
|
-
|
|
257
|
-
Selecting it:
|
|
258
|
-
1. Looks up the current default profile in the profile list.
|
|
259
|
-
2. Retrieves fresh credentials (SSO login if needed).
|
|
260
|
-
3. Updates the `[default]` section.
|
|
261
|
-
|
|
262
|
-
**Linux / macOS:**
|
|
263
|
-
```
|
|
264
|
-
AWS profile sso-dev successfully refreshed. # Green
|
|
265
|
-
|
|
266
|
-
┌─────────────────────────────────────────────────────────┐
|
|
267
|
-
│ To lock this profile to this terminal session, run: │ # Cyan
|
|
268
|
-
│ │
|
|
269
|
-
│ export AWS_PROFILE=sso-dev │ # Cyan + Bold
|
|
270
|
-
│ │
|
|
271
|
-
│ This prevents other terminals from affecting this one. │
|
|
272
|
-
└─────────────────────────────────────────────────────────┘
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
On Windows, the hint shows PowerShell and CMD equivalents instead (see [Step 4a](#step-4a-select-a-profile)).
|
|
276
|
-
|
|
277
|
-
## Visual Indicators
|
|
278
|
-
|
|
279
|
-
| Color | Meaning |
|
|
280
|
-
|-------|---------|
|
|
281
|
-
| **Green** | Success messages |
|
|
282
|
-
| **Red** | Error messages |
|
|
283
|
-
| **Cyan** | Informational (current profile, time remaining) |
|
|
284
|
-
| **Yellow** | Warnings (expired, expiring soon) |
|
|
285
|
-
| **Bold** | Profile names in messages |
|
|
286
|
-
| **Cyan + Bold** | Profile isolation command hint (`export AWS_PROFILE=...` on Unix, PowerShell/CMD equivalents on Windows) |
|
|
287
|
-
|
|
288
|
-
## Error Display
|
|
289
|
-
|
|
290
|
-
Errors are displayed in red with contextual messages:
|
|
291
|
-
|
|
292
|
-
```
|
|
293
|
-
ERROR - Fail to get credentials for profile sso-dev
|
|
294
|
-
Fail to refresh the SSO session for AWS profile sso-dev
|
|
295
|
-
Timeout - Time to wait for refreshing the SSO session exceeded 300000ms.
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
When the AWS CLI is missing, a helpful suggestion is appended:
|
|
299
|
-
|
|
300
|
-
```
|
|
301
|
-
ERROR - Command aws not found
|
|
302
|
-
|
|
303
|
-
To fix this issue, try installing the aws CLI
|
|
304
|
-
```
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
# Configuration Files
|
|
2
|
-
|
|
3
|
-
This document describes the exact format of all AWS configuration files that `switch-profile` reads and writes.
|
|
4
|
-
|
|
5
|
-
## `~/.aws/config`
|
|
6
|
-
|
|
7
|
-
The AWS CLI configuration file. Stores profile settings including region, output format, and SSO metadata.
|
|
8
|
-
|
|
9
|
-
### Format
|
|
10
|
-
|
|
11
|
-
Standard INI-style format. The default profile uses `[default]`, all other profiles use `[profile name]`.
|
|
12
|
-
|
|
13
|
-
### Example
|
|
14
|
-
|
|
15
|
-
```ini
|
|
16
|
-
[default]
|
|
17
|
-
region = us-east-1
|
|
18
|
-
output = json
|
|
19
|
-
|
|
20
|
-
[profile my-standard]
|
|
21
|
-
region = ap-southeast-2
|
|
22
|
-
output = json
|
|
23
|
-
|
|
24
|
-
[profile sso-dev]
|
|
25
|
-
sso_start_url = https://my-company.awsapps.com/start
|
|
26
|
-
sso_region = us-east-1
|
|
27
|
-
sso_account_id = 123456789012
|
|
28
|
-
sso_role_name = CloudlessAdmin
|
|
29
|
-
region = us-east-1
|
|
30
|
-
output = json
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Fields
|
|
34
|
-
|
|
35
|
-
**Standard profile fields:**
|
|
36
|
-
|
|
37
|
-
| Field | Description | Example |
|
|
38
|
-
|-------|-------------|---------|
|
|
39
|
-
| `region` | AWS region for API calls | `us-east-1` |
|
|
40
|
-
| `output` | CLI output format | `json` |
|
|
41
|
-
|
|
42
|
-
**SSO profile additional fields:**
|
|
43
|
-
|
|
44
|
-
| Field | Description | Example |
|
|
45
|
-
|-------|-------------|---------|
|
|
46
|
-
| `sso_start_url` | SSO portal URL | `https://my-company.awsapps.com/start` |
|
|
47
|
-
| `sso_region` | Region where SSO is configured | `us-east-1` |
|
|
48
|
-
| `sso_account_id` | AWS account ID (12 digits) | `123456789012` |
|
|
49
|
-
| `sso_role_name` | IAM role name in the account | `CloudlessAdmin` |
|
|
50
|
-
|
|
51
|
-
### How `switch-profile` Modifies This File
|
|
52
|
-
|
|
53
|
-
When setting a profile as default, only the `[default]` section is updated (region and output). Other profile sections are preserved unchanged.
|
|
54
|
-
|
|
55
|
-
When creating a standard profile, a new `[profile name]` section is appended. When creating an SSO profile, the `aws configure sso` command writes the section.
|
|
56
|
-
|
|
57
|
-
When deleting a profile, the `[profile name]` section and its contents (up to the next `[` bracket) are removed via regex.
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## `~/.aws/credentials`
|
|
62
|
-
|
|
63
|
-
Stores AWS access credentials. All profiles use `[name]` syntax (no `profile` prefix).
|
|
64
|
-
|
|
65
|
-
### Example
|
|
66
|
-
|
|
67
|
-
```ini
|
|
68
|
-
[default]
|
|
69
|
-
aws_access_key_id = ASIAZOCWXABCD123456
|
|
70
|
-
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
|
71
|
-
aws_session_token = AQoDYXdzEJr...
|
|
72
|
-
expiry_date = 2021-07-17T11:33:12.000Z
|
|
73
|
-
profile = sso-dev
|
|
74
|
-
|
|
75
|
-
[my-standard]
|
|
76
|
-
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
|
|
77
|
-
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Standard AWS Fields
|
|
81
|
-
|
|
82
|
-
| Field | Description | Present For |
|
|
83
|
-
|-------|-------------|-------------|
|
|
84
|
-
| `aws_access_key_id` | AWS access key | All profiles |
|
|
85
|
-
| `aws_secret_access_key` | AWS secret key | All profiles |
|
|
86
|
-
| `aws_session_token` | Temporary session token | SSO profiles only |
|
|
87
|
-
|
|
88
|
-
### Custom Fields (added by `switch-profile`)
|
|
89
|
-
|
|
90
|
-
These fields are written into the `[default]` section only:
|
|
91
|
-
|
|
92
|
-
| Field | Description | Purpose |
|
|
93
|
-
|-------|-------------|---------|
|
|
94
|
-
| `profile` | Name of the profile these credentials belong to | Track which profile is currently active |
|
|
95
|
-
| `expiry_date` | ISO 8601 timestamp of when credentials expire | Display expiry status, detect expired profiles |
|
|
96
|
-
|
|
97
|
-
These are non-standard fields. The AWS CLI ignores them, but `switch-profile` reads them back to show profile status.
|
|
98
|
-
|
|
99
|
-
### How `switch-profile` Modifies This File
|
|
100
|
-
|
|
101
|
-
When setting a profile as default, the `[default]` section is replaced with the selected profile's credentials plus the custom `profile` and `expiry_date` fields.
|
|
102
|
-
|
|
103
|
-
When creating a standard profile, a new `[name]` section with access key and secret key is appended.
|
|
104
|
-
|
|
105
|
-
When deleting a profile, the `[name]` section and its contents are removed via regex.
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## `~/.aws/sso/cache/` (Read-only)
|
|
110
|
-
|
|
111
|
-
`switch-profile` reads but does not write to this directory. It is managed entirely by the AWS CLI.
|
|
112
|
-
|
|
113
|
-
### Purpose
|
|
114
|
-
|
|
115
|
-
Stores SSO session tokens obtained through the `aws sso login` flow.
|
|
116
|
-
|
|
117
|
-
### File Format
|
|
118
|
-
|
|
119
|
-
Files are named with hash-based identifiers (e.g., `bdc1be3a4f0c3b5e8c0e4d6a1b2c3d4e.json`).
|
|
120
|
-
|
|
121
|
-
```json
|
|
122
|
-
{
|
|
123
|
-
"startUrl": "https://my-company.awsapps.com/start",
|
|
124
|
-
"region": "us-east-1",
|
|
125
|
-
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
126
|
-
"expiresAt": "2021-07-17T11:33:12Z"
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Fields
|
|
131
|
-
|
|
132
|
-
| Field | Description |
|
|
133
|
-
|-------|-------------|
|
|
134
|
-
| `startUrl` | The SSO portal URL this session belongs to |
|
|
135
|
-
| `region` | The SSO region |
|
|
136
|
-
| `accessToken` | JWT token for the SSO session |
|
|
137
|
-
| `expiresAt` | ISO 8601 expiry timestamp |
|
|
138
|
-
|
|
139
|
-
### How `switch-profile` Uses It
|
|
140
|
-
|
|
141
|
-
The tool searches all `*.json` files in this directory when it needs to verify or find an SSO session. It matches by comparing the `startUrl` host with the profile's `sso_start_url` host. A session is considered valid if it expires more than 2 minutes from now.
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## `~/.aws/cli/cache/` (Read-only)
|
|
146
|
-
|
|
147
|
-
`switch-profile` reads but does not write to this directory. It is managed entirely by the AWS CLI.
|
|
148
|
-
|
|
149
|
-
### Purpose
|
|
150
|
-
|
|
151
|
-
Stores temporary AWS credentials (access key, secret key, session token) obtained through SSO authentication.
|
|
152
|
-
|
|
153
|
-
### File Format
|
|
154
|
-
|
|
155
|
-
Files are named with hash-based identifiers.
|
|
156
|
-
|
|
157
|
-
```json
|
|
158
|
-
{
|
|
159
|
-
"ProviderType": "sso",
|
|
160
|
-
"Credentials": {
|
|
161
|
-
"AccessKeyId": "ASIAZOCWXABCD123456",
|
|
162
|
-
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
|
163
|
-
"SessionToken": "AQoDYXdzEJr...",
|
|
164
|
-
"Expiration": "2021-07-17T11:33:12Z"
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Fields
|
|
170
|
-
|
|
171
|
-
| Field | Description |
|
|
172
|
-
|-------|-------------|
|
|
173
|
-
| `ProviderType` | Credential source type (`"sso"` for SSO) |
|
|
174
|
-
| `Credentials.AccessKeyId` | AWS access key ID |
|
|
175
|
-
| `Credentials.SecretAccessKey` | AWS secret access key |
|
|
176
|
-
| `Credentials.SessionToken` | Temporary session token |
|
|
177
|
-
| `Credentials.Expiration` | ISO 8601 expiry timestamp |
|
|
178
|
-
|
|
179
|
-
### How `switch-profile` Uses It
|
|
180
|
-
|
|
181
|
-
After running `aws configure list --profile <name>` (which populates this cache), the tool searches for a file where:
|
|
182
|
-
|
|
183
|
-
1. `ProviderType` is `"sso"`.
|
|
184
|
-
2. The last 4 characters of `AccessKeyId` match what `aws configure list` reported.
|
|
185
|
-
3. The last 4 characters of `SecretAccessKey` match what `aws configure list` reported.
|
|
186
|
-
4. `Expiration` is at least 2 minutes in the future.
|
|
187
|
-
|
|
188
|
-
This matching-by-suffix approach is necessary because `aws configure list` only shows masked keys (e.g., `****3456`), not the full values.
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
## Default File Contents
|
|
193
|
-
|
|
194
|
-
When `switch-profile` creates a standard profile and the AWS config files don't exist yet, it initializes them with these defaults:
|
|
195
|
-
|
|
196
|
-
**`~/.aws/config`:**
|
|
197
|
-
```ini
|
|
198
|
-
[default]
|
|
199
|
-
region = ap-southeast-1
|
|
200
|
-
output = json
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
**`~/.aws/credentials`:**
|
|
205
|
-
```ini
|
|
206
|
-
[default]
|
|
207
|
-
aws_access_key_id = 1234_DUMMY
|
|
208
|
-
aws_secret_access_key = 4567_DUMMY
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
These are dummy values that serve as placeholders until a real profile is set as default.
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## INI Parsing Approach
|
|
217
|
-
|
|
218
|
-
`switch-profile` does not use a dedicated INI parser. Instead, it uses regex-based string operations:
|
|
219
|
-
|
|
220
|
-
**Reading a section:**
|
|
221
|
-
```javascript
|
|
222
|
-
// Extract [default] section content (everything until the next [ or end of file)
|
|
223
|
-
const section = fileContent.match(/\[default\]((.|\n|\r)*?)(\[|$)/)[0]
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**Extracting a parameter:**
|
|
227
|
-
```javascript
|
|
228
|
-
// Match " paramName = value" with flexible whitespace
|
|
229
|
-
const regexp = new RegExp(`\\s*${paramName}\\s*=\\s*`)
|
|
230
|
-
const value = params.filter(p => regexp.test(p)).map(p => p.replace(regexp,'').trim())[0]
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**Replacing a section:**
|
|
234
|
-
```javascript
|
|
235
|
-
// Replace the [default] section while preserving the opening bracket of the next section
|
|
236
|
-
const lastChar = defaultSection.slice(-1) // Either '[' or end-of-string
|
|
237
|
-
updatedContent = fileContent.replace(defaultSection, newSection + lastChar)
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
This approach works for the tool's use case but depends on well-formed config files. It preserves all content outside the targeted section unchanged.
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# Development Guide
|
|
2
|
-
|
|
3
|
-
This document covers how to set up, develop, test, lint, and release `switch-profile`.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
```shell
|
|
8
|
-
git clone https://github.com/nicolasdao/switch-profile.git
|
|
9
|
-
cd switch-profile
|
|
10
|
-
npm install
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Running Locally
|
|
14
|
-
|
|
15
|
-
**Development mode:**
|
|
16
|
-
```shell
|
|
17
|
-
npm run dev
|
|
18
|
-
# Runs: TZ=UTC NODE_ENV=dev node index.js
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**Production mode:**
|
|
22
|
-
```shell
|
|
23
|
-
npm start
|
|
24
|
-
# Runs: TZ=UTC NODE_ENV=production node index.js
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Direct execution:**
|
|
28
|
-
```shell
|
|
29
|
-
node index.js
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Both modes set `TZ=UTC` to ensure consistent timestamp handling.
|
|
33
|
-
|
|
34
|
-
## Linting
|
|
35
|
-
|
|
36
|
-
```shell
|
|
37
|
-
npm run lint
|
|
38
|
-
# Runs: eslint index.js src/ test/ --fix
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
The ESLint configuration (`.eslintrc.json`) enforces:
|
|
42
|
-
|
|
43
|
-
| Rule | Setting |
|
|
44
|
-
|------|---------|
|
|
45
|
-
| Indentation | Tabs |
|
|
46
|
-
| Quotes | Single |
|
|
47
|
-
| Semicolons | None (never) |
|
|
48
|
-
| Line endings | Unix (`\n`) |
|
|
49
|
-
| Environment | ES6, Node.js (CommonJS) |
|
|
50
|
-
| Console | Allowed |
|
|
51
|
-
|
|
52
|
-
The `--fix` flag auto-fixes style issues when possible.
|
|
53
|
-
|
|
54
|
-
## Testing
|
|
55
|
-
|
|
56
|
-
```shell
|
|
57
|
-
npm test
|
|
58
|
-
# Runs: mocha --exit
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Tests are located in `test/index.js` and use [Mocha](https://mochajs.org/) as the test runner and [Chai](https://www.chaijs.com/) for assertions.
|
|
62
|
-
|
|
63
|
-
**Current state:** The test suite contains a single placeholder test. There are no functional tests for the AWS operations, profile management, or file I/O.
|
|
64
|
-
|
|
65
|
-
**Test utilities (from comments in test file):**
|
|
66
|
-
- Skip a test: Use `xit` instead of `it`, or `describe.skip` instead of `describe`.
|
|
67
|
-
- Run only one test: Use `it.only` instead of `it`.
|
|
68
|
-
|
|
69
|
-
## Dependencies
|
|
70
|
-
|
|
71
|
-
### Production Dependencies
|
|
72
|
-
|
|
73
|
-
| Package | Purpose |
|
|
74
|
-
|---------|---------|
|
|
75
|
-
| `commander` | CLI argument parsing and command registration |
|
|
76
|
-
| `inquirer` | Interactive prompts (list, input, confirm, checkbox) |
|
|
77
|
-
| `inquirer-autocomplete-prompt` | Autocomplete support for region selection |
|
|
78
|
-
| `colors` | Colored terminal output |
|
|
79
|
-
| `puffy` | Error handling (`catchErrors`, `wrapErrors`, `delay`) |
|
|
80
|
-
| `core-async` | Generator-based async flow (co-routines) |
|
|
81
|
-
| `fast-glob` | File pattern matching for cache directory scanning |
|
|
82
|
-
| `rimraf` | Cross-platform recursive directory deletion |
|
|
83
|
-
| `mime-types` | MIME type detection (used by fileHelper, not core functionality) |
|
|
84
|
-
| `archiver` | ZIP creation (imported by fileHelper, unused in current flows) |
|
|
85
|
-
| `tar-stream` | TAR streaming (imported by fileHelper, unused in current flows) |
|
|
86
|
-
| `convert-stream` | Stream conversion (imported by fileHelper, unused in current flows) |
|
|
87
|
-
|
|
88
|
-
### Dev Dependencies
|
|
89
|
-
|
|
90
|
-
| Package | Purpose |
|
|
91
|
-
|---------|---------|
|
|
92
|
-
| `mocha` | Test runner |
|
|
93
|
-
| `chai` | Assertion library |
|
|
94
|
-
| `eslint` | Code linting |
|
|
95
|
-
| `standard-version` | Automated versioning and changelog generation |
|
|
96
|
-
|
|
97
|
-
### Unused Dependencies
|
|
98
|
-
|
|
99
|
-
The `fileHelper.js` module is a shared utility library that imports several packages not used by `switch-profile`'s core functionality: `archiver`, `tar-stream`, `convert-stream`, and partially `mime-types`. These are present because `fileHelper.js` provides general-purpose file operations that may be used in other projects sharing this codebase.
|
|
100
|
-
|
|
101
|
-
## Release Process
|
|
102
|
-
|
|
103
|
-
### Step 1: Version Bump and Changelog
|
|
104
|
-
|
|
105
|
-
```shell
|
|
106
|
-
npm run rls -- minor # For new features (0.1.x → 0.2.0)
|
|
107
|
-
npm run rls -- patch # For bug fixes (0.1.2 → 0.1.3)
|
|
108
|
-
npm run rls -- major # For breaking changes (0.x.x → 1.0.0)
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
This runs `standard-version --release-as <type>`, which:
|
|
112
|
-
1. Bumps the version in `package.json`.
|
|
113
|
-
2. Updates `CHANGELOG.md` based on conventional commit messages.
|
|
114
|
-
3. Creates a git commit with the version bump.
|
|
115
|
-
4. Creates an annotated git tag (e.g., `v0.1.3`).
|
|
116
|
-
|
|
117
|
-
### Step 2: Publish
|
|
118
|
-
|
|
119
|
-
```shell
|
|
120
|
-
npm run push
|
|
121
|
-
# Runs: git push --follow-tags origin master && npm publish --access=public
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
This:
|
|
125
|
-
1. Pushes the commit and tag to the `master` branch on GitHub.
|
|
126
|
-
2. Publishes the package to the npm registry with public access.
|
|
127
|
-
|
|
128
|
-
### Version Check
|
|
129
|
-
|
|
130
|
-
```shell
|
|
131
|
-
npm run v
|
|
132
|
-
# Prints the current version from package.json
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## npm Package Configuration
|
|
136
|
-
|
|
137
|
-
| Field | Value |
|
|
138
|
-
|-------|-------|
|
|
139
|
-
| Package name | `switch-profile` |
|
|
140
|
-
| Entry point | `index.js` |
|
|
141
|
-
| Binary | `index.js` (registered via `"bin"` field) |
|
|
142
|
-
| Access | Public |
|
|
143
|
-
| License | BSD-3-Clause |
|
|
144
|
-
| Files excluded from npm | `test/` (via `.npmignore`) |
|
|
145
|
-
|
|
146
|
-
## Conventional Commits
|
|
147
|
-
|
|
148
|
-
The project uses [standard-version](https://github.com/conventional-commits/standard-version) for automated changelog generation. Commit messages should follow the [Conventional Commits](https://www.conventionalcommits.org/) format:
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
feat: Add support for profile refresh
|
|
152
|
-
fix: Multiple SSO profiles are not supported
|
|
153
|
-
chore(release): 0.1.2
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Prefixes:
|
|
157
|
-
- `feat:` - New features (bumps minor version)
|
|
158
|
-
- `fix:` - Bug fixes (bumps patch version)
|
|
159
|
-
- `chore:` - Maintenance tasks (no version bump unless specified)
|
|
160
|
-
|
|
161
|
-
## Project Layout Conventions
|
|
162
|
-
|
|
163
|
-
- **No semicolons** in JavaScript files.
|
|
164
|
-
- **Tab indentation** throughout.
|
|
165
|
-
- **Single quotes** for strings.
|
|
166
|
-
- **CommonJS** module system (`require`/`module.exports`), not ES modules.
|
|
167
|
-
- **Error tuple pattern**: Async functions return `[errors, result]` via the `catchErrors` wrapper from `puffy`.
|
|
168
|
-
- **Shebang**: `index.js` starts with `#!/usr/bin/env node` for direct CLI execution.
|