Skip to content

Commit 91b40e0

Browse files
authored
perf!: modernized and removed commonjs support
* fix formatting issues * remove build step from ci * fix: passwordless npm publishing BREAKING CHANGE: remove commonjs support, use esm instead. The package now exclusively supports ESM.
1 parent 15e7e54 commit 91b40e0

28 files changed

Lines changed: 6282 additions & 6744 deletions

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Please describe the tests that you ran to verify your changes. Provide instructi
2222
## Checklist:
2323

2424
- [ ] `npm run spell`
25+
- [ ] `npm run format`
2526
- [ ] `npm run lint`
2627
- [ ] `npm audit`
27-
- [ ] `npm test`
28+
- [ ] `npm test`

.github/workflows/release.yml

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,50 @@
11
name: Secrets
22

33
on:
4-
- push
5-
- pull_request
4+
- push
5+
- pull_request
66

77
jobs:
8-
verify:
9-
runs-on: ubuntu-latest
8+
verify:
9+
runs-on: ubuntu-latest
1010

11-
concurrency:
12-
group: ${{ github.ref }}
13-
cancel-in-progress: true
11+
permissions:
12+
contents: write
13+
issues: write
14+
pull-requests: write
15+
id-token: write # Required for passwordless npm publishing
1416

15-
steps:
16-
- uses: actions/checkout@v4
17+
concurrency:
18+
group: ${{ github.ref }}
19+
cancel-in-progress: true
1720

18-
- uses: actions/setup-node@v3
19-
with:
20-
node-version: 22
21+
steps:
22+
- uses: actions/checkout@v6
2123

22-
- name: Install packages
23-
run: |
24-
npm ci --ignore-scripts
24+
- uses: actions/setup-node@v6
25+
with:
26+
node-version: 24
2527

26-
- name: Security audit
27-
run: npm audit --audit-level=moderate --omit=dev
28+
- name: Install packages
29+
run: |
30+
npm ci --ignore-scripts
2831
29-
- name: Lint check
30-
run: npm run lint
32+
- name: Security audit
33+
run: npm audit --audit-level=moderate --omit=dev
3134

32-
- name: Spell check
33-
run: npm run spell
35+
- name: Format check
36+
run: npm run format
3437

35-
# - name: Test (tests can only be run with valid AWS API key)
36-
# run: npm test
38+
- name: Lint check
39+
run: npm run lint
3740

38-
- name: Build dist directory
39-
run: npm run build
41+
- name: Spell check
42+
run: npm run spell
4043

41-
- name: Release
42-
run: npm run release
43-
env:
44-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
44+
- name: Test
45+
run: npm run test:ci
46+
47+
- name: Release
48+
run: npm run release
49+
env:
50+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.npmignore

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
# Source files (dist is built from these)
2-
lib/
3-
rollup.config.js
4-
5-
# Development files
6-
test
7-
eslint.config.mjs
8-
.github/
9-
.cspell.json
10-
.releaserc.yaml
11-
121
# Documentation files that aren't needed in the package
132
*.md
143
!README.md
@@ -30,11 +19,19 @@ yarn-error.log*
3019
.npm
3120

3221
# Development dependencies
33-
node_modules/
22+
.cspell.json
23+
.github/
3424
.nyc_output
25+
.prettierignore
26+
.prettierrc
27+
.releaserc.yaml
3528
coverage/
36-
rollup.config.mjs
37-
eslint.config.mjs
29+
eslint.config.js
30+
node_modules/
31+
package-lock.json
32+
test
33+
tsconfig.json
34+
vitest.config.ts
3835

3936
# Git files
4037
.git

.prettierignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Dependencies
2+
node_modules
3+
4+
# Build output
5+
dist
6+
7+
# Other
8+
*.log

.prettierrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"useTabs": true,
3+
"tabWidth": 2,
4+
"semi": true,
5+
"singleQuote": true,
6+
"trailingComma": "es5",
7+
"printWidth": 100,
8+
"endOfLine": "lf"
9+
}

.releaserc.yaml

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
branches:
2-
- master
3-
- next
4-
- next-major
5-
- name: beta
6-
prerelease: true
7-
- name: alpha
8-
prerelease: true
2+
- master
3+
- name: beta
4+
prerelease: true
5+
- name: alpha
6+
prerelease: true
97
plugins:
10-
- '@semantic-release/commit-analyzer'
11-
- '@semantic-release/release-notes-generator'
12-
- - '@semantic-release/npm'
13-
- pkgRoot: '.'
14-
- - '@semantic-release/github'
15-
- assets:
16-
- path: 'dist/**/*'
17-
label: 'Distribution files'
8+
- '@semantic-release/commit-analyzer'
9+
- - '@semantic-release/npm'
10+
- pkgRoot: '.'
11+
- - '@semantic-release/github'
12+
- assets: []

