node-lambda 1.3.0 → 2.0.0-alpha.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.
@@ -9,7 +9,7 @@ jobs:
9
9
  strategy:
10
10
  fail-fast: false
11
11
  matrix:
12
- node-version: [16.x, 18.x, 20.x]
12
+ node-version: [20.x, 22.x]
13
13
  steps:
14
14
  - uses: actions/checkout@v4
15
15
  - uses: actions/setup-node@v4
@@ -32,7 +32,7 @@ jobs:
32
32
  - uses: actions/checkout@v4
33
33
  - uses: actions/setup-node@v4
34
34
  with:
35
- node-version: 20.x
35
+ node-version: 22.x
36
36
  cache: 'npm'
37
37
  - run: node -v
38
38
  - run: npm -v
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- If you found this useful, consider also checking out [dotenv-vault](https://github.com/dotenv-org/dotenv-vault). Thank you! 😇
1
+ > If you found this useful, consider also checking out [dotenvx](https://github.com/dotenvx/dotenvx). Thank you! 😇
2
2
 
3
3
  # node-lambda
4
4
 
package/bin/node-lambda CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  'use strict'
4
4
 
5
- require('dotenv').config()
5
+ require('@dotenvx/dotenvx').config()
6
6
  const process = require('process')
7
7
  const path = require('path')
8
8
 
package/lib/.env.example CHANGED
@@ -16,4 +16,5 @@ AWS_VPC_SECURITY_GROUPS=
16
16
  AWS_TRACING_CONFIG=
17
17
  AWS_LOGS_RETENTION_IN_DAYS=
18
18
  EXCLUDE_GLOBS="event.json build/"
19
+ CONFIG_FILE="deploy.env"
19
20
  PACKAGE_DIRECTORY=build
package/lib/aws.js CHANGED
@@ -1,38 +1,41 @@
1
- 'use strict'
2
-
3
- const aws = require('aws-sdk')
4
- const proxy = require('proxy-agent')
5
-
6
- module.exports = {
7
- sdk: aws,
8
- updateConfig (config, region) {
9
- const awsSecurity = { region }
10
-
11
- if (config.profile) {
12
- aws.config.credentials = new aws.SharedIniFileCredentials({
13
- profile: config.profile
14
- })
15
- } else {
16
- awsSecurity.accessKeyId = config.accessKey
17
- awsSecurity.secretAccessKey = config.secretKey
18
- }
19
-
20
- if (config.sessionToken) {
21
- awsSecurity.sessionToken = config.sessionToken
22
- }
23
-
24
- if (config.deployTimeout) {
25
- aws.config.httpOptions.timeout = parseInt(config.deployTimeout)
26
- }
27
-
28
- if (config.proxy) {
29
- aws.config.httpOptions.agent = proxy(config.proxy)
30
- }
31
-
32
- if (config.endpoint) {
33
- aws.config.endpoint = config.endpoint
34
- }
35
-
36
- aws.config.update(awsSecurity)
37
- }
38
- }
1
+ // TODO:
2
+ // Support these option settings in SDK v3
3
+ //
4
+ // 'use strict'
5
+ //
6
+ // const aws = require('aws-sdk')
7
+ // const proxy = require('proxy-agent')
8
+ //
9
+ // module.exports = {
10
+ // sdk: aws,
11
+ // updateConfig (config, region) {
12
+ // const awsSecurity = { region }
13
+ //
14
+ // if (config.profile) {
15
+ // aws.config.credentials = new aws.SharedIniFileCredentials({
16
+ // profile: config.profile
17
+ // })
18
+ // } else {
19
+ // awsSecurity.accessKeyId = config.accessKey
20
+ // awsSecurity.secretAccessKey = config.secretKey
21
+ // }
22
+ //
23
+ // if (config.sessionToken) {
24
+ // awsSecurity.sessionToken = config.sessionToken
25
+ // }
26
+ //
27
+ // if (config.deployTimeout) {
28
+ // aws.config.httpOptions.timeout = parseInt(config.deployTimeout)
29
+ // }
30
+ //
31
+ // if (config.proxy) {
32
+ // aws.config.httpOptions.agent = proxy(config.proxy)
33
+ // }
34
+ //
35
+ // if (config.endpoint) {
36
+ // aws.config.endpoint = config.endpoint
37
+ // }
38
+ //
39
+ // aws.config.update(awsSecurity)
40
+ // }
41
+ // }
@@ -1,15 +1,14 @@
1
1
  'use strict'
2
2
 
3
+ const {
4
+ CloudWatchLogsClient,
5
+ CreateLogGroupCommand,
6
+ PutRetentionPolicyCommand
7
+ } = require('@aws-sdk/client-cloudwatch-logs')
8
+
3
9
  class CloudWatchLogs {
4
- constructor (aws, region) {
5
- // Authenticated `aws` object in `lib/main.js`
6
- this.lambda = new aws.Lambda({
7
- region,
8
- apiVersion: '2015-03-31'
9
- })
10
- this.cloudwatchlogs = new aws.CloudWatchLogs({
11
- apiVersion: '2014-03-28'
12
- })
10
+ constructor (config) {
11
+ this.client = new CloudWatchLogsClient(config)
13
12
  }
14
13
 
15
14
  _logGroupName (params) {
@@ -17,33 +16,24 @@ class CloudWatchLogs {
17
16
  }
18
17
 
19
18
  _createLogGroup (params) {
20
- return new Promise((resolve, reject) => {
21
- this.cloudwatchlogs.createLogGroup({
19
+ try {
20
+ return this.client.send(new CreateLogGroupCommand({
22
21
  logGroupName: this._logGroupName(params)
23
- }, (err, data) => {
24
- if (err) {
25
- if (err.code === 'ResourceAlreadyExistsException') {
26
- // If it exists it will result in an error but there is no problem.
27
- return resolve({})
28
- }
29
- return reject(err)
30
- }
31
-
32
- resolve(data)
33
- })
34
- })
22
+ }))
23
+ } catch (err) {
24
+ if (err.code === 'ResourceAlreadyExistsException') {
25
+ // If it exists it will result in an error but there is no problem.
26
+ return {}
27
+ }
28
+ throw err
29
+ }
35
30
  }
36
31
 
37
32
  _putRetentionPolicy (params) {
38
- return new Promise((resolve, reject) => {
39
- this.cloudwatchlogs.putRetentionPolicy({
40
- logGroupName: this._logGroupName(params),
41
- retentionInDays: params.retentionInDays
42
- }, (err, data) => {
43
- if (err) return reject(err)
44
- resolve(data)
45
- })
46
- })
33
+ return this.client.send(new PutRetentionPolicyCommand({
34
+ logGroupName: this._logGroupName(params),
35
+ retentionInDays: params.retentionInDays
36
+ }))
47
37
  }
48
38
 
49
39
  setLogsRetentionPolicy (params) {
package/lib/main.js CHANGED
@@ -3,14 +3,13 @@
3
3
  const process = require('process')
4
4
  const path = require('path')
5
5
  const os = require('os')
6
- const aws = require(path.join(__dirname, 'aws'))
7
6
  const { exec, execSync, execFile } = require('child_process')
8
7
  const fs = require('fs-extra')
9
8
  const klaw = require('klaw')
10
9
  const packageJson = require(path.join(__dirname, '..', 'package.json'))
11
10
  const { minimatch } = require('minimatch')
12
11
  const archiver = require('archiver')
13
- const dotenv = require('dotenv')
12
+ const dotenv = require('@dotenvx/dotenvx')
14
13
  const ScheduleEvents = require(path.join(__dirname, 'schedule_events'))
15
14
  const S3Events = require(path.join(__dirname, 's3_events'))
16
15
  const S3Deploy = require(path.join(__dirname, 's3_deploy'))
@@ -19,6 +18,29 @@ const CloudWatchLogs = require(path.join(__dirname, 'cloudwatch_logs'))
19
18
  const AWSXRay = require('aws-xray-sdk-core')
20
19
  const { createNamespace } = require('continuation-local-storage')
21
20
 
21
+ /*
22
+ * Migrating to v3.
23
+ *
24
+ * # About retry
25
+ * By default, each client already has a default retry strategy.
26
+ * The default retry count is 3, and only retryable errors will be retried.
27
+ * https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html
28
+ */
29
+ const {
30
+ LambdaClient,
31
+ CreateEventSourceMappingCommand,
32
+ CreateFunctionCommand,
33
+ DeleteEventSourceMappingCommand,
34
+ GetFunctionCommand,
35
+ ListEventSourceMappingsCommand,
36
+ ListTagsCommand,
37
+ TagResourceCommand,
38
+ UntagResourceCommand,
39
+ UpdateEventSourceMappingCommand,
40
+ UpdateFunctionCodeCommand,
41
+ UpdateFunctionConfigurationCommand
42
+ } = require('@aws-sdk/client-lambda')
43
+
22
44
  const maxBufferSize = 50 * 1024 * 1024
23
45
 
24
46
  class Lambda {
@@ -236,8 +258,8 @@ Emulate only the body of the API Gateway event.
236
258
  Role: program.role,
237
259
  Runtime: program.runtime,
238
260
  Description: program.description,
239
- MemorySize: program.memorySize,
240
- Timeout: program.timeout,
261
+ MemorySize: Number(program.memorySize),
262
+ Timeout: Number(program.timeout),
241
263
  Architectures: program.architecture ? [program.architecture] : ['x86_64'],
242
264
  Publish: (() => {
243
265
  if (typeof program.publish === 'boolean') {
@@ -661,43 +683,24 @@ Emulate only the body of the API Gateway event.
661
683
  delete functionConfigParams.Layers
662
684
  }
663
685
 
664
- const updateConfigRequest = lambda.updateFunctionConfiguration(functionConfigParams)
665
- updateConfigRequest.on('retry', (response) => {
666
- console.log(response.error.message)
667
- console.log('=> Retrying')
668
- })
669
- const updateConfigResponse = await updateConfigRequest.promise()
686
+ const updateConfigResponse = await lambda.send(new UpdateFunctionConfigurationCommand(functionConfigParams))
670
687
 
671
688
  // Wait for the `Configuration.LastUpdateStatus` to change from `InProgress` to `Successful`.
689
+ const getFunction = new GetFunctionCommand({ FunctionName: params.FunctionName })
672
690
  for (let i = 0; i < 10; i++) {
673
- const data = await lambda.getFunction({ FunctionName: params.FunctionName }).promise()
691
+ const data = await lambda.send(getFunction)
674
692
  if (data.Configuration.LastUpdateStatus === 'Successful') {
675
693
  break
676
694
  }
677
695
  await new Promise((resolve) => setTimeout(resolve, 3000))
678
696
  }
679
-
680
- const updateCodeRequest = lambda.updateFunctionCode(functionCodeParams)
681
- updateCodeRequest.on('retry', (response) => {
682
- console.log(response.error.message)
683
- console.log('=> Retrying')
684
- })
685
- await updateCodeRequest.promise()
697
+ lambda.send(new UpdateFunctionCodeCommand(functionCodeParams))
686
698
 
687
699
  return updateConfigResponse
688
700
  }
689
701
 
690
702
  _uploadNew (lambda, params) {
691
- return new Promise((resolve, reject) => {
692
- const request = lambda.createFunction(params, (err, data) => {
693
- if (err) return reject(err)
694
- resolve(data)
695
- })
696
- request.on('retry', (response) => {
697
- console.log(response.error.message)
698
- console.log('=> Retrying')
699
- })
700
- })
703
+ return lambda.send(new CreateFunctionCommand(params))
701
704
  }
702
705
 
703
706
  _readArchive (program) {
@@ -769,16 +772,12 @@ they may not work as expected in the Lambda environment.
769
772
  return this._zip(program, codeDirectory)
770
773
  }
771
774
 
772
- _listEventSourceMappings (lambda, params) {
773
- return new Promise((resolve, reject) => {
774
- lambda.listEventSourceMappings(params, (err, data) => {
775
- if (err) return reject(err)
776
- if (data && data.EventSourceMappings) {
777
- return resolve(data.EventSourceMappings)
778
- }
779
- return resolve([])
780
- })
781
- })
775
+ async _listEventSourceMappings (lambda, params) {
776
+ const data = await lambda.send(new ListEventSourceMappingsCommand(params))
777
+ if (data && data.EventSourceMappings) {
778
+ return data.EventSourceMappings
779
+ }
780
+ return []
782
781
  }
783
782
 
784
783
  _getStartingPosition (eventSource) {
@@ -846,48 +845,30 @@ they may not work as expected in the Lambda environment.
846
845
  switch (updateEventSource.type) {
847
846
  case 'create':
848
847
  delete updateEventSource.type
849
- return new Promise((resolve, reject) => {
850
- lambda.createEventSourceMapping(updateEventSource, (err, data) => {
851
- if (err) return reject(err)
852
- resolve(data)
853
- })
854
- })
848
+ return lambda.send(new CreateEventSourceMappingCommand(updateEventSource))
855
849
  case 'update':
856
850
  delete updateEventSource.type
857
- return new Promise((resolve, reject) => {
858
- lambda.updateEventSourceMapping(updateEventSource, (err, data) => {
859
- if (err) return reject(err)
860
- resolve(data)
861
- })
862
- })
851
+ return lambda.send(new UpdateEventSourceMappingCommand(updateEventSource))
863
852
  case 'delete':
864
853
  delete updateEventSource.type
865
- return new Promise((resolve, reject) => {
866
- lambda.deleteEventSourceMapping(updateEventSource, (err, data) => {
867
- if (err) return reject(err)
868
- resolve(data)
869
- })
870
- })
854
+ return lambda.send(new DeleteEventSourceMappingCommand(updateEventSource))
855
+ default:
856
+ return Promise.resolve()
871
857
  }
872
- return Promise.resolve()
873
858
  }))
874
859
  }
875
860
 
876
- _updateTags (lambda, functionArn, tags) {
861
+ async _updateTags (lambda, functionArn, tags) {
877
862
  if (!tags || Object.keys(tags).length <= 0) {
878
- return Promise.resolve([])
879
- } else {
880
- return lambda.listTags({ Resource: functionArn }).promise()
881
- .then(data => {
882
- const keys = Object.keys(data.Tags)
883
- return keys && keys.length > 0
884
- ? lambda.untagResource({ Resource: functionArn, TagKeys: keys }).promise()
885
- : Promise.resolve()
886
- })
887
- .then(() => {
888
- return lambda.tagResource({ Resource: functionArn, Tags: tags }).promise()
889
- })
863
+ return []
890
864
  }
865
+
866
+ const data = await lambda.send(new ListTagsCommand({ Resource: functionArn }))
867
+ const keys = Object.keys(data.Tags)
868
+ if (keys && keys.length > 0) {
869
+ await lambda.send(new UntagResourceCommand({ Resource: functionArn, TagKeys: keys }))
870
+ }
871
+ return lambda.send(new TagResourceCommand({ Resource: functionArn, Tags: tags }))
891
872
  }
892
873
 
893
874
  _updateScheduleEvents (scheduleEvents, functionArn, scheduleList) {
@@ -973,115 +954,108 @@ they may not work as expected in the Lambda environment.
973
954
  !!err.message.match(/^Function not found:/)
974
955
  }
975
956
 
976
- _deployToRegion (program, params, region, buffer) {
977
- aws.updateConfig(program, region)
957
+ async _deployToRegion (program, params, region, buffer) {
958
+ // sdk v3 todo: Migration of aws.updateConfig.
959
+ // aws.updateConfig(program, region)
960
+ const config = { region }
978
961
 
979
962
  console.log('=> Reading event source file to memory')
980
963
  const eventSourceList = this._eventSourceList(program)
981
964
 
982
- return Promise.resolve().then(() => {
983
- if (this._isUseS3(program)) {
984
- const s3Deploy = new S3Deploy(aws.sdk, region)
985
- return s3Deploy.putPackage(params, region, buffer)
986
- }
987
- return null
988
- }).then((code) => {
989
- if (code != null) params.Code = code
990
- }).then(() => {
991
- if (!this._isUseS3(program)) {
992
- console.log(`=> Uploading zip file to AWS Lambda ${region} with parameters:`)
993
- } else {
994
- console.log(`=> Uploading AWS Lambda ${region} with parameters:`)
995
- }
996
- console.log(params)
965
+ if (this._isUseS3(program)) {
966
+ const s3Deploy = new S3Deploy(config)
967
+ params.Code = await s3Deploy.putPackage(params, region, buffer)
968
+ console.log(`=> Uploading AWS Lambda ${region} with parameters:`)
969
+ } else {
970
+ console.log(`=> Uploading zip file to AWS Lambda ${region} with parameters:`)
971
+ }
972
+ console.log(params)
997
973
 
998
- const lambda = new aws.sdk.Lambda({
999
- region,
1000
- apiVersion: '2015-03-31'
1001
- })
1002
- const scheduleEvents = new ScheduleEvents(aws.sdk, region)
1003
- const s3Events = new S3Events(aws.sdk, region)
1004
- const cloudWatchLogs = new CloudWatchLogs(aws.sdk, region)
974
+ const lambdaClient = new LambdaClient(config)
975
+ const scheduleEvents = new ScheduleEvents(config)
976
+ const s3Events = new S3Events(config)
977
+ const cloudWatchLogs = new CloudWatchLogs(config)
1005
978
 
1006
- // Checking function
1007
- return lambda.getFunction({
1008
- FunctionName: params.FunctionName
1009
- }).promise().then(() => {
1010
- // Function exists
1011
- return this._listEventSourceMappings(lambda, {
979
+ const existsFunction = await (async () => {
980
+ try {
981
+ await lambdaClient.send(new GetFunctionCommand({
1012
982
  FunctionName: params.FunctionName
1013
- }).then((existingEventSourceList) => {
1014
- return Promise.all([
1015
- this._uploadExisting(lambda, params).then((results) => {
1016
- console.log('=> Done uploading. Results follow: ')
1017
- console.log(results)
1018
- return results
1019
- }).then(results => {
1020
- return Promise.all([
1021
- this._updateScheduleEvents(
1022
- scheduleEvents,
1023
- results.FunctionArn,
1024
- eventSourceList.ScheduleEvents
1025
- ),
1026
- this._updateS3Events(
1027
- s3Events,
1028
- results.FunctionArn,
1029
- eventSourceList.S3Events
1030
- ),
1031
- this._updateTags(
1032
- lambda,
1033
- results.FunctionArn,
1034
- params.Tags)
1035
- ])
1036
- }),
1037
- this._updateEventSources(
1038
- lambda,
1039
- params.FunctionName,
1040
- existingEventSourceList,
1041
- eventSourceList.EventSourceMappings
1042
- ),
1043
- this._setLogsRetentionPolicy(
1044
- cloudWatchLogs,
1045
- program,
1046
- params.FunctionName
1047
- )
1048
- ])
1049
- })
1050
- }).catch((err) => {
983
+ }))
984
+ return true
985
+ } catch (err) {
1051
986
  if (!this._isFunctionDoesNotExist(err)) {
1052
987
  throw err
1053
988
  }
1054
- // Function does not exist
1055
- return this._uploadNew(lambda, params).then((results) => {
1056
- console.log('=> Done uploading. Results follow: ')
1057
- console.log(results)
1058
-
1059
- return Promise.all([
1060
- this._updateEventSources(
1061
- lambda,
1062
- params.FunctionName,
1063
- [],
1064
- eventSourceList.EventSourceMappings
1065
- ),
1066
- this._updateScheduleEvents(
1067
- scheduleEvents,
1068
- results.FunctionArn,
1069
- eventSourceList.ScheduleEvents
1070
- ),
1071
- this._updateS3Events(
1072
- s3Events,
1073
- results.FunctionArn,
1074
- eventSourceList.S3Events
1075
- ),
1076
- this._setLogsRetentionPolicy(
1077
- cloudWatchLogs,
1078
- program,
1079
- params.FunctionName
1080
- )
1081
- ])
1082
- })
989
+ return false
990
+ }
991
+ })()
992
+
993
+ if (existsFunction) {
994
+ const existingEventSourceList = await this._listEventSourceMappings(lambdaClient, {
995
+ FunctionName: params.FunctionName
1083
996
  })
1084
- })
997
+ const results = await this._uploadExisting(lambdaClient, params)
998
+ console.log('=> Done uploading. Results follow: ')
999
+ console.log(results)
1000
+
1001
+ return Promise.all([
1002
+ Promise.all([
1003
+ this._updateScheduleEvents(
1004
+ scheduleEvents,
1005
+ results.FunctionArn,
1006
+ eventSourceList.ScheduleEvents
1007
+ ),
1008
+ this._updateS3Events(
1009
+ s3Events,
1010
+ results.FunctionArn,
1011
+ eventSourceList.S3Events
1012
+ ),
1013
+ this._updateTags(
1014
+ lambdaClient,
1015
+ results.FunctionArn,
1016
+ params.Tags)
1017
+ ]),
1018
+ this._updateEventSources(
1019
+ lambdaClient,
1020
+ params.FunctionName,
1021
+ existingEventSourceList,
1022
+ eventSourceList.EventSourceMappings
1023
+ ),
1024
+ this._setLogsRetentionPolicy(
1025
+ cloudWatchLogs,
1026
+ program,
1027
+ params.FunctionName
1028
+ )
1029
+ ])
1030
+ } else {
1031
+ const results = await this._uploadNew(lambdaClient, params)
1032
+ console.log('=> Done uploading. Results follow: ')
1033
+ console.log(results)
1034
+
1035
+ return Promise.all([
1036
+ this._updateEventSources(
1037
+ lambdaClient,
1038
+ params.FunctionName,
1039
+ [],
1040
+ eventSourceList.EventSourceMappings
1041
+ ),
1042
+ this._updateScheduleEvents(
1043
+ scheduleEvents,
1044
+ results.FunctionArn,
1045
+ eventSourceList.ScheduleEvents
1046
+ ),
1047
+ this._updateS3Events(
1048
+ s3Events,
1049
+ results.FunctionArn,
1050
+ eventSourceList.S3Events
1051
+ ),
1052
+ this._setLogsRetentionPolicy(
1053
+ cloudWatchLogs,
1054
+ program,
1055
+ params.FunctionName
1056
+ )
1057
+ ])
1058
+ }
1085
1059
  }
1086
1060
 
1087
1061
  _printDeployResults (results, isFirst) {
package/lib/s3_deploy.js CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  const process = require('process')
4
4
  const crypto = require('crypto')
5
+
6
+ const {
7
+ S3Client,
8
+ CreateBucketCommand,
9
+ PutObjectCommand
10
+ } = require('@aws-sdk/client-s3')
11
+
5
12
  // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property
6
13
  const S3_LOCATION_POSSIBLE_VALUES = [
7
14
  'EU',
@@ -33,12 +40,8 @@ const S3_LOCATION_POSSIBLE_VALUES = [
33
40
  ]
34
41
 
35
42
  class S3Deploy {
36
- constructor (aws, region) {
37
- // Authenticated `aws` object in `lib/main.js`
38
- this.s3 = new aws.S3({
39
- region,
40
- apiVersion: '2006-03-01'
41
- })
43
+ constructor (config) {
44
+ this.client = new S3Client(config)
42
45
  }
43
46
 
44
47
  _md5 (str) {
@@ -107,30 +110,21 @@ class S3Deploy {
107
110
  LocationConstraint: s3Location
108
111
  }
109
112
  }
110
- return new Promise((resolve, reject) => {
111
- this.s3.createBucket(_params, (err, data) => {
112
- if (err) {
113
- // Ignored created
114
- if (err.code === 'BucketAlreadyOwnedByYou') return resolve({})
115
- return reject(err)
116
- }
117
- resolve(data)
118
- })
119
- })
113
+ try {
114
+ return this.client.send(new CreateBucketCommand(_params))
115
+ } catch (err) {
116
+ // Ignored created
117
+ if (err.code === 'BucketAlreadyOwnedByYou') return {}
118
+ throw err
119
+ }
120
120
  }
121
121
 
122
122
  _putObject (params, buffer) {
123
- const _params = {
123
+ return this.client.send(new PutObjectCommand({
124
124
  Body: buffer,
125
125
  Bucket: params.bucketName,
126
126
  Key: params.s3Key
127
- }
128
- return new Promise((resolve, reject) => {
129
- this.s3.putObject(_params, (err, data) => {
130
- if (err) reject(err)
131
- resolve(data)
132
- })
133
- })
127
+ }))
134
128
  }
135
129
 
136
130
  putPackage (params, region, buffer) {