switch-profile 0.2.3 → 1.1.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [1.1.0](https://github.com/nicolasdao/switch-profile/compare/v1.0.0...v1.1.0) (2026-03-21)
6
+
7
+
8
+ ### Features
9
+
10
+ * add Windows compatibility for profile switching, config parsing, and shell hints ([16ce46b](https://github.com/nicolasdao/switch-profile/commit/16ce46bc5cb1d92fc6d882358eaabc718a157f22))
11
+
12
+ ## [1.0.0](https://github.com/nicolasdao/switch-profile/compare/v0.2.3...v1.0.0) (2026-03-21)
13
+
14
+
15
+ ### Features
16
+
17
+ * Display export AWS_PROFILE hint after profile switch for per-terminal isolation ([7dd09c8](https://github.com/nicolasdao/switch-profile/commit/7dd09c882708fcafd66fefc6139cd97a13d9b2fb))
18
+
5
19
  ### [0.2.3](https://github.com/nicolasdao/switch-profile/compare/v0.2.2...v0.2.3) (2026-02-11)
6
20
 
7
21
 
package/README.md CHANGED
@@ -52,6 +52,7 @@ This will:
52
52
  1. Show your current default profile with its expiry status.
53
53
  2. List all available profiles.
54
54
  3. Let you pick one to set as the new `default`.
55
+ 4. Display an `export AWS_PROFILE=<name>` command you can run to lock that profile to your current terminal session.
55
56
 
56
57
  For SSO profiles, if the session has expired, it automatically opens your browser for re-authentication.
57
58
 
@@ -97,6 +98,11 @@ When you select a profile, `switch-profile`:
97
98
  1. Retrieves the credentials for that profile (from cache or via SSO login).
98
99
  2. Writes them into the `[default]` section of both files.
99
100
  3. Records the profile name and expiry date for status display.
101
+ 4. Shows an `export AWS_PROFILE=<name>` command to optionally lock the profile to your terminal session.
102
+
103
+ ### Per-terminal profile isolation
104
+
105
+ By default, switching profiles updates the global `[default]` section, which affects all terminals. If you need different AWS profiles in different terminals simultaneously, copy and run the command shown after each switch (`export AWS_PROFILE=<name>` on Linux/macOS, or the PowerShell/CMD equivalent on Windows). This sets an environment variable scoped to that terminal only, so other terminals remain unaffected.
100
106
 
101
107
  For SSO profiles specifically, it leverages two additional AWS CLI cache directories:
102
108
  - `~/.aws/sso/cache/` - SSO session tokens (long-lived, ~24 hours)
@@ -113,6 +119,7 @@ For deeper technical details, see the docs below:
113
119
  | [CLI Interface](docs/cli-interface.md) | Detailed walkthrough of every menu, prompt, and user flow |
114
120
  | [Configuration Files](docs/configuration-files.md) | Exact formats of all AWS and internal configuration files |
115
121
  | [Development Guide](docs/development-guide.md) | How to set up, develop, test, lint, and release |
122
+ | [Gotchas](docs/gotchas.md) | Critical pitfalls — global profile switching, per-terminal isolation limits, and LLM agent constraints |
116
123
 
117
124
  ## Troubleshooting
118
125
 
@@ -37,7 +37,8 @@ The main executable file (with `#!/usr/bin/env node` shebang). Registered as the
37
37
  | Function | Purpose |
38
38
  |----------|---------|
39
39
  | `switchCmd()` | Main command handler. Checks AWS CLI, shows current profile status, lists profiles, renders the selection menu. |
40
- | `setProfileToDefault(name, list, msg)` | Gets credentials for a profile, writes them as the `[default]` profile. Shows a clear error if the profile is not found in the list. |
40
+ | `setProfileToDefault(name, list, msg)` | Gets credentials for a profile, writes them as the `[default]` profile. Shows a clear error if the profile is not found in the list. Displays the `export AWS_PROFILE` hint on success. |
41
+ | `printExportHint(profileName)` | Displays a cyan box with the profile isolation command. On Linux/macOS shows `export AWS_PROFILE=<name>`. On Windows shows both PowerShell (`$env:AWS_PROFILE`) and CMD (`set AWS_PROFILE`) variants. Box width adjusts dynamically. |
41
42
  | `createNewProfile(profiles, makeItDefault)` | Walks the user through creating a standard or SSO profile. Displays an SSO Setup Guide before SSO creation and checks for errors before reporting success. |
42
43
  | `chooseProfileName(denyList)` | Validates profile name input (lowercase alphanumeric, dashes, underscores, min 2 chars, no duplicates). |
43
44
  | `chooseRegions()` | Autocomplete region picker from the 24 supported AWS regions. |
@@ -56,6 +57,8 @@ The core module. Handles all interactions with AWS configuration files and the A
56
57
  - Creating, deleting, and listing profiles.
57
58
  - Refreshing expired SSO sessions (including browser redirect).
58
59
 
60
+ **Windows compatibility:** Uses `IS_WINDOWS` (`process.platform === 'win32'`) to select platform-appropriate line separator for parsing (`LINE_SEP`: regex `/\r?\n/` on Windows, `os.EOL` otherwise), newline character for writing (`NL`: `'\n'` on Windows, `os.EOL` otherwise), and `shell: true` for `spawn` on Windows (required because `aws` is a `.cmd` batch file).
61
+
59
62
  See [AWS Profile Management](aws-profile-management.md) for a detailed breakdown of every function.
60
63
 
61
64
  ### `src/aws/regions.js` - Region Definitions
@@ -181,5 +184,16 @@ User runs: npx switch-profile
181
184
  │ section to: │
182
185
  │ - ~/.aws/credentials│
183
186
  │ - ~/.aws/config │
187
+ └──────────────────────┘
188
+ │
189
+ ▼
190
+ ┌──────────────────────┐
191
+ │ printExportHint │
192
+ │ │
193
+ │ Shows: │
194
+ │ export AWS_PROFILE= │
195
+ │ <name> │
196
+ │ for per-terminal │
197
+ │ isolation │
184
198
  └──────────────────────┘
185
199
  ```
@@ -202,7 +202,7 @@ If the config or credentials files don't exist, they are created with a default
202
202
 
203
203
  Creates an SSO profile by spawning the interactive `aws configure sso --profile <name>` command. This hands control to the AWS CLI, which walks the user through the SSO setup (URL, region, account, role).
204
204
 
205
- Uses `spawn` with `stdio: 'inherit'` so the user interacts directly with the AWS CLI process. Checks the exit code of the spawned process and throws an error if it is non-zero, indicating the SSO setup failed.
205
+ Uses `spawn` with `stdio: 'inherit'` so the user interacts directly with the AWS CLI process. On Windows, `shell: true` is also passed because `aws` is typically a `.cmd` batch file that requires shell resolution. Checks the exit code of the spawned process and throws an error if it is non-zero, indicating the SSO setup failed.
206
206
 
207
207
  #### `deleteProfiles(profiles)`
208
208
 
@@ -21,7 +21,7 @@ Before anything else, the tool verifies AWS CLI v2+ is installed. If not found,
21
21
 
22
22
  - **macOS:** `brew install awscli && brew link --overwrite awscli`
23
23
  - **Linux:** curl + unzip instructions for the AWS CLI v2 installer
24
- - **Windows:** Generic "not installed" message
24
+ - **Windows:** "Not installed" message with a link to the AWS CLI MSI installer download page
25
25
 
26
26
  ### Step 2: Default Profile Status
27
27
 
@@ -82,10 +82,35 @@ Selecting a profile from the list sets it as the `default`. For SSO profiles, th
82
82
 
83
83
  On success:
84
84
 
85
+ **Linux / macOS:**
85
86
  ```
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
+ └─────────────────────────────────────────────────────────┘
87
96
  ```
88
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
+
89
114
  ### Step 4b: More Options
90
115
 
91
116
  Selecting "More options" opens a submenu:
@@ -234,10 +259,21 @@ Selecting it:
234
259
  2. Retrieves fresh credentials (SSO login if needed).
235
260
  3. Updates the `[default]` section.
236
261
 
262
+ **Linux / macOS:**
237
263
  ```
238
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
+ └─────────────────────────────────────────────────────────┘
239
273
  ```
240
274
 
275
+ On Windows, the hint shows PowerShell and CMD equivalents instead (see [Step 4a](#step-4a-select-a-profile)).
276
+
241
277
  ## Visual Indicators
242
278
 
243
279
  | Color | Meaning |
@@ -247,6 +283,7 @@ AWS profile sso-dev successfully refreshed. # Green
247
283
  | **Cyan** | Informational (current profile, time remaining) |
248
284
  | **Yellow** | Warnings (expired, expiring soon) |
249
285
  | **Bold** | Profile names in messages |
286
+ | **Cyan + Bold** | Profile isolation command hint (`export AWS_PROFILE=...` on Unix, PowerShell/CMD equivalents on Windows) |
250
287
 
251
288
  ## Error Display
252
289
 
@@ -0,0 +1,82 @@
1
+ # Gotchas
2
+
3
+ Critical pitfalls and edge cases that are not immediately obvious when using `switch-profile`.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Profile switching is global by default](#profile-switching-is-global-by-default)
8
+ - [The problem](#the-problem)
9
+ - [The solution: `export AWS_PROFILE`](#the-solution-export-aws_profile)
10
+ - [The limitation: you must copy-paste it yourself](#the-limitation-you-must-copy-paste-it-yourself)
11
+ - [LLM agents and automation](#llm-agents-and-automation)
12
+
13
+ ## Profile switching is global by default
14
+
15
+ ### The problem
16
+
17
+ When you run `npx switch-profile` and select a profile, the tool writes credentials into the `[default]` section of `~/.aws/credentials` and `~/.aws/config`. These are **global files** shared by every terminal, every tool, and every process on the machine.
18
+
19
+ This means:
20
+ - If Terminal A switches to `dev`, Terminal B is now also on `dev`.
21
+ - If Terminal B then switches to `prod`, Terminal A is silently moved to `prod` too.
22
+ - Any concurrent process relying on `[default]` (Terraform, CDK, scripts) is affected immediately.
23
+
24
+ ### The solution: `export AWS_PROFILE`
25
+
26
+ After every successful switch, `switch-profile` displays a box like:
27
+
28
+ ```
29
+ ┌─────────────────────────────────────────────────────────┐
30
+ │ To lock this profile to this terminal session, run: │
31
+ │ │
32
+ │ export AWS_PROFILE=dev │
33
+ │ │
34
+ │ This prevents other terminals from affecting this one. │
35
+ └─────────────────────────────────────────────────────────┘
36
+ ```
37
+
38
+ Running the displayed command sets an environment variable **scoped to that terminal session only**. The AWS CLI and all AWS SDKs honor `AWS_PROFILE` and will use the named profile directly — bypassing `[default]` entirely. Other terminals remain unaffected.
39
+
40
+ On **Linux / macOS**: `export AWS_PROFILE=dev`
41
+ On **Windows (PowerShell)**: `$env:AWS_PROFILE = "dev"`
42
+ On **Windows (CMD)**: `set AWS_PROFILE=dev`
43
+
44
+ ### The limitation: you must copy-paste it yourself
45
+
46
+ `switch-profile` **cannot** set the environment variable for you. This is a fundamental operating system constraint: a child process (the `npx` command) cannot modify the environment of its parent process (your terminal shell). The displayed command (`export` on Unix, `$env:` on PowerShell, `set` on CMD) must be run directly in the terminal by the user.
47
+
48
+ There is no workaround for this within the tool itself. The user must manually copy-paste and run the `export AWS_PROFILE=<name>` command shown after each switch.
49
+
50
+ ### LLM agents and automation
51
+
52
+ When an LLM agent (e.g., a Claude Code skill) uses `switch-profile` via a shell tool, the same constraint applies — but with an additional twist.
53
+
54
+ **Environment variables do not persist between shell tool invocations.** Each time an LLM agent runs a Bash command, it spawns a **new shell subprocess**. So even if the agent runs `export AWS_PROFILE=dev` in one command, that variable is gone in the next command.
55
+
56
+ **Workaround:** The agent must prefix every AWS command with the profile inline:
57
+
58
+ ```shell
59
+ AWS_PROFILE=dev aws s3 ls
60
+ AWS_PROFILE=dev terraform plan
61
+ AWS_PROFILE=prod aws sts get-caller-identity
62
+ ```
63
+
64
+ This works reliably and supports concurrent agents using different profiles, since each command carries its own profile context with no shared global state.
65
+
66
+ **What does NOT work for agents:**
67
+
68
+ ```shell
69
+ # Command 1 — sets the variable, but only in this subprocess
70
+ export AWS_PROFILE=dev
71
+
72
+ # Command 2 — this is a NEW subprocess, AWS_PROFILE is not set here
73
+ aws s3 ls # Uses [default], NOT dev
74
+ ```
75
+
76
+ **Chaining commands in a single invocation** also works but is less practical for multi-step workflows:
77
+
78
+ ```shell
79
+ export AWS_PROFILE=dev && aws s3 ls && aws sts get-caller-identity
80
+ ```
81
+
82
+ **Summary for skill/agent authors:** After running `npx switch-profile` to authenticate and ensure the SSO session is valid, extract the profile name and use `AWS_PROFILE=<name>` as an inline prefix on every subsequent AWS command.
package/index.js CHANGED
@@ -6,6 +6,7 @@
6
6
  const program = require('commander')
7
7
  const inquirer = require('inquirer')
8
8
  const { EOL } = require('os')
9
+ const IS_WINDOWS = process.platform === 'win32'
9
10
  const { listProfiles, getCredentials, getDefaultProfile, updateDefaultProfile, deleteProfiles, createProfile, regions, createSsoProfile, awsCliV2Exists } = require('./src/aws')
10
11
  const { printAWSerrors } = require('./src/core')
11
12
  require('colors')
@@ -179,7 +180,8 @@ const switchCmd = async () => {
179
180
  console.log('brew link --overwrite awscli')
180
181
  return
181
182
  } else if (process.platform == 'win32') {
182
- console.log('AWS CLI seems to not be installed.'.red)
183
+ console.log('AWS CLI seems to not be installed. Download the installer from:\n'.red)
184
+ console.log('https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html')
183
185
  return
184
186
  } else {
185
187
  console.log('AWS CLI seems to not be installed. Try installing it as follow\n'.red)
@@ -330,6 +332,35 @@ const switchCmd = async () => {
330
332
  }
331
333
  }
332
334
 
335
+ const printExportHint = (profileName) => {
336
+ const lines = IS_WINDOWS ? [
337
+ ' To lock this profile to this terminal session, run: ',
338
+ '',
339
+ ` PowerShell: $env:AWS_PROFILE = "${profileName}"`,
340
+ ` CMD: set AWS_PROFILE=${profileName}`,
341
+ '',
342
+ ' This prevents other terminals from affecting this one. '
343
+ ] : [
344
+ ' To lock this profile to this terminal session, run: ',
345
+ '',
346
+ ` export AWS_PROFILE=${profileName}`,
347
+ '',
348
+ ' This prevents other terminals from affecting this one. '
349
+ ]
350
+ const width = Math.max(...lines.map(l => l.length))
351
+ const pad = s => s + ' '.repeat(width - s.length)
352
+ console.log('')
353
+ console.log(('┌' + '─'.repeat(width) + '┐').cyan)
354
+ const boldStart = IS_WINDOWS ? 2 : 2
355
+ const boldEnd = IS_WINDOWS ? 3 : 2
356
+ for (let i = 0; i < lines.length; i++) {
357
+ const content = '│' + pad(lines[i]) + '│'
358
+ console.log(i >= boldStart && i <= boldEnd ? content.cyan.bold : content.cyan)
359
+ }
360
+ console.log(('└' + '─'.repeat(width) + '┘').cyan)
361
+ console.log('')
362
+ }
363
+
333
364
  const setProfileToDefault = async (profileName, profileList, successMsg) => {
334
365
  const profile = profileList.find(p => p.friendlyName == profileName || p.name == profileName)
335
366
 
@@ -357,6 +388,7 @@ const setProfileToDefault = async (profileName, profileList, successMsg) => {
357
388
  return printAWSerrors([new Error('Fail to update the default profile'), ...errors])
358
389
 
359
390
  console.log((successMsg || `AWS profile ${profile.name.bold} successfully set up as default.`).green)
391
+ printExportHint(profile.name)
360
392
  }
361
393
 
362
394
  // 1. Creates your first command. This example shows an 'order' command with a required argument
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switch-profile",
3
- "version": "0.2.3",
3
+ "version": "1.1.0",
4
4
  "main": "index.js",
5
5
  "bin": "index.js",
6
6
  "description": "NPX script that exposes terminal shortcut to easily switch between cloud configuration (aws, gcp).",
@@ -0,0 +1,73 @@
1
+ {
2
+ "lockVersion": 1,
3
+ "generatedAt": "2026-03-21T07:51:15.981Z",
4
+ "skills": {
5
+ "happyskillsai/happyskills": {
6
+ "version": "1.17.0",
7
+ "ref": "refs/tags/v1.17.0",
8
+ "commit": "8024d2ee1efd9f17391ebd701a6e6131eafec14777d550e23d3d3a50b5d11439",
9
+ "integrity": "sha256-24e69e779a31ade191ae2fb9dec5a90d28fd9d4afcda2851fc048dd03093c6fb",
10
+ "requested_by": [
11
+ "__root__"
12
+ ],
13
+ "dependencies": {}
14
+ },
15
+ "nicolasdao/_kit-dev-essentials": {
16
+ "version": "1.0.0",
17
+ "ref": "refs/tags/v1.0.0",
18
+ "commit": "7c793754d999f50dc44e289b6d190e5f9dc2959e132f62c84625897ced7f95f7",
19
+ "integrity": "sha256-f4fe6b211aa96bbc291c880a4a61682bf5d438a52db0b82e73f42e7126c39e45",
20
+ "requested_by": [
21
+ "__root__"
22
+ ],
23
+ "dependencies": {
24
+ "nicolasdao/git-commit": "*",
25
+ "nicolasdao/update-doc": "*",
26
+ "nicolasdao/init-doc": "*",
27
+ "nicolasdao/init-context": "*"
28
+ },
29
+ "type": "kit"
30
+ },
31
+ "nicolasdao/git-commit": {
32
+ "version": "1.0.1",
33
+ "ref": "refs/tags/v1.0.1",
34
+ "commit": "315daee8d9d3ad5e88c42ed35b8e89ccc7ff57bfc28ef0d72ad5122c8e834e19",
35
+ "integrity": "sha256-d7e5a0e9afe9f2633e4e9ad64d8248fca0ee8e20a44f54586474bbfecc79d7e7",
36
+ "requested_by": [
37
+ "nicolasdao/_kit-dev-essentials"
38
+ ],
39
+ "dependencies": {}
40
+ },
41
+ "nicolasdao/update-doc": {
42
+ "version": "1.0.4",
43
+ "ref": "refs/tags/v1.0.4",
44
+ "commit": "6394de7f8b487c16700f84d5235a3dca5746205d2abafbdfad02e59bbd924a60",
45
+ "integrity": "sha256-e60d3df49530031a5f663aed8a6999fda6b4caab4deba249ec7cfd5ec65f085c",
46
+ "requested_by": [
47
+ "nicolasdao/_kit-dev-essentials"
48
+ ],
49
+ "dependencies": {}
50
+ },
51
+ "nicolasdao/init-doc": {
52
+ "version": "0.1.1",
53
+ "ref": "refs/tags/v0.1.1",
54
+ "commit": "9603e12aa7dba8c2d6903f249a60b418f3913c94dddfde266e065d1b9bbd0171",
55
+ "integrity": "sha256-567e6e55d27b9873bf1664bd7992cc8d3b7045e4d371de136245e5193e04b680",
56
+ "requested_by": [
57
+ "nicolasdao/_kit-dev-essentials"
58
+ ],
59
+ "dependencies": {},
60
+ "type": "skill"
61
+ },
62
+ "nicolasdao/init-context": {
63
+ "version": "1.0.1",
64
+ "ref": "refs/tags/v1.0.1",
65
+ "commit": "a52d089f1c6a102feac17b99e7df72e29899952f393013bd479e3f97cc614f32",
66
+ "integrity": "sha256-417c5dc3e0b59f785fd8af166bbaa757f4bfac8343d7365708342e84d386bd01",
67
+ "requested_by": [
68
+ "nicolasdao/_kit-dev-essentials"
69
+ ],
70
+ "dependencies": {}
71
+ }
72
+ }
73
+ }
package/src/aws/index.js CHANGED
@@ -6,6 +6,9 @@ const { spawn } = require('child_process')
6
6
  const fileHelper = require('../fileHelper')
7
7
  const regions = require('./regions')
8
8
 
9
+ const IS_WINDOWS = process.platform === 'win32'
10
+ const LINE_SEP = IS_WINDOWS ? /\r?\n/ : EOL
11
+ const NL = IS_WINDOWS ? '\n' : EOL
9
12
  const SSO_GET_CREDS_TIMEOUT = 5*60*1000 // 5 minutes to complete the SSO login
10
13
  const AWS_CONFIG_FILE = join(homedir(), '.aws', 'config')
11
14
  const AWS_CREDS_FILE = join(homedir(), '.aws', 'credentials')
@@ -100,7 +103,7 @@ const listProfiles = () => catchErrors((async () => {
100
103
  return profiles.map(profile => {
101
104
  const [,rest=''] = configStr.split(profile)
102
105
  const [config=''] = rest.split('[')
103
- const params = config.split(EOL)
106
+ const params = config.split(LINE_SEP)
104
107
  const p = {
105
108
  name: profile.replace(/(^\[profile\s+|\[|\])/g, ''),
106
109
  sso_start_url: getParam(params, 'sso_start_url'),
@@ -118,7 +121,7 @@ const listProfiles = () => catchErrors((async () => {
118
121
  const ssoSessionMatch = configStr.split(ssoSessionSection)
119
122
  if (ssoSessionMatch.length > 1) {
120
123
  const [ssoSessionRest=''] = ssoSessionMatch[1].split('[')
121
- const ssoSessionParams = ssoSessionRest.split(EOL)
124
+ const ssoSessionParams = ssoSessionRest.split(LINE_SEP)
122
125
  p.sso_start_url = getParam(ssoSessionParams, 'sso_start_url')
123
126
  // If sso_region is not in profile, check the session section
124
127
  if (!p.sso_region) {
@@ -384,7 +387,7 @@ const getCredentials = (profile, ssoUrl) => catchErrors((async () => {
384
387
  throw new Error(`Profile ${profile} not found in ${AWS_CREDS_FILE}. Standard profiles must have credentials defined in this file.`)
385
388
 
386
389
  const [config=''] = rest.split('[')
387
- const params = config.split(EOL)
390
+ const params = config.split(LINE_SEP)
388
391
  const creds = {
389
392
  aws_access_key_id: getParam(params, 'aws_access_key_id'),
390
393
  aws_secret_access_key: getParam(params, 'aws_secret_access_key'),
@@ -404,16 +407,16 @@ const updateDefaultProfile = ({ profile, region, expiry_date, aws_access_key_id,
404
407
  if (credsStrErrors||configStrErrors)
405
408
  throw wrapErrors(errMsg, credsStrErrors||configStrErrors)
406
409
 
407
- const newDefaultCreds = '[default]'+EOL+
408
- `aws_access_key_id = ${aws_access_key_id}`+EOL+
409
- `aws_secret_access_key = ${aws_secret_access_key}`+EOL+
410
- (aws_session_token ? `aws_session_token = ${aws_session_token}`+EOL : '') +
411
- (expiry_date ? `expiry_date = ${expiry_date.toISOString()}`+EOL : '') +
412
- `profile = ${profile}`+EOL+EOL
410
+ const newDefaultCreds = '[default]'+NL+
411
+ `aws_access_key_id = ${aws_access_key_id}`+NL+
412
+ `aws_secret_access_key = ${aws_secret_access_key}`+NL+
413
+ (aws_session_token ? `aws_session_token = ${aws_session_token}`+NL : '') +
414
+ (expiry_date ? `expiry_date = ${expiry_date.toISOString()}`+NL : '') +
415
+ `profile = ${profile}`+NL+NL
413
416
 
414
- const newDefaultConfig = '[default]'+EOL+
415
- `region = ${region}`+EOL+
416
- 'output = json'+EOL+EOL
417
+ const newDefaultConfig = '[default]'+NL+
418
+ `region = ${region}`+NL+
419
+ 'output = json'+NL+NL
417
420
 
418
421
  const defaultCredsSection = (credsStr.match(/\[default\]((.|\n|\r)*?)(\[|$)/)||[])[0]
419
422
  const defaultConfigSection = (configStr.match(/\[default\]((.|\n|\r)*?)(\[|$)/)||[])[0]
@@ -442,7 +445,7 @@ const getDefaultProfile = () => catchErrors((async () => {
442
445
  if (errors)
443
446
  throw wrapErrors(errMsg, errors)
444
447
 
445
- const params = ((credsStr.match(/\[default\]((.|\n|\r)*?)(\[|$)/)||[])[0]||'').split(EOL)
448
+ const params = ((credsStr.match(/\[default\]((.|\n|\r)*?)(\[|$)/)||[])[0]||'').split(LINE_SEP)
446
449
  const creds = {
447
450
  aws_access_key_id: getParam(params, 'aws_access_key_id'),
448
451
  aws_secret_access_key: getParam(params, 'aws_secret_access_key'),
@@ -526,14 +529,14 @@ const createProfile = ({ name, aws_access_key_id, aws_secret_access_key, region
526
529
  if (configStrErrors||credsStrErrors)
527
530
  throw wrapErrors(errMsg, configStrErrors||credsStrErrors)
528
531
 
529
- const configProfiles = [`[profile ${name}]`+EOL]
530
- const credsProfiles = [`[${name}]`+EOL]
532
+ const configProfiles = [`[profile ${name}]`+NL]
533
+ const credsProfiles = [`[${name}]`+NL]
531
534
 
532
- credsProfiles.push(`aws_access_key_id = ${aws_access_key_id}`+EOL)
533
- credsProfiles.push(`aws_secret_access_key = ${aws_secret_access_key}`+EOL+EOL)
535
+ credsProfiles.push(`aws_access_key_id = ${aws_access_key_id}`+NL)
536
+ credsProfiles.push(`aws_secret_access_key = ${aws_secret_access_key}`+NL+NL)
534
537
 
535
- configProfiles.push(`region = ${region}`+EOL)
536
- configProfiles.push('output = json'+EOL+EOL)
538
+ configProfiles.push(`region = ${region}`+NL)
539
+ configProfiles.push('output = json'+NL+NL)
537
540
 
538
541
  const newCreds = credsProfiles.join('')
539
542
  const newConfig = configProfiles.join('')
@@ -543,14 +546,14 @@ const createProfile = ({ name, aws_access_key_id, aws_secret_access_key, region
543
546
  if (!credsStr)
544
547
  credsStr = DEFAULT_CREDS
545
548
 
546
- await fileHelper.write(AWS_CONFIG_FILE, configStr+EOL+newConfig)
547
- await fileHelper.write(AWS_CREDS_FILE, credsStr+EOL+newCreds)
549
+ await fileHelper.write(AWS_CONFIG_FILE, configStr+NL+newConfig)
550
+ await fileHelper.write(AWS_CREDS_FILE, credsStr+NL+newCreds)
548
551
  })())
549
552
 
550
553
  const createSsoProfile = name => catchErrors((async () => {
551
554
  await awsCliV2Exists()
552
555
  const exitCode = await new Promise(next => {
553
- const child = spawn('aws', ['configure', 'sso', '--profile', name],{ stdio: 'inherit' })
556
+ const child = spawn('aws', ['configure', 'sso', '--profile', name], { stdio: 'inherit', ...(IS_WINDOWS ? { shell: true } : {}) })
554
557
  child.on('exit', code => next(code))
555
558
  })
556
559
  if (exitCode !== 0)