README.md

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ npm install --save @jwerre/secrets
1313
### Get all secrets
1414

1515
```js
16-
import {configSync} from '@jwerre/secrets';
16+
import { configSync } from '@jwerre/secrets';
1717

1818
// Retrieve all secrets that begin with 'my-project/production/'
1919
const config = configSync({
2020
region: 'us-east-1',
2121
namespace: 'my-project',
22-
env: 'production'
22+
env: 'production',
2323
});
2424
```
2525

2626
#### Result:
27+
2728
```js
2829
{
2930
name: 'My App'
@@ -48,30 +49,28 @@ const config = configSync({
4849
Loading _all_ your secrets may not always be the best option. It's much faster to load a single secret like this:
4950

5051
```js
51-
import {secretSync} from '@jwerre/secrets';
52+
import { secretSync } from '@jwerre/secrets';
5253
const dbCredentials = secretSync({ region: 'us-east-1', id: '/my-project/production/db' });
5354
```
5455

5556
#### Result:
57+
5658
```js
5759
{
5860
username: 'admin',
5961
password: 'Super$ercret!'
6062
}
6163
```
6264

63-
6465
### Asynchronously get all secrets
6566

6667
In most cases, you'll want to get your configuration object synchronously before your application starts up. But, if you prefer, you can also get your secrets asynchronously like this.
6768

6869
```js
69-
import {config} from '@jwerre/secrets';
70-
71-
( async function(){
70+
import { config } from '@jwerre/secrets';
7271

72+
(async function () {
7373
const appConfig = await config(options);
74-
7574
})();
7675
```
7776

@@ -90,10 +89,10 @@ import {config} from '@jwerre/secrets';
9089

9190
Your secrets should be named appropriately so they can be parsed into a proper object. They should also have an environment like 'production' or 'development' so the secrets can be loaded into the correct environment. You may use a namespace but that\'s not required. The [example](#example) above was generated from secrets with the following names:
9291

93-
- `acme-co/production/name`
94-
- `acme-co/production/db`
95-
- `acme-co/production/session`
96-
- `acme-co/production/apis/google`
92+
- `acme-co/production/name`
93+
- `acme-co/production/db`
94+
- `acme-co/production/session`
95+
- `acme-co/production/apis/google`
9796

9897
### Delimiters
9998

@@ -108,10 +107,7 @@ You'll need to give your application or service permission to access your secret
108107
"Version": "2012-10-17",
109108
"Statement": [
110109
{
111-
"Action": [
112-
"secretsmanager:ListSecrets",
113-
"secretsmanager:GetSecretValue"
114-
],
110+
"Action": ["secretsmanager:ListSecrets", "secretsmanager:GetSecretValue"],
115111
"Effect": "Allow",
116112
"Resource": "*"
117113
}
@@ -161,13 +157,13 @@ Create a new secret in AWS Secrets Manager. This method will automatically appen
161157

162158
Retrieve a secret from AWS Secrets Manager
163159

164-
| Option | Type | Description |
165-
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
166-
| id | String | The secret id. |
167-
| version | String | The secret version. |
168-
| stage | String | Staging label attached to the version. |
169-
| raw | Boolean | Return the full response from AWS. |
170-
| maxBuffer=65536 | Number | Largest amount of data in Bytes the secret can be (default: 65536 Bytes) which is the quota. See [Secret Manager quotas]( https://docs.aws.amazon.com/secretsmanager/latest/userguide/reference_limits.html#quotas). |
160+
| Option | Type | Description |
161+
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162+
| id | String | The secret id. |
163+
| version | String | The secret version. |
164+
| stage | String | Staging label attached to the version. |
165+
| raw | Boolean | Return the full response from AWS. |
166+
| maxBuffer=65536 | Number | Largest amount of data in Bytes the secret can be (default: 65536 Bytes) which is the quota. See [Secret Manager quotas](https://docs.aws.amazon.com/secretsmanager/latest/userguide/reference_limits.html#quotas). |
171167

172168
##### getSecretSync({})
173169

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,10 @@ program
2424
'The AWS Secrets Manager region',
2525
process.env.AWS_REGION || REGION
2626
)
27-
.option(
28-
'-e, --env <environment>',
29-
'Which environment to use in the secret name',
30-
ENV
31-
)
27+
.option('-e, --env <environment>', 'Which environment to use in the secret name', ENV)
3228
.option('-k, --kms <keyId>', 'KMS key id to use for encryption')
3329
.option('-n, --namespace <namespace>', 'Namespace of all parameters')
34-
.option(
35-
'-d, --delimiter <delimiter>',
36-
'Delimiter to use for secret name',
37-
DELIMITER
38-
)
30+
.option('-d, --delimiter <delimiter>', 'Delimiter to use for secret name', DELIMITER)
3931
.option('-i, --in <file>', 'Input file path (alternative to argument)')
4032
.parse(process.argv);
4133

@@ -57,9 +49,7 @@ async function getConfig(path) {
5749
await fs.access(path, F_OK | R_OK);
5850
} catch (err) {
5951
console.log(err);
60-
return Promise.reject(
61-
`${path} ${err.code === 'ENOENT' ? 'does not exist' : 'is read-only'}.`
62-
);
52+
return Promise.reject(`${path} ${err.code === 'ENOENT' ? 'does not exist' : 'is read-only'}.`);
6353
}
6454

6555
try {
@@ -97,10 +87,7 @@ function parseSecrets(obj, current) {
9787
// if it's the last nested object stop recursion
9888
if (Object.prototype.toString.call(value) === '[object Object]') {
9989
isEnumerable = Object.keys(value).some((key) => {
100-
return (
101-
Object.prototype.toString.call(value[key]) ===
102-
'[object Object]'
103-
);
90+
return Object.prototype.toString.call(value[key]) === '[object Object]';
10491
});
10592
}
10693

@@ -135,10 +122,7 @@ function createSecrets(list) {
135122
SecretString: item.value,
136123
};
137124

138-
if (
139-
Object.prototype.toString.call(params.SecretString) !==
140-
'[object String]'
141-
) {
125+
if (Object.prototype.toString.call(params.SecretString) !== '[object String]') {
142126
try {
143127
params.SecretString = JSON.stringify(params.SecretString);
144128
} catch {
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ function prompt(question) {
4848
return new Promise(function (resolve, reject) {
4949
readln.question(question, function (answer) {
5050
resolve(
51-
(answer &&
52-
answer.length &&
53-
answer.trim().toLowerCase() === 'yes') ||
51+
(answer && answer.length && answer.trim().toLowerCase() === 'yes') ||
5452
answer.trim().toLowerCase() === 'y'
5553
);
5654
});
@@ -146,9 +144,7 @@ Secret Manager. Are you sure you want to continue? [y/N] `;
146144
}
147145

148146
if (!abort) {
149-
return Promise.reject(
150-
'Aborting... Nothing was deleted your secrets are safe.'
151-
);
147+
return Promise.reject('Aborting... Nothing was deleted your secrets are safe.');
152148
}
153149
}
154150

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env node
22

