node-lambda 0.19.0 → 0.22.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/test/main.js CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const process = require('process')
3
4
  const path = require('path')
4
5
  const os = require('os')
5
6
  const fs = require('fs-extra')
@@ -10,6 +11,7 @@ const awsMock = require('aws-sdk-mock')
10
11
  awsMock.setSDK(path.resolve('node_modules/aws-sdk'))
11
12
 
12
13
  const originalProgram = {
14
+ packageManager: 'npm',
13
15
  environment: 'development',
14
16
  accessKey: 'key',
15
17
  secretKey: 'secret',
@@ -39,10 +41,10 @@ let program = {}
39
41
  let codeDirectory = lambda._codeDirectory()
40
42
 
41
43
  const _timeout = function (params) {
42
- // Even if timeout is set for the whole test for Windows,
44
+ // Even if timeout is set for the whole test for Windows and Mac,
43
45
  // if it is set in local it will be valid.
44
- // For Windows, do not set it with local.
45
- if (process.platform !== 'win32') {
46
+ // For Windows and Mac, do not set it with local.
47
+ if (!['win32', 'darwin'].includes(process.platform)) {
46
48
  params.this.timeout(params.sec * 1000)
47
49
  }
48
50
  }
@@ -52,7 +54,7 @@ const lambdaMockSettings = {
52
54
  addPermission: {},
53
55
  getFunction: {
54
56
  Code: {},
55
- Configuration: {},
57
+ Configuration: { LastUpdateStatus: 'Successful' },
56
58
  FunctionArn: 'Lambda.getFunction.mock.FunctionArn'
57
59
  },
58
60
  createFunction: {
@@ -130,10 +132,10 @@ const _awsRestore = () => {
130
132
 
131
133
  /* global before, after, beforeEach, afterEach, describe, it */
132
134
  describe('lib/main', function () {
133
- if (process.platform === 'win32') {
134
- // It seems that it takes time for file operation in Windows.
135
- // So set `timeout(60000)` for the whole test.
136
- this.timeout(60000)
135
+ if (['win32', 'darwin'].includes(process.platform)) {
136
+ // It seems that it takes time for file operation in Windows and Mac.
137
+ // So set `timeout(120000)` for the whole test.
138
+ this.timeout(120000)
137
139
  }
138
140
 
139
141
  let aws = null // mock
@@ -149,7 +151,7 @@ describe('lib/main', function () {
149
151
  })
150
152
 
151
153
  it('version should be set', () => {
152
- assert.equal(lambda.version, '0.19.0')
154
+ assert.equal(lambda.version, '0.22.0')
153
155
  })
154
156
 
155
157
  describe('_codeDirectory', () => {
@@ -590,96 +592,254 @@ describe('lib/main', function () {
590
592
  })
591
593
  })
592
594
 
593
- describe('_npmInstall', function () {
594
- _timeout({ this: this, sec: 30 }) // ci should be faster than install
595
+ describe('_getNpmInstallCommand', () => {
596
+ describe('when package-lock.json exists', () => {
597
+ const codeDirectory = '.'
595
598
 
596
- // npm treats files as packages when installing, and so removes them.
597
- // Test with `devDependencies` packages that are not installed with the `--production` option.
598
- const nodeModulesMocha = path.join(codeDirectory, 'node_modules', 'mocha')
599
+ it('npm ci', () => {
600
+ const { packageManager, installOptions } = lambda._getNpmInstallCommand(program, codeDirectory)
601
+ assert.equal(packageManager, 'npm')
602
+ assert.deepEqual(installOptions, ['-s', 'ci', '--production', '--no-audit', '--prefix', codeDirectory])
603
+ })
599
604
 
600
- beforeEach(() => {
601
- return lambda._cleanDirectory(codeDirectory).then(() => {
602
- fs.copySync(
603
- path.join('node_modules', 'aws-sdk'),
604
- path.join(codeDirectory, 'node_modules', 'aws-sdk')
605
+ it('npm ci with "--no-optional"', () => {
606
+ const { packageManager, installOptions } = lambda._getNpmInstallCommand(
607
+ {
608
+ ...program,
609
+ optionalDependencies: false
610
+ },
611
+ codeDirectory
605
612
  )
606
- return lambda._fileCopy(program, '.', codeDirectory, true)
613
+ assert.equal(packageManager, 'npm')
614
+ assert.deepEqual(
615
+ installOptions,
616
+ ['-s', 'ci', '--production', '--no-audit', '--no-optional', '--prefix', codeDirectory]
617
+ )
618
+ })
619
+
620
+ it('npm ci on docker', () => {
621
+ const { packageManager, installOptions } = lambda._getNpmInstallCommand(
622
+ {
623
+ ...program,
624
+ dockerImage: 'test'
625
+ },
626
+ codeDirectory
627
+ )
628
+ assert.equal(packageManager, 'npm')
629
+ assert.deepEqual(installOptions, ['-s', 'ci', '--production', '--no-audit'])
607
630
  })
608
631
  })
609
632
 
610
- describe('when package-lock.json does exist', () => {
611
- it('should use "npm ci"', () => {
612
- const beforeAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
613
- return lambda._npmInstall(program, codeDirectory).then(() => {
614
- const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
615
- assert.include(contents, 'dotenv')
633
+ describe('when package-lock.json does not exist', () => {
634
+ const codeDirectory = './test'
616
635
 
617
- // To remove and then install.
618
- // beforeAwsSdkStat.ctimeMs < afterAwsSdkStat.ctimeMs
619
- const afterAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
620
- assert.isBelow(beforeAwsSdkStat.ctimeMs, afterAwsSdkStat.ctimeMs)
636
+ it('npm install', () => {
637
+ const { packageManager, installOptions } = lambda._getNpmInstallCommand(program, './test')
638
+ assert.equal(packageManager, 'npm')
639
+ assert.deepEqual(installOptions, ['-s', 'install', '--production', '--no-audit', '--prefix', './test'])
640
+ })
621
641
 
622
- // Not installed with the `--production` option.
623
- assert.isFalse(fs.existsSync(nodeModulesMocha))
624
- })
642
+ it('npm install with "--no-optional"', () => {
643
+ const { packageManager, installOptions } = lambda._getNpmInstallCommand(
644
+ {
645
+ ...program,
646
+ optionalDependencies: false
647
+ },
648
+ codeDirectory
649
+ )
650
+ assert.equal(packageManager, 'npm')
651
+ assert.deepEqual(
652
+ installOptions,
653
+ ['-s', 'install', '--production', '--no-audit', '--no-optional', '--prefix', codeDirectory]
654
+ )
625
655
  })
626
- })
627
656
 
628
- describe('when package-lock.json does not exist', () => {
629
- beforeEach(() => {
630
- return fs.removeSync(path.join(codeDirectory, 'package-lock.json'))
657
+ it('npm install on docker', () => {
658
+ const { packageManager, installOptions } = lambda._getNpmInstallCommand(
659
+ {
660
+ ...program,
661
+ dockerImage: 'test'
662
+ },
663
+ codeDirectory
664
+ )
665
+ assert.equal(packageManager, 'npm')
666
+ assert.deepEqual(installOptions, ['-s', 'install', '--production', '--no-audit'])
631
667
  })
668
+ })
669
+ })
632
670
 
633
- it('should use "npm install"', () => {
634
- const beforeAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
635
- return lambda._npmInstall(program, codeDirectory).then(() => {
636
- const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
637
- assert.include(contents, 'dotenv')
671
+ describe('_getYarnInstallCommand', () => {
672
+ const codeDirectory = '.'
638
673
 
639
- // Installed packages will remain intact.
640
- // beforeAwsSdkStat.ctimeMs === afterAwsSdkStat.ctimeMs
641
- const afterAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
642
- assert.equal(beforeAwsSdkStat.ctimeMs, afterAwsSdkStat.ctimeMs)
674
+ it('yarn install', () => {
675
+ const { packageManager, installOptions } = lambda._getYarnInstallCommand(program, codeDirectory)
676
+ assert.equal(packageManager, 'yarn')
677
+ assert.deepEqual(installOptions, ['-s', 'install', '--production', '--cwd', codeDirectory])
678
+ })
643
679
 
644
- // Not installed with the `--production` option.
645
- assert.isFalse(fs.existsSync(nodeModulesMocha))
646
- })
647
- })
680
+ it('yarn install with "--no-optional"', () => {
681
+ const { packageManager, installOptions } = lambda._getYarnInstallCommand(
682
+ {
683
+ ...program,
684
+ optionalDependencies: false
685
+ },
686
+ codeDirectory
687
+ )
688
+ assert.equal(packageManager, 'yarn')
689
+ assert.deepEqual(
690
+ installOptions,
691
+ ['-s', 'install', '--production', '--ignore-optional', '--cwd', codeDirectory]
692
+ )
648
693
  })
649
694
 
650
- describe('optionalDependencies', () => {
651
- beforeEach(() => {
652
- const packageJsonPath = path.join(codeDirectory, 'package.json')
653
- const packageJson = require(packageJsonPath)
654
- packageJson.optionalDependencies = { npm: '*' }
655
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson))
695
+ it('yarn install on docker', () => {
696
+ const { packageManager, installOptions } = lambda._getYarnInstallCommand(
697
+ {
698
+ ...program,
699
+ dockerImage: 'test'
700
+ },
701
+ codeDirectory
702
+ )
703
+ assert.equal(packageManager, 'yarn')
704
+ assert.deepEqual(installOptions, ['-s', 'install', '--production'])
705
+ })
706
+ })
707
+
708
+ describe('_packageInstall', function () {
709
+ _timeout({ this: this, sec: 60 }) // ci should be faster than install
710
+
711
+ // npm treats files as packages when installing, and so removes them.
712
+ // Test with `devDependencies` packages that are not installed with the `--production` option.
713
+ const nodeModulesMocha = path.join(codeDirectory, 'node_modules', 'mocha')
714
+
715
+ const testCleanAndInstall = async (packageManager) => {
716
+ const beforeAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
717
+
718
+ const usedPackageManager = await lambda._packageInstall(
719
+ {
720
+ ...program,
721
+ packageManager
722
+ },
723
+ codeDirectory
724
+ )
725
+ assert.equal(usedPackageManager, packageManager)
726
+
727
+ const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
728
+ assert.include(contents, 'dotenv')
729
+
730
+ // To remove and then install.
731
+ // beforeAwsSdkStat.ctimeMs < afterAwsSdkStat.ctimeMs
732
+ const afterAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
733
+ assert.isBelow(beforeAwsSdkStat.ctimeMs, afterAwsSdkStat.ctimeMs)
734
+
735
+ // Not installed with the `--production` option.
736
+ assert.isFalse(fs.existsSync(nodeModulesMocha))
737
+ }
738
+
739
+ const beforeEachOptionalDependencies = () => {
740
+ const packageJsonPath = path.join(codeDirectory, 'package.json')
741
+ const packageJson = require(packageJsonPath)
742
+ packageJson.optionalDependencies = { npm: '*' }
743
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson))
744
+
745
+ // Remove package-lock.json because it does not match the package.json to which optionalDependencies was added.
746
+ fs.removeSync(path.join(codeDirectory, 'package-lock.json'))
747
+ }
748
+
749
+ const testOptionalDependenciesIsInstalled = async (packageManager) => {
750
+ const usedPackageManager = await lambda._packageInstall(
751
+ {
752
+ ...program,
753
+ packageManager
754
+ },
755
+ codeDirectory
756
+ )
757
+ assert.equal(usedPackageManager, packageManager)
758
+
759
+ const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
760
+ assert.include(contents, 'npm')
761
+ }
762
+
763
+ const testOptionalDependenciesIsNotInstalled = async (packageManager) => {
764
+ const params = {
765
+ ...program,
766
+ packageManager,
767
+ optionalDependencies: false
768
+ }
769
+ const usedPackageManager = await lambda._packageInstall(params, codeDirectory)
770
+ assert.equal(usedPackageManager, packageManager)
771
+
772
+ const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
773
+ assert.notInclude(contents, 'npm')
774
+ }
775
+
776
+ beforeEach(async () => {
777
+ await lambda._cleanDirectory(codeDirectory)
778
+ await lambda._fileCopy(program, '.', codeDirectory, false)
779
+ })
780
+
781
+ describe('Use npm', () => {
782
+ describe('when package-lock.json does exist', () => {
783
+ it('should use "npm ci"', () => testCleanAndInstall('npm'))
656
784
  })
657
785
 
658
- describe('No `--no-optionalDependencies`', () => {
659
- it('optionalDependencies is installed', () => {
660
- return lambda._npmInstall(program, codeDirectory).then(() => {
786
+ describe('when package-lock.json does not exist', () => {
787
+ beforeEach(() => {
788
+ return fs.removeSync(path.join(codeDirectory, 'package-lock.json'))
789
+ })
790
+
791
+ it('should use "npm install"', () => {
792
+ const beforeAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
793
+ return lambda._packageInstall(program, codeDirectory).then((usedPackageManager) => {
794
+ assert.equal(usedPackageManager, 'npm')
795
+
661
796
  const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
662
- assert.include(contents, 'npm')
797
+ assert.include(contents, 'dotenv')
798
+
799
+ // Installed packages will remain intact.
800
+ // beforeAwsSdkStat.ctimeMs === afterAwsSdkStat.ctimeMs
801
+ const afterAwsSdkStat = fs.statSync(path.join(codeDirectory, 'node_modules', 'aws-sdk'))
802
+ assert.equal(beforeAwsSdkStat.ctimeMs, afterAwsSdkStat.ctimeMs)
803
+
804
+ // Not installed with the `--production` option.
805
+ assert.isFalse(fs.existsSync(nodeModulesMocha))
663
806
  })
664
807
  })
665
808
  })
666
809
 
667
- describe('With `--no-optionalDependencies`', () => {
668
- it('optionalDependency is NOT installed', () => {
669
- const params = {
670
- ...program,
671
- optionalDependencies: false
672
- }
673
- return lambda._npmInstall(params, codeDirectory).then(() => {
674
- const contents = fs.readdirSync(path.join(codeDirectory, 'node_modules'))
675
- assert.notInclude(contents, 'npm')
676
- })
810
+ describe('optionalDependencies', () => {
811
+ beforeEach(beforeEachOptionalDependencies)
812
+
813
+ describe('No `--no-optionalDependencies`', () => {
814
+ it('optionalDependencies is installed', () => testOptionalDependenciesIsInstalled('npm'))
815
+ })
816
+
817
+ describe('With `--no-optionalDependencies`', () => {
818
+ it('optionalDependency is NOT installed', () => testOptionalDependenciesIsNotInstalled('npm'))
819
+ })
820
+ })
821
+ })
822
+
823
+ describe('Use yarn', () => {
824
+ it('should use "yarn install"', () => testCleanAndInstall('yarn'))
825
+
826
+ describe('optionalDependencies', () => {
827
+ beforeEach(beforeEachOptionalDependencies)
828
+
829
+ describe('No `--ignore-optionalDependencies`', () => {
830
+ it('optionalDependencies is installed', () => testOptionalDependenciesIsInstalled('yarn'))
831
+ })
832
+
833
+ describe('With `--ignore-optionalDependencies`', () => {
834
+ it('optionalDependency is NOT installed', () => testOptionalDependenciesIsNotInstalled('yarn'))
677
835
  })
678
836
  })
679
837
  })
680
838
  })
681
839
 
682
- describe('_npmInstall (When codeDirectory contains characters to be escaped)', () => {
840
+ describe('_packageInstall (When codeDirectory contains characters to be escaped)', function () {
841
+ _timeout({ this: this, sec: 30 }) // give it time to build the node modules
842
+
683
843
  beforeEach(() => {
684
844
  // Since '\' can not be included in the file or directory name in Windows
685
845
  const directoryName = process.platform === 'win32'
@@ -696,14 +856,21 @@ describe('lib/main', function () {
696
856
  codeDirectory = lambda._codeDirectory()
697
857
  })
698
858
 
699
- it('_npm adds node_modules', function () {
700
- _timeout({ this: this, sec: 30 }) // give it time to build the node modules
859
+ const testFunc = async (packageManager) => {
860
+ const usedPackageManager = await lambda._packageInstall(
861
+ {
862
+ ...program,
863
+ packageManager
864
+ },
865
+ codeDirectory
866
+ )
867
+ assert.equal(usedPackageManager, packageManager)
868
+ const contents = fs.readdirSync(codeDirectory)
869
+ assert.include(contents, 'node_modules')
870
+ }
701
871
 
702
- return lambda._npmInstall(program, codeDirectory).then(() => {
703
- const contents = fs.readdirSync(codeDirectory)
704
- assert.include(contents, 'node_modules')
705
- })
706
- })
872
+ it('npm adds node_modules', () => testFunc('npm'))
873
+ it('yarn adds node_modules', () => testFunc('yarn'))
707
874
  })
708
875
 
709
876
  describe('_postInstallScript', () => {
@@ -773,53 +940,70 @@ describe('lib/main', function () {
773
940
  })
774
941
  })
775
942
 
776
- describe('_zip', () => {
777
- beforeEach(function () {
778
- _timeout({ this: this, sec: 30 }) // give it time to build the node modules
779
- return Promise.resolve().then(() => {
780
- return lambda._cleanDirectory(codeDirectory)
781
- }).then(() => {
782
- return lambda._fileCopy(program, '.', codeDirectory, true)
783
- }).then(() => {
784
- return lambda._npmInstall(program, codeDirectory)
785
- }).then(() => {
786
- if (process.platform !== 'win32') {
787
- fs.symlinkSync(
788
- path.join(__dirname, '..', 'bin', 'node-lambda'),
789
- path.join(codeDirectory, 'node-lambda-link')
790
- )
791
- }
792
- })
793
- })
943
+ describe('_zip', function () {
944
+ _timeout({ this: this, sec: 60 }) // give it time to zip
794
945
 
795
- it('Compress the file. `index.js` and `bin/node-lambda` are included and the permission is also preserved.', function () {
796
- _timeout({ this: this, sec: 30 }) // give it time to zip
946
+ const beforeTask = async (packageManager) => {
947
+ await lambda._cleanDirectory(codeDirectory)
948
+ await lambda._fileCopy(program, '.', codeDirectory, true)
949
+ const usedPackageManager = await lambda._packageInstall(
950
+ {
951
+ ...program,
952
+ packageManager
953
+ },
954
+ codeDirectory
955
+ )
956
+ assert.equal(usedPackageManager, packageManager)
957
+ if (process.platform !== 'win32') {
958
+ fs.symlinkSync(
959
+ path.join(__dirname, '..', 'bin', 'node-lambda'),
960
+ path.join(codeDirectory, 'node-lambda-link')
961
+ )
962
+ }
963
+ }
797
964
 
798
- return lambda._zip(program, codeDirectory).then((data) => {
799
- const archive = new Zip(data)
800
- assert.include(archive.files['index.js'].name, 'index.js')
801
- assert.include(archive.files['bin/node-lambda'].name, 'bin/node-lambda')
802
-
803
- if (process.platform !== 'win32') {
804
- const indexJsStat = fs.lstatSync('index.js')
805
- const binNodeLambdaStat = fs.lstatSync(path.join('bin', 'node-lambda'))
806
- assert.equal(
807
- archive.files['index.js'].unixPermissions,
808
- indexJsStat.mode
809
- )
810
- assert.equal(
811
- archive.files['bin/node-lambda'].unixPermissions,
812
- binNodeLambdaStat.mode
813
- )
814
-
815
- // isSymbolicLink
816
- assert.include(archive.files['node-lambda-link'].name, 'node-lambda-link')
817
- assert.equal(
818
- archive.files['node-lambda-link'].unixPermissions & fs.constants.S_IFMT,
819
- fs.constants.S_IFLNK
820
- )
821
- }
822
- })
965
+ const testFunc = async (packageManager) => {
966
+ // setup
967
+ await beforeTask(packageManager)
968
+
969
+ // tests
970
+ const data = await lambda._zip(program, codeDirectory)
971
+ const archive = new Zip(data)
972
+ assert.include(archive.files['index.js'].name, 'index.js')
973
+ assert.include(archive.files['bin/node-lambda'].name, 'bin/node-lambda')
974
+
975
+ if (process.platform !== 'win32') {
976
+ const indexJsStat = fs.lstatSync('index.js')
977
+ const binNodeLambdaStat = fs.lstatSync(path.join('bin', 'node-lambda'))
978
+ assert.equal(
979
+ archive.files['index.js'].unixPermissions,
980
+ indexJsStat.mode
981
+ )
982
+ assert.equal(
983
+ archive.files['bin/node-lambda'].unixPermissions,
984
+ binNodeLambdaStat.mode
985
+ )
986
+
987
+ // isSymbolicLink
988
+ assert.include(archive.files['node-lambda-link'].name, 'node-lambda-link')
989
+ assert.equal(
990
+ archive.files['node-lambda-link'].unixPermissions & fs.constants.S_IFMT,
991
+ fs.constants.S_IFLNK
992
+ )
993
+ }
994
+ }
995
+
996
+ describe('Use npm', () => {
997
+ it(
998
+ 'Compress the file. `index.js` and `bin/node-lambda` are included and the permission is also preserved.',
999
+ () => testFunc('npm')
1000
+ )
1001
+ })
1002
+ describe('Use yarn', () => {
1003
+ it(
1004
+ 'Compress the file. `index.js` and `bin/node-lambda` are included and the permission is also preserved.',
1005
+ () => testFunc('yarn')
1006
+ )
823
1007
  })
824
1008
  })
825
1009
 
@@ -865,6 +1049,24 @@ describe('lib/main', function () {
865
1049
  })
866
1050
  })
867
1051
  })
1052
+
1053
+ it('cleans the temporary directory before running `_archivePrebuilt`', function () {
1054
+ _timeout({ this: this, sec: 30 }) // give it time to zip
1055
+ const buildDir = '.build_' + Date.now()
1056
+ const codeDir = lambda._codeDirectory()
1057
+ const tmpFile = path.join(codeDir, 'deleteme')
1058
+ after(() => fs.removeSync(buildDir))
1059
+
1060
+ fs.mkdirSync(codeDir, { recursive: true })
1061
+ fs.writeFileSync(tmpFile, '...')
1062
+ fs.mkdirSync(buildDir)
1063
+ fs.writeFileSync(path.join(buildDir, 'test'), '...')
1064
+
1065
+ program.prebuiltDirectory = buildDir
1066
+ return lambda._archive(program).then((_data) => {
1067
+ assert.isNotTrue(fs.existsSync(tmpFile))
1068
+ })
1069
+ })
868
1070
  })
869
1071
 
870
1072
  describe('_readArchive', () => {
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const assert = require('chai').assert
4
+ const process = require('process')
4
5
  const path = require('path')
5
6
  const fs = require('fs-extra')
6
7
  const spawn = require('child_process').spawn
package/test/s3_deploy.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { assert } = require('chai')
4
+ const process = require('process')
4
5
  const path = require('path')
5
6
  const aws = require('aws-sdk-mock')
6
7
  aws.setSDK(path.resolve('node_modules/aws-sdk'))