Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@

---

## [5.0.2] 2025-11-10

### Changed

- Added support for `region` parameter in programmatic API

---

## [5.0.1] 2025-09-25

### Changed

- Lock down dependencies.

---

## [5.0.0] 2025-09-24

### Changed

- Updated supported node.js versions to 20, 22 and 24.
- Removed dependencies that are vendored into `@architect/utils`.

---

## [4.2.0] 2024-09-04

### Changed
Expand Down
5 changes: 3 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Architect Destroy destroys Architect-generated projects. More specifically, it d

## API

### `destroy({ appname, stackname, env, force, now, retries, credentials, quiet }, callback)`
### `destroy({ appname, stackname, env, force, now, retries, credentials, quiet, region }, callback)`

Destroys all infrastructure associated to your Architect app.

Expand All @@ -24,4 +24,5 @@ Destroys all infrastructure associated to your Architect app.
removed? This API is pinged every 10 seconds. If `retries` is exhausted,
`callback` will be invoked with an error.
- `credentials`: (object) AWS credentials object with `accessKeyId`, `secretAccessKey`, and optionally `sessionToken`
- `quiet`: (boolean) suppress status output during destruction
- `quiet`: (boolean) suppress status output during destruction
- `region`: (string) provide region override
5 changes: 3 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ function stackNotFound (StackName, err) {
* @param {boolean} [params.force] - deletes app with impunity, regardless of tables or buckets
* @param {object} [params.credentials] - AWS credentials object with accessKeyId, secretAccessKey, and optionally sessionToken
* @param {boolean} [params.quiet] - suppress output
* @param {string} [params.region] - region override
*/
module.exports = function destroy (params, callback) {
let { appname, env, force = false, inventory, now, retries, stackname, update, credentials, quiet } = params
let { appname, env, force = false, inventory, now, retries, stackname, update, credentials, quiet, region } = params
if (!update) update = updater('Destroy', { quiet })

// always validate input
Expand Down Expand Up @@ -86,7 +87,7 @@ module.exports = function destroy (params, callback) {
// Instantiate client
function (callback) {
let params = {
region: inventory.inv.aws.region,
region: region || inventory.inv.aws.region,
plugins: [
import('@aws-lite/cloudformation'),
import('@aws-lite/cloudwatch-logs'),
Expand Down
61 changes: 61 additions & 0 deletions test/unit/region-param-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
let test = require('tape')
let proxyquire = require('proxyquire')
let inventory = require('@architect/inventory')

let awsLiteArgs = []
let mockAwsLite = (args) => {
awsLiteArgs.push(args)
return Promise.resolve({
cloudformation: { DescribeStacks: ({ StackName }) => Promise.reject({ code: 'ValidationError', message: `Stack with id ${StackName} does not exist` }) },
CloudFormation: { DescribeStacks: ({ StackName }) => Promise.reject({ code: 'ValidationError', message: `Stack with id ${StackName} does not exist` }) },
ssm: {
GetParameter: () => Promise.resolve({
Parameter: {
Value: 'test-bucket-name',
},
}),
GetParametersByPath: () => Promise.resolve({ Parameters: [] }),
},
s3: {
HeadBucket: () => Promise.reject({ code: 'NotFound' }),
},
cloudwatchlogs: {
DescribeLogGroups: () => Promise.resolve({ logGroups: [] }),
},
})
}

let destroy = proxyquire('../../', {
'@aws-lite/client': mockAwsLite,
})

test('destroy credentials accepted', async t => {
t.plan(2)
let inv = await inventory({
rawArc: '@app\ntest-app\n@http\nget /',
deployStage: 'staging',
})
try {

await destroy({
appname: 'test-app',
env: 'staging',
credentials: {
accessKeyId: 'ASIATEST123456789',
secretAccessKey: 'testSecretKey123456789',
sessionToken: 'testSessionToken123456789',
},
inventory: inv,
now: true, // Skip the 5-second delay for testing
dryRun: true,
region: 'ca-central-1',
})

t.ok(awsLiteArgs[0].region, 'region is present')
t.equal(awsLiteArgs[0].region, 'ca-central-1', 'region is set correctly')
}
catch (err) {

t.fail('Destroy failed: ' + err.message)
}
})