33
import { Command } from 'commander';
4-
import Secrets from '../lib/secrets.mjs';
54
import { inspect } from 'util';
5+
import Secrets from '../lib/secrets.js';
66

77
const ENV = 'development';
88
const REGION = 'us-west-2';
@@ -18,24 +18,13 @@ program
1818
'The AWS Secrets Manager region',
1919
process.env.AWS_REGION || REGION
2020
)
21-
.option(
22-
'-e, --env <environment>',
23-
'Which environment to use in the secret name',
24-
ENV
25-
)
21+
.option('-e, --env <environment>', 'Which environment to use in the secret name', ENV)
2622
.option('-d, --delimiter <delimiter>', 'Secret name delimiter', DELIMITER)
2723
.option('-p, --pretty', 'Pretty output')
28-
.option(
29-
'-a, --all',
30-
'Ignore the environment and retrieve all secrets',
31-
false
32-
)
24+
.option('-a, --all', 'Ignore the environment and retrieve all secrets', false)
3325
.option('-n, --namespace <namespace>', 'Namespace of all parameters')
3426
.option('-t, --time', 'Display time it takes to retrieve config')
35-
.option(
36-
'-m, --maxBuffer <bytes>',
37-
'Largest the entire config can be in bytes (default: 3 Mb)'
38-
)
27+
.option('-m, --maxBuffer <bytes>', 'Largest the entire config can be in bytes (default: 3 Mb)')
3928
.parse(process.argv);
4029

4130
const options = program.opts();

0 commit comments

Comments
 (0)