@vercel/go 2.4.4 → 2.5.1

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.
Files changed (2) hide show
  1. package/dist/index.js +1451 -325
  2. package/package.json +3 -13
package/dist/index.js CHANGED
@@ -5556,6 +5556,979 @@ function patch (fs) {
5556
5556
  }
5557
5557
 
5558
5558
 
5559
+ /***/ }),
5560
+
5561
+ /***/ 3016:
5562
+ /***/ ((module) => {
5563
+
5564
+ "use strict";
5565
+
5566
+
5567
+ module.exports = clone
5568
+
5569
+ var getPrototypeOf = Object.getPrototypeOf || function (obj) {
5570
+ return obj.__proto__
5571
+ }
5572
+
5573
+ function clone (obj) {
5574
+ if (obj === null || typeof obj !== 'object')
5575
+ return obj
5576
+
5577
+ if (obj instanceof Object)
5578
+ var copy = { __proto__: getPrototypeOf(obj) }
5579
+ else
5580
+ var copy = Object.create(null)
5581
+
5582
+ Object.getOwnPropertyNames(obj).forEach(function (key) {
5583
+ Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key))
5584
+ })
5585
+
5586
+ return copy
5587
+ }
5588
+
5589
+
5590
+ /***/ }),
5591
+
5592
+ /***/ 7156:
5593
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
5594
+
5595
+ var fs = __webpack_require__(5747)
5596
+ var polyfills = __webpack_require__(4692)
5597
+ var legacy = __webpack_require__(6465)
5598
+ var clone = __webpack_require__(3016)
5599
+
5600
+ var util = __webpack_require__(1669)
5601
+
5602
+ /* istanbul ignore next - node 0.x polyfill */
5603
+ var gracefulQueue
5604
+ var previousSymbol
5605
+
5606
+ /* istanbul ignore else - node 0.x polyfill */
5607
+ if (typeof Symbol === 'function' && typeof Symbol.for === 'function') {
5608
+ gracefulQueue = Symbol.for('graceful-fs.queue')
5609
+ // This is used in testing by future versions
5610
+ previousSymbol = Symbol.for('graceful-fs.previous')
5611
+ } else {
5612
+ gracefulQueue = '___graceful-fs.queue'
5613
+ previousSymbol = '___graceful-fs.previous'
5614
+ }
5615
+
5616
+ function noop () {}
5617
+
5618
+ function publishQueue(context, queue) {
5619
+ Object.defineProperty(context, gracefulQueue, {
5620
+ get: function() {
5621
+ return queue
5622
+ }
5623
+ })
5624
+ }
5625
+
5626
+ var debug = noop
5627
+ if (util.debuglog)
5628
+ debug = util.debuglog('gfs4')
5629
+ else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ''))
5630
+ debug = function() {
5631
+ var m = util.format.apply(util, arguments)
5632
+ m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ')
5633
+ console.error(m)
5634
+ }
5635
+
5636
+ // Once time initialization
5637
+ if (!fs[gracefulQueue]) {
5638
+ // This queue can be shared by multiple loaded instances
5639
+ var queue = global[gracefulQueue] || []
5640
+ publishQueue(fs, queue)
5641
+
5642
+ // Patch fs.close/closeSync to shared queue version, because we need
5643
+ // to retry() whenever a close happens *anywhere* in the program.
5644
+ // This is essential when multiple graceful-fs instances are
5645
+ // in play at the same time.
5646
+ fs.close = (function (fs$close) {
5647
+ function close (fd, cb) {
5648
+ return fs$close.call(fs, fd, function (err) {
5649
+ // This function uses the graceful-fs shared queue
5650
+ if (!err) {
5651
+ resetQueue()
5652
+ }
5653
+
5654
+ if (typeof cb === 'function')
5655
+ cb.apply(this, arguments)
5656
+ })
5657
+ }
5658
+
5659
+ Object.defineProperty(close, previousSymbol, {
5660
+ value: fs$close
5661
+ })
5662
+ return close
5663
+ })(fs.close)
5664
+
5665
+ fs.closeSync = (function (fs$closeSync) {
5666
+ function closeSync (fd) {
5667
+ // This function uses the graceful-fs shared queue
5668
+ fs$closeSync.apply(fs, arguments)
5669
+ resetQueue()
5670
+ }
5671
+
5672
+ Object.defineProperty(closeSync, previousSymbol, {
5673
+ value: fs$closeSync
5674
+ })
5675
+ return closeSync
5676
+ })(fs.closeSync)
5677
+
5678
+ if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
5679
+ process.on('exit', function() {
5680
+ debug(fs[gracefulQueue])
5681
+ __webpack_require__(2357).equal(fs[gracefulQueue].length, 0)
5682
+ })
5683
+ }
5684
+ }
5685
+
5686
+ if (!global[gracefulQueue]) {
5687
+ publishQueue(global, fs[gracefulQueue]);
5688
+ }
5689
+
5690
+ module.exports = patch(clone(fs))
5691
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
5692
+ module.exports = patch(fs)
5693
+ fs.__patched = true;
5694
+ }
5695
+
5696
+ function patch (fs) {
5697
+ // Everything that references the open() function needs to be in here
5698
+ polyfills(fs)
5699
+ fs.gracefulify = patch
5700
+
5701
+ fs.createReadStream = createReadStream
5702
+ fs.createWriteStream = createWriteStream
5703
+ var fs$readFile = fs.readFile
5704
+ fs.readFile = readFile
5705
+ function readFile (path, options, cb) {
5706
+ if (typeof options === 'function')
5707
+ cb = options, options = null
5708
+
5709
+ return go$readFile(path, options, cb)
5710
+
5711
+ function go$readFile (path, options, cb, startTime) {
5712
+ return fs$readFile(path, options, function (err) {
5713
+ if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
5714
+ enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()])
5715
+ else {
5716
+ if (typeof cb === 'function')
5717
+ cb.apply(this, arguments)
5718
+ }
5719
+ })
5720
+ }
5721
+ }
5722
+
5723
+ var fs$writeFile = fs.writeFile
5724
+ fs.writeFile = writeFile
5725
+ function writeFile (path, data, options, cb) {
5726
+ if (typeof options === 'function')
5727
+ cb = options, options = null
5728
+
5729
+ return go$writeFile(path, data, options, cb)
5730
+
5731
+ function go$writeFile (path, data, options, cb, startTime) {
5732
+ return fs$writeFile(path, data, options, function (err) {
5733
+ if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
5734
+ enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()])
5735
+ else {
5736
+ if (typeof cb === 'function')
5737
+ cb.apply(this, arguments)
5738
+ }
5739
+ })
5740
+ }
5741
+ }
5742
+
5743
+ var fs$appendFile = fs.appendFile
5744
+ if (fs$appendFile)
5745
+ fs.appendFile = appendFile
5746
+ function appendFile (path, data, options, cb) {
5747
+ if (typeof options === 'function')
5748
+ cb = options, options = null
5749
+
5750
+ return go$appendFile(path, data, options, cb)
5751
+
5752
+ function go$appendFile (path, data, options, cb, startTime) {
5753
+ return fs$appendFile(path, data, options, function (err) {
5754
+ if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
5755
+ enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()])
5756
+ else {
5757
+ if (typeof cb === 'function')
5758
+ cb.apply(this, arguments)
5759
+ }
5760
+ })
5761
+ }
5762
+ }
5763
+
5764
+ var fs$copyFile = fs.copyFile
5765
+ if (fs$copyFile)
5766
+ fs.copyFile = copyFile
5767
+ function copyFile (src, dest, flags, cb) {
5768
+ if (typeof flags === 'function') {
5769
+ cb = flags
5770
+ flags = 0
5771
+ }
5772
+ return go$copyFile(src, dest, flags, cb)
5773
+
5774
+ function go$copyFile (src, dest, flags, cb, startTime) {
5775
+ return fs$copyFile(src, dest, flags, function (err) {
5776
+ if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
5777
+ enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()])
5778
+ else {
5779
+ if (typeof cb === 'function')
5780
+ cb.apply(this, arguments)
5781
+ }
5782
+ })
5783
+ }
5784
+ }
5785
+
5786
+ var fs$readdir = fs.readdir
5787
+ fs.readdir = readdir
5788
+ var noReaddirOptionVersions = /^v[0-5]\./
5789
+ function readdir (path, options, cb) {
5790
+ if (typeof options === 'function')
5791
+ cb = options, options = null
5792
+
5793
+ var go$readdir = noReaddirOptionVersions.test(process.version)
5794
+ ? function go$readdir (path, options, cb, startTime) {
5795
+ return fs$readdir(path, fs$readdirCallback(
5796
+ path, options, cb, startTime
5797
+ ))
5798
+ }
5799
+ : function go$readdir (path, options, cb, startTime) {
5800
+ return fs$readdir(path, options, fs$readdirCallback(
5801
+ path, options, cb, startTime
5802
+ ))
5803
+ }
5804
+
5805
+ return go$readdir(path, options, cb)
5806
+
5807
+ function fs$readdirCallback (path, options, cb, startTime) {
5808
+ return function (err, files) {
5809
+ if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
5810
+ enqueue([
5811
+ go$readdir,
5812
+ [path, options, cb],
5813
+ err,
5814
+ startTime || Date.now(),
5815
+ Date.now()
5816
+ ])
5817
+ else {
5818
+ if (files && files.sort)
5819
+ files.sort()
5820
+
5821
+ if (typeof cb === 'function')
5822
+ cb.call(this, err, files)
5823
+ }
5824
+ }
5825
+ }
5826
+ }
5827
+
5828
+ if (process.version.substr(0, 4) === 'v0.8') {
5829
+ var legStreams = legacy(fs)
5830
+ ReadStream = legStreams.ReadStream
5831
+ WriteStream = legStreams.WriteStream
5832
+ }
5833
+
5834
+ var fs$ReadStream = fs.ReadStream
5835
+ if (fs$ReadStream) {
5836
+ ReadStream.prototype = Object.create(fs$ReadStream.prototype)
5837
+ ReadStream.prototype.open = ReadStream$open
5838
+ }
5839
+
5840
+ var fs$WriteStream = fs.WriteStream
5841
+ if (fs$WriteStream) {
5842
+ WriteStream.prototype = Object.create(fs$WriteStream.prototype)
5843
+ WriteStream.prototype.open = WriteStream$open
5844
+ }
5845
+
5846
+ Object.defineProperty(fs, 'ReadStream', {
5847
+ get: function () {
5848
+ return ReadStream
5849
+ },
5850
+ set: function (val) {
5851
+ ReadStream = val
5852
+ },
5853
+ enumerable: true,
5854
+ configurable: true
5855
+ })
5856
+ Object.defineProperty(fs, 'WriteStream', {
5857
+ get: function () {
5858
+ return WriteStream
5859
+ },
5860
+ set: function (val) {
5861
+ WriteStream = val
5862
+ },
5863
+ enumerable: true,
5864
+ configurable: true
5865
+ })
5866
+
5867
+ // legacy names
5868
+ var FileReadStream = ReadStream
5869
+ Object.defineProperty(fs, 'FileReadStream', {
5870
+ get: function () {
5871
+ return FileReadStream
5872
+ },
5873
+ set: function (val) {
5874
+ FileReadStream = val
5875
+ },
5876
+ enumerable: true,
5877
+ configurable: true
5878
+ })
5879
+ var FileWriteStream = WriteStream
5880
+ Object.defineProperty(fs, 'FileWriteStream', {
5881
+ get: function () {
5882
+ return FileWriteStream
5883
+ },
5884
+ set: function (val) {
5885
+ FileWriteStream = val
5886
+ },
5887
+ enumerable: true,
5888
+ configurable: true
5889
+ })
5890
+
5891
+ function ReadStream (path, options) {
5892
+ if (this instanceof ReadStream)
5893
+ return fs$ReadStream.apply(this, arguments), this
5894
+ else
5895
+ return ReadStream.apply(Object.create(ReadStream.prototype), arguments)
5896
+ }
5897
+
5898
+ function ReadStream$open () {
5899
+ var that = this
5900
+ open(that.path, that.flags, that.mode, function (err, fd) {
5901
+ if (err) {
5902
+ if (that.autoClose)
5903
+ that.destroy()
5904
+
5905
+ that.emit('error', err)
5906
+ } else {
5907
+ that.fd = fd
5908
+ that.emit('open', fd)
5909
+ that.read()
5910
+ }
5911
+ })
5912
+ }
5913
+
5914
+ function WriteStream (path, options) {
5915
+ if (this instanceof WriteStream)
5916
+ return fs$WriteStream.apply(this, arguments), this
5917
+ else
5918
+ return WriteStream.apply(Object.create(WriteStream.prototype), arguments)
5919
+ }
5920
+
5921
+ function WriteStream$open () {
5922
+ var that = this
5923
+ open(that.path, that.flags, that.mode, function (err, fd) {
5924
+ if (err) {
5925
+ that.destroy()
5926
+ that.emit('error', err)
5927
+ } else {
5928
+ that.fd = fd
5929
+ that.emit('open', fd)
5930
+ }
5931
+ })
5932
+ }
5933
+
5934
+ function createReadStream (path, options) {
5935
+ return new fs.ReadStream(path, options)
5936
+ }
5937
+
5938
+ function createWriteStream (path, options) {
5939
+ return new fs.WriteStream(path, options)
5940
+ }
5941
+
5942
+ var fs$open = fs.open
5943
+ fs.open = open
5944
+ function open (path, flags, mode, cb) {
5945
+ if (typeof mode === 'function')
5946
+ cb = mode, mode = null
5947
+
5948
+ return go$open(path, flags, mode, cb)
5949
+
5950
+ function go$open (path, flags, mode, cb, startTime) {
5951
+ return fs$open(path, flags, mode, function (err, fd) {
5952
+ if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
5953
+ enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()])
5954
+ else {
5955
+ if (typeof cb === 'function')
5956
+ cb.apply(this, arguments)
5957
+ }
5958
+ })
5959
+ }
5960
+ }
5961
+
5962
+ return fs
5963
+ }
5964
+
5965
+ function enqueue (elem) {
5966
+ debug('ENQUEUE', elem[0].name, elem[1])
5967
+ fs[gracefulQueue].push(elem)
5968
+ retry()
5969
+ }
5970
+
5971
+ // keep track of the timeout between retry() calls
5972
+ var retryTimer
5973
+
5974
+ // reset the startTime and lastTime to now
5975
+ // this resets the start of the 60 second overall timeout as well as the
5976
+ // delay between attempts so that we'll retry these jobs sooner
5977
+ function resetQueue () {
5978
+ var now = Date.now()
5979
+ for (var i = 0; i < fs[gracefulQueue].length; ++i) {
5980
+ // entries that are only a length of 2 are from an older version, don't
5981
+ // bother modifying those since they'll be retried anyway.
5982
+ if (fs[gracefulQueue][i].length > 2) {
5983
+ fs[gracefulQueue][i][3] = now // startTime
5984
+ fs[gracefulQueue][i][4] = now // lastTime
5985
+ }
5986
+ }
5987
+ // call retry to make sure we're actively processing the queue
5988
+ retry()
5989
+ }
5990
+
5991
+ function retry () {
5992
+ // clear the timer and remove it to help prevent unintended concurrency
5993
+ clearTimeout(retryTimer)
5994
+ retryTimer = undefined
5995
+
5996
+ if (fs[gracefulQueue].length === 0)
5997
+ return
5998
+
5999
+ var elem = fs[gracefulQueue].shift()
6000
+ var fn = elem[0]
6001
+ var args = elem[1]
6002
+ // these items may be unset if they were added by an older graceful-fs
6003
+ var err = elem[2]
6004
+ var startTime = elem[3]
6005
+ var lastTime = elem[4]
6006
+
6007
+ // if we don't have a startTime we have no way of knowing if we've waited
6008
+ // long enough, so go ahead and retry this item now
6009
+ if (startTime === undefined) {
6010
+ debug('RETRY', fn.name, args)
6011
+ fn.apply(null, args)
6012
+ } else if (Date.now() - startTime >= 60000) {
6013
+ // it's been more than 60 seconds total, bail now
6014
+ debug('TIMEOUT', fn.name, args)
6015
+ var cb = args.pop()
6016
+ if (typeof cb === 'function')
6017
+ cb.call(null, err)
6018
+ } else {
6019
+ // the amount of time between the last attempt and right now
6020
+ var sinceAttempt = Date.now() - lastTime
6021
+ // the amount of time between when we first tried, and when we last tried
6022
+ // rounded up to at least 1
6023
+ var sinceStart = Math.max(lastTime - startTime, 1)
6024
+ // backoff. wait longer than the total time we've been retrying, but only
6025
+ // up to a maximum of 100ms
6026
+ var desiredDelay = Math.min(sinceStart * 1.2, 100)
6027
+ // it's been long enough since the last retry, do it again
6028
+ if (sinceAttempt >= desiredDelay) {
6029
+ debug('RETRY', fn.name, args)
6030
+ fn.apply(null, args.concat([startTime]))
6031
+ } else {
6032
+ // if we can't do this job yet, push it to the end of the queue
6033
+ // and let the next iteration check again
6034
+ fs[gracefulQueue].push(elem)
6035
+ }
6036
+ }
6037
+
6038
+ // schedule our next run if one isn't already scheduled
6039
+ if (retryTimer === undefined) {
6040
+ retryTimer = setTimeout(retry, 0)
6041
+ }
6042
+ }
6043
+
6044
+
6045
+ /***/ }),
6046
+
6047
+ /***/ 6465:
6048
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
6049
+
6050
+ var Stream = __webpack_require__(2413).Stream
6051
+
6052
+ module.exports = legacy
6053
+
6054
+ function legacy (fs) {
6055
+ return {
6056
+ ReadStream: ReadStream,
6057
+ WriteStream: WriteStream
6058
+ }
6059
+
6060
+ function ReadStream (path, options) {
6061
+ if (!(this instanceof ReadStream)) return new ReadStream(path, options);
6062
+
6063
+ Stream.call(this);
6064
+
6065
+ var self = this;
6066
+
6067
+ this.path = path;
6068
+ this.fd = null;
6069
+ this.readable = true;
6070
+ this.paused = false;
6071
+
6072
+ this.flags = 'r';
6073
+ this.mode = 438; /*=0666*/
6074
+ this.bufferSize = 64 * 1024;
6075
+
6076
+ options = options || {};
6077
+
6078
+ // Mixin options into this
6079
+ var keys = Object.keys(options);
6080
+ for (var index = 0, length = keys.length; index < length; index++) {
6081
+ var key = keys[index];
6082
+ this[key] = options[key];
6083
+ }
6084
+
6085
+ if (this.encoding) this.setEncoding(this.encoding);
6086
+
6087
+ if (this.start !== undefined) {
6088
+ if ('number' !== typeof this.start) {
6089
+ throw TypeError('start must be a Number');
6090
+ }
6091
+ if (this.end === undefined) {
6092
+ this.end = Infinity;
6093
+ } else if ('number' !== typeof this.end) {
6094
+ throw TypeError('end must be a Number');
6095
+ }
6096
+
6097
+ if (this.start > this.end) {
6098
+ throw new Error('start must be <= end');
6099
+ }
6100
+
6101
+ this.pos = this.start;
6102
+ }
6103
+
6104
+ if (this.fd !== null) {
6105
+ process.nextTick(function() {
6106
+ self._read();
6107
+ });
6108
+ return;
6109
+ }
6110
+
6111
+ fs.open(this.path, this.flags, this.mode, function (err, fd) {
6112
+ if (err) {
6113
+ self.emit('error', err);
6114
+ self.readable = false;
6115
+ return;
6116
+ }
6117
+
6118
+ self.fd = fd;
6119
+ self.emit('open', fd);
6120
+ self._read();
6121
+ })
6122
+ }
6123
+
6124
+ function WriteStream (path, options) {
6125
+ if (!(this instanceof WriteStream)) return new WriteStream(path, options);
6126
+
6127
+ Stream.call(this);
6128
+
6129
+ this.path = path;
6130
+ this.fd = null;
6131
+ this.writable = true;
6132
+
6133
+ this.flags = 'w';
6134
+ this.encoding = 'binary';
6135
+ this.mode = 438; /*=0666*/
6136
+ this.bytesWritten = 0;
6137
+
6138
+ options = options || {};
6139
+
6140
+ // Mixin options into this
6141
+ var keys = Object.keys(options);
6142
+ for (var index = 0, length = keys.length; index < length; index++) {
6143
+ var key = keys[index];
6144
+ this[key] = options[key];
6145
+ }
6146
+
6147
+ if (this.start !== undefined) {
6148
+ if ('number' !== typeof this.start) {
6149
+ throw TypeError('start must be a Number');
6150
+ }
6151
+ if (this.start < 0) {
6152
+ throw new Error('start must be >= zero');
6153
+ }
6154
+
6155
+ this.pos = this.start;
6156
+ }
6157
+
6158
+ this.busy = false;
6159
+ this._queue = [];
6160
+
6161
+ if (this.fd === null) {
6162
+ this._open = fs.open;
6163
+ this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
6164
+ this.flush();
6165
+ }
6166
+ }
6167
+ }
6168
+
6169
+
6170
+ /***/ }),
6171
+
6172
+ /***/ 4692:
6173
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
6174
+
6175
+ var constants = __webpack_require__(7619)
6176
+
6177
+ var origCwd = process.cwd
6178
+ var cwd = null
6179
+
6180
+ var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform
6181
+
6182
+ process.cwd = function() {
6183
+ if (!cwd)
6184
+ cwd = origCwd.call(process)
6185
+ return cwd
6186
+ }
6187
+ try {
6188
+ process.cwd()
6189
+ } catch (er) {}
6190
+
6191
+ // This check is needed until node.js 12 is required
6192
+ if (typeof process.chdir === 'function') {
6193
+ var chdir = process.chdir
6194
+ process.chdir = function (d) {
6195
+ cwd = null
6196
+ chdir.call(process, d)
6197
+ }
6198
+ if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir)
6199
+ }
6200
+
6201
+ module.exports = patch
6202
+
6203
+ function patch (fs) {
6204
+ // (re-)implement some things that are known busted or missing.
6205
+
6206
+ // lchmod, broken prior to 0.6.2
6207
+ // back-port the fix here.
6208
+ if (constants.hasOwnProperty('O_SYMLINK') &&
6209
+ process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
6210
+ patchLchmod(fs)
6211
+ }
6212
+
6213
+ // lutimes implementation, or no-op
6214
+ if (!fs.lutimes) {
6215
+ patchLutimes(fs)
6216
+ }
6217
+
6218
+ // https://github.com/isaacs/node-graceful-fs/issues/4
6219
+ // Chown should not fail on einval or eperm if non-root.
6220
+ // It should not fail on enosys ever, as this just indicates
6221
+ // that a fs doesn't support the intended operation.
6222
+
6223
+ fs.chown = chownFix(fs.chown)
6224
+ fs.fchown = chownFix(fs.fchown)
6225
+ fs.lchown = chownFix(fs.lchown)
6226
+
6227
+ fs.chmod = chmodFix(fs.chmod)
6228
+ fs.fchmod = chmodFix(fs.fchmod)
6229
+ fs.lchmod = chmodFix(fs.lchmod)
6230
+
6231
+ fs.chownSync = chownFixSync(fs.chownSync)
6232
+ fs.fchownSync = chownFixSync(fs.fchownSync)
6233
+ fs.lchownSync = chownFixSync(fs.lchownSync)
6234
+
6235
+ fs.chmodSync = chmodFixSync(fs.chmodSync)
6236
+ fs.fchmodSync = chmodFixSync(fs.fchmodSync)
6237
+ fs.lchmodSync = chmodFixSync(fs.lchmodSync)
6238
+
6239
+ fs.stat = statFix(fs.stat)
6240
+ fs.fstat = statFix(fs.fstat)
6241
+ fs.lstat = statFix(fs.lstat)
6242
+
6243
+ fs.statSync = statFixSync(fs.statSync)
6244
+ fs.fstatSync = statFixSync(fs.fstatSync)
6245
+ fs.lstatSync = statFixSync(fs.lstatSync)
6246
+
6247
+ // if lchmod/lchown do not exist, then make them no-ops
6248
+ if (fs.chmod && !fs.lchmod) {
6249
+ fs.lchmod = function (path, mode, cb) {
6250
+ if (cb) process.nextTick(cb)
6251
+ }
6252
+ fs.lchmodSync = function () {}
6253
+ }
6254
+ if (fs.chown && !fs.lchown) {
6255
+ fs.lchown = function (path, uid, gid, cb) {
6256
+ if (cb) process.nextTick(cb)
6257
+ }
6258
+ fs.lchownSync = function () {}
6259
+ }
6260
+
6261
+ // on Windows, A/V software can lock the directory, causing this
6262
+ // to fail with an EACCES or EPERM if the directory contains newly
6263
+ // created files. Try again on failure, for up to 60 seconds.
6264
+
6265
+ // Set the timeout this long because some Windows Anti-Virus, such as Parity
6266
+ // bit9, may lock files for up to a minute, causing npm package install
6267
+ // failures. Also, take care to yield the scheduler. Windows scheduling gives
6268
+ // CPU to a busy looping process, which can cause the program causing the lock
6269
+ // contention to be starved of CPU by node, so the contention doesn't resolve.
6270
+ if (platform === "win32") {
6271
+ fs.rename = typeof fs.rename !== 'function' ? fs.rename
6272
+ : (function (fs$rename) {
6273
+ function rename (from, to, cb) {
6274
+ var start = Date.now()
6275
+ var backoff = 0;
6276
+ fs$rename(from, to, function CB (er) {
6277
+ if (er
6278
+ && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY")
6279
+ && Date.now() - start < 60000) {
6280
+ setTimeout(function() {
6281
+ fs.stat(to, function (stater, st) {
6282
+ if (stater && stater.code === "ENOENT")
6283
+ fs$rename(from, to, CB);
6284
+ else
6285
+ cb(er)
6286
+ })
6287
+ }, backoff)
6288
+ if (backoff < 100)
6289
+ backoff += 10;
6290
+ return;
6291
+ }
6292
+ if (cb) cb(er)
6293
+ })
6294
+ }
6295
+ if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename)
6296
+ return rename
6297
+ })(fs.rename)
6298
+ }
6299
+
6300
+ // if read() returns EAGAIN, then just try it again.
6301
+ fs.read = typeof fs.read !== 'function' ? fs.read
6302
+ : (function (fs$read) {
6303
+ function read (fd, buffer, offset, length, position, callback_) {
6304
+ var callback
6305
+ if (callback_ && typeof callback_ === 'function') {
6306
+ var eagCounter = 0
6307
+ callback = function (er, _, __) {
6308
+ if (er && er.code === 'EAGAIN' && eagCounter < 10) {
6309
+ eagCounter ++
6310
+ return fs$read.call(fs, fd, buffer, offset, length, position, callback)
6311
+ }
6312
+ callback_.apply(this, arguments)
6313
+ }
6314
+ }
6315
+ return fs$read.call(fs, fd, buffer, offset, length, position, callback)
6316
+ }
6317
+
6318
+ // This ensures `util.promisify` works as it does for native `fs.read`.
6319
+ if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read)
6320
+ return read
6321
+ })(fs.read)
6322
+
6323
+ fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync
6324
+ : (function (fs$readSync) { return function (fd, buffer, offset, length, position) {
6325
+ var eagCounter = 0
6326
+ while (true) {
6327
+ try {
6328
+ return fs$readSync.call(fs, fd, buffer, offset, length, position)
6329
+ } catch (er) {
6330
+ if (er.code === 'EAGAIN' && eagCounter < 10) {
6331
+ eagCounter ++
6332
+ continue
6333
+ }
6334
+ throw er
6335
+ }
6336
+ }
6337
+ }})(fs.readSync)
6338
+
6339
+ function patchLchmod (fs) {
6340
+ fs.lchmod = function (path, mode, callback) {
6341
+ fs.open( path
6342
+ , constants.O_WRONLY | constants.O_SYMLINK
6343
+ , mode
6344
+ , function (err, fd) {
6345
+ if (err) {
6346
+ if (callback) callback(err)
6347
+ return
6348
+ }
6349
+ // prefer to return the chmod error, if one occurs,
6350
+ // but still try to close, and report closing errors if they occur.
6351
+ fs.fchmod(fd, mode, function (err) {
6352
+ fs.close(fd, function(err2) {
6353
+ if (callback) callback(err || err2)
6354
+ })
6355
+ })
6356
+ })
6357
+ }
6358
+
6359
+ fs.lchmodSync = function (path, mode) {
6360
+ var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
6361
+
6362
+ // prefer to return the chmod error, if one occurs,
6363
+ // but still try to close, and report closing errors if they occur.
6364
+ var threw = true
6365
+ var ret
6366
+ try {
6367
+ ret = fs.fchmodSync(fd, mode)
6368
+ threw = false
6369
+ } finally {
6370
+ if (threw) {
6371
+ try {
6372
+ fs.closeSync(fd)
6373
+ } catch (er) {}
6374
+ } else {
6375
+ fs.closeSync(fd)
6376
+ }
6377
+ }
6378
+ return ret
6379
+ }
6380
+ }
6381
+
6382
+ function patchLutimes (fs) {
6383
+ if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) {
6384
+ fs.lutimes = function (path, at, mt, cb) {
6385
+ fs.open(path, constants.O_SYMLINK, function (er, fd) {
6386
+ if (er) {
6387
+ if (cb) cb(er)
6388
+ return
6389
+ }
6390
+ fs.futimes(fd, at, mt, function (er) {
6391
+ fs.close(fd, function (er2) {
6392
+ if (cb) cb(er || er2)
6393
+ })
6394
+ })
6395
+ })
6396
+ }
6397
+
6398
+ fs.lutimesSync = function (path, at, mt) {
6399
+ var fd = fs.openSync(path, constants.O_SYMLINK)
6400
+ var ret
6401
+ var threw = true
6402
+ try {
6403
+ ret = fs.futimesSync(fd, at, mt)
6404
+ threw = false
6405
+ } finally {
6406
+ if (threw) {
6407
+ try {
6408
+ fs.closeSync(fd)
6409
+ } catch (er) {}
6410
+ } else {
6411
+ fs.closeSync(fd)
6412
+ }
6413
+ }
6414
+ return ret
6415
+ }
6416
+
6417
+ } else if (fs.futimes) {
6418
+ fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) }
6419
+ fs.lutimesSync = function () {}
6420
+ }
6421
+ }
6422
+
6423
+ function chmodFix (orig) {
6424
+ if (!orig) return orig
6425
+ return function (target, mode, cb) {
6426
+ return orig.call(fs, target, mode, function (er) {
6427
+ if (chownErOk(er)) er = null
6428
+ if (cb) cb.apply(this, arguments)
6429
+ })
6430
+ }
6431
+ }
6432
+
6433
+ function chmodFixSync (orig) {
6434
+ if (!orig) return orig
6435
+ return function (target, mode) {
6436
+ try {
6437
+ return orig.call(fs, target, mode)
6438
+ } catch (er) {
6439
+ if (!chownErOk(er)) throw er
6440
+ }
6441
+ }
6442
+ }
6443
+
6444
+
6445
+ function chownFix (orig) {
6446
+ if (!orig) return orig
6447
+ return function (target, uid, gid, cb) {
6448
+ return orig.call(fs, target, uid, gid, function (er) {
6449
+ if (chownErOk(er)) er = null
6450
+ if (cb) cb.apply(this, arguments)
6451
+ })
6452
+ }
6453
+ }
6454
+
6455
+ function chownFixSync (orig) {
6456
+ if (!orig) return orig
6457
+ return function (target, uid, gid) {
6458
+ try {
6459
+ return orig.call(fs, target, uid, gid)
6460
+ } catch (er) {
6461
+ if (!chownErOk(er)) throw er
6462
+ }
6463
+ }
6464
+ }
6465
+
6466
+ function statFix (orig) {
6467
+ if (!orig) return orig
6468
+ // Older versions of Node erroneously returned signed integers for
6469
+ // uid + gid.
6470
+ return function (target, options, cb) {
6471
+ if (typeof options === 'function') {
6472
+ cb = options
6473
+ options = null
6474
+ }
6475
+ function callback (er, stats) {
6476
+ if (stats) {
6477
+ if (stats.uid < 0) stats.uid += 0x100000000
6478
+ if (stats.gid < 0) stats.gid += 0x100000000
6479
+ }
6480
+ if (cb) cb.apply(this, arguments)
6481
+ }
6482
+ return options ? orig.call(fs, target, options, callback)
6483
+ : orig.call(fs, target, callback)
6484
+ }
6485
+ }
6486
+
6487
+ function statFixSync (orig) {
6488
+ if (!orig) return orig
6489
+ // Older versions of Node erroneously returned signed integers for
6490
+ // uid + gid.
6491
+ return function (target, options) {
6492
+ var stats = options ? orig.call(fs, target, options)
6493
+ : orig.call(fs, target)
6494
+ if (stats) {
6495
+ if (stats.uid < 0) stats.uid += 0x100000000
6496
+ if (stats.gid < 0) stats.gid += 0x100000000
6497
+ }
6498
+ return stats;
6499
+ }
6500
+ }
6501
+
6502
+ // ENOSYS means that the fs doesn't support the op. Just ignore
6503
+ // that, because it doesn't matter.
6504
+ //
6505
+ // if there's no getuid, or if getuid() is something other
6506
+ // than 0, and the error is EINVAL or EPERM, then just ignore
6507
+ // it.
6508
+ //
6509
+ // This specific case is a silent failure in cp, install, tar,
6510
+ // and most other unix tools that manage permissions.
6511
+ //
6512
+ // When running as root, or if other types of errors are
6513
+ // encountered, then it's strict.
6514
+ function chownErOk (er) {
6515
+ if (!er)
6516
+ return true
6517
+
6518
+ if (er.code === "ENOSYS")
6519
+ return true
6520
+
6521
+ var nonroot = !process.getuid || process.getuid() !== 0
6522
+ if (nonroot) {
6523
+ if (er.code === "EINVAL" || er.code === "EPERM")
6524
+ return true
6525
+ }
6526
+
6527
+ return false
6528
+ }
6529
+ }
6530
+
6531
+
5559
6532
  /***/ }),
5560
6533
 
5561
6534
  /***/ 8675:
@@ -8709,7 +9682,7 @@ function sync (path, options) {
8709
9682
 
8710
9683
  var _fs
8711
9684
  try {
8712
- _fs = __webpack_require__(1317)
9685
+ _fs = __webpack_require__(7156)
8713
9686
  } catch (_) {
8714
9687
  _fs = __webpack_require__(5747)
8715
9688
  }
@@ -22636,7 +23609,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22636
23609
  return (mod && mod.__esModule) ? mod : { "default": mod };
22637
23610
  };
22638
23611
  Object.defineProperty(exports, "__esModule", ({ value: true }));
22639
- exports.createGo = exports.getAnalyzedEntrypoint = exports.OUT_EXTENSION = exports.goGlobalCachePath = exports.cacheDir = void 0;
23612
+ exports.createGo = exports.GoWrapper = exports.getAnalyzedEntrypoint = exports.OUT_EXTENSION = exports.goGlobalCachePath = exports.localCacheDir = void 0;
22640
23613
  const tar_1 = __importDefault(__webpack_require__(6758));
22641
23614
  const execa_1 = __importDefault(__webpack_require__(389));
22642
23615
  const node_fetch_1 = __importDefault(__webpack_require__(779));
@@ -22651,7 +23624,7 @@ const yauzl_promise_1 = __importDefault(__webpack_require__(7542));
22651
23624
  const xdg_app_paths_1 = __importDefault(__webpack_require__(4925));
22652
23625
  const streamPipeline = util_1.promisify(stream_1.pipeline);
22653
23626
  const versionMap = new Map([
22654
- ['1.20', '1.20.1'],
23627
+ ['1.20', '1.20.2'],
22655
23628
  ['1.19', '1.19.6'],
22656
23629
  ['1.18', '1.18.10'],
22657
23630
  ['1.17', '1.17.13'],
@@ -22665,16 +23638,26 @@ const archMap = new Map([
22665
23638
  ['x86', '386'],
22666
23639
  ]);
22667
23640
  const platformMap = new Map([['win32', 'windows']]);
22668
- exports.cacheDir = path_1.join('.vercel', 'cache', 'golang');
23641
+ exports.localCacheDir = path_1.join('.vercel', 'cache', 'golang');
22669
23642
  const GO_FLAGS = process.platform === 'win32' ? [] : ['-ldflags', '-s -w'];
22670
23643
  const GO_MIN_VERSION = 13;
22671
- const getPlatform = (p) => platformMap.get(p) || p;
22672
- const getArch = (a) => archMap.get(a) || a;
23644
+ /**
23645
+ * Determines the URL to download the Golang SDK.
23646
+ * @param version The desireed Go version
23647
+ * @returns The Go download URL
23648
+ */
22673
23649
  function getGoUrl(version) {
22674
23650
  const { arch, platform } = process;
22675
- const goArch = getArch(arch);
22676
- const goPlatform = getPlatform(platform);
22677
23651
  const ext = platform === 'win32' ? 'zip' : 'tar.gz';
23652
+ const goPlatform = platformMap.get(platform) || platform;
23653
+ let goArch = archMap.get(arch) || arch;
23654
+ // Go 1.16 was the first version to support arm64, so if the version is older
23655
+ // we need to download the amd64 version
23656
+ if (platform === 'darwin' &&
23657
+ goArch === 'arm64' &&
23658
+ parseInt(version.split('.')[1], 10) < 16) {
23659
+ goArch = 'amd64';
23660
+ }
22678
23661
  const filename = `go${version}.${goPlatform}-${goArch}.${ext}`;
22679
23662
  return {
22680
23663
  filename,
@@ -22683,23 +23666,69 @@ function getGoUrl(version) {
22683
23666
  }
22684
23667
  exports.goGlobalCachePath = path_1.join(xdg_app_paths_1.default('com.vercel.cli').cache(), 'golang');
22685
23668
  exports.OUT_EXTENSION = process.platform === 'win32' ? '.exe' : '';
22686
- async function getAnalyzedEntrypoint(workPath, filePath, modulePath) {
23669
+ /**
23670
+ * Parses the AST of the specified entrypoint Go file.
23671
+ * @param workPath The work path (e.g. `/path/to/project`)
23672
+ * @param entrypoint The path to the entrypoint file (e.g.
23673
+ * `/path/to/project/api/index.go`)
23674
+ * @param modulePath The path to the directory containing the `go.mod` (e.g.
23675
+ * `/path/to/project/api`)
23676
+ * @returns The results from the AST parsing
23677
+ */
23678
+ async function getAnalyzedEntrypoint({ entrypoint, modulePath, workPath, }) {
22687
23679
  const bin = path_1.join(__dirname, `analyze${exports.OUT_EXTENSION}`);
22688
- const isAnalyzeExist = await fs_extra_1.pathExists(bin);
22689
- if (!isAnalyzeExist) {
22690
- build_utils_1.debug(`Building analyze bin: ${bin}`);
22691
- const src = __webpack_require__.ab + "analyze.go";
22692
- const go = await createGo({
22693
- modulePath,
22694
- workPath,
22695
- });
22696
- await go.build(__webpack_require__.ab + "analyze.go", bin);
23680
+ let analyzed;
23681
+ try {
23682
+ // build the `analyze` binary if not found in the `dist` directory
23683
+ const isAnalyzeExist = await fs_extra_1.pathExists(bin);
23684
+ if (!isAnalyzeExist) {
23685
+ build_utils_1.debug(`Building analyze bin: ${bin}`);
23686
+ const src = __webpack_require__.ab + "analyze.go";
23687
+ let go;
23688
+ const createOpts = {
23689
+ modulePath,
23690
+ opts: { cwd: __dirname },
23691
+ workPath,
23692
+ };
23693
+ try {
23694
+ go = await createGo(createOpts);
23695
+ }
23696
+ catch (err) {
23697
+ // if the version in the `go.mod` is too old, then download the latest
23698
+ if (err instanceof GoError &&
23699
+ err.code === 'ERR_UNSUPPORTED_GO_VERSION') {
23700
+ delete createOpts.modulePath;
23701
+ go = await createGo(createOpts);
23702
+ }
23703
+ else {
23704
+ throw err;
23705
+ }
23706
+ }
23707
+ await go.build(__webpack_require__.ab + "analyze.go", bin);
23708
+ }
23709
+ }
23710
+ catch (err) {
23711
+ console.error('Failed to build the Go AST analyzer');
23712
+ throw err;
23713
+ }
23714
+ try {
23715
+ build_utils_1.debug(`Analyzing entrypoint ${entrypoint} with modulePath ${modulePath}`);
23716
+ const args = [`-modpath=${modulePath}`, path_1.join(workPath, entrypoint)];
23717
+ analyzed = await execa_1.default.stdout(bin, args);
23718
+ }
23719
+ catch (err) {
23720
+ console.error(`Failed to parse AST for "${entrypoint}"`);
23721
+ throw err;
22697
23722
  }
22698
- build_utils_1.debug(`Analyzing entrypoint ${filePath} with modulePath ${modulePath}`);
22699
- const args = [`-modpath=${modulePath}`, filePath];
22700
- const analyzed = await execa_1.default.stdout(bin, args);
22701
23723
  build_utils_1.debug(`Analyzed entrypoint ${analyzed}`);
22702
- return analyzed;
23724
+ if (!analyzed) {
23725
+ const err = new Error(`Could not find an exported function in "${entrypoint}"
23726
+ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
23727
+ `);
23728
+ console.error(err.message);
23729
+ throw err;
23730
+ }
23731
+ return JSON.parse(analyzed);
22703
23732
  }
22704
23733
  exports.getAnalyzedEntrypoint = getAnalyzedEntrypoint;
22705
23734
  class GoWrapper {
@@ -22712,9 +23741,10 @@ class GoWrapper {
22712
23741
  }
22713
23742
  execute(...args) {
22714
23743
  const { opts, env } = this;
22715
- build_utils_1.debug(`Exec: go ${args
22716
- .map(a => (a.includes(' ') ? `"${a}"` : a))
22717
- .join(' ')} CWD=${opts.cwd}`);
23744
+ build_utils_1.debug(`Exec: go ${args.map(a => (a.includes(' ') ? `"${a}"` : a)).join(' ')}`);
23745
+ build_utils_1.debug(` CWD=${opts.cwd}`);
23746
+ build_utils_1.debug(` GOROOT=${(env || opts.env).GOROOT}`);
23747
+ build_utils_1.debug(` GO_BUILD_FLAGS=${(env || opts.env).GO_BUILD_FLAGS}`);
22718
23748
  return execa_1.default('go', args, { stdio: 'inherit', ...opts, env });
22719
23749
  }
22720
23750
  mod() {
@@ -22734,12 +23764,12 @@ class GoWrapper {
22734
23764
  build(src, dest) {
22735
23765
  build_utils_1.debug(`Building optimized 'go' binary ${src} -> ${dest}`);
22736
23766
  const sources = Array.isArray(src) ? src : [src];
22737
- const flags = process.env.GO_BUILD_FLAGS
22738
- ? string_argv_1.default(process.env.GO_BUILD_FLAGS)
22739
- : GO_FLAGS;
23767
+ const envGoBuildFlags = (this.env || this.opts.env).GO_BUILD_FLAGS;
23768
+ const flags = envGoBuildFlags ? string_argv_1.default(envGoBuildFlags) : GO_FLAGS;
22740
23769
  return this.execute('build', ...flags, '-o', dest, ...sources);
22741
23770
  }
22742
23771
  }
23772
+ exports.GoWrapper = GoWrapper;
22743
23773
  /**
22744
23774
  * Initializes a `GoWrapper` instance.
22745
23775
  *
@@ -22775,7 +23805,7 @@ async function createGo({ modulePath, opts = {}, workPath, }) {
22775
23805
  const { PATH } = env;
22776
23806
  const { platform } = process;
22777
23807
  const goGlobalCacheDir = path_1.join(exports.goGlobalCachePath, `${goSelectedVersion}_${platform}_${process.arch}`);
22778
- const goCacheDir = path_1.join(workPath, exports.cacheDir);
23808
+ const goCacheDir = path_1.join(workPath, exports.localCacheDir);
22779
23809
  if (goPreferredVersion) {
22780
23810
  build_utils_1.debug(`Preferred go version ${goPreferredVersion} (from go.mod)`);
22781
23811
  env.GO111MODULE = 'on';
@@ -22815,7 +23845,7 @@ async function createGo({ modulePath, opts = {}, workPath, }) {
22815
23845
  build_utils_1.debug(`Found go ${version} in ${label}, but version is unsupported`);
22816
23846
  }
22817
23847
  if (version === goSelectedVersion || short === goSelectedVersion) {
22818
- console.log(`Selected go ${version} (from ${label})`);
23848
+ build_utils_1.debug(`Selected go ${version} (from ${label})`);
22819
23849
  await setGoEnv(goDir);
22820
23850
  return new GoWrapper(env, opts);
22821
23851
  }
@@ -22910,6 +23940,8 @@ function parseGoVersionString(goVersionOutput) {
22910
23940
  patch,
22911
23941
  };
22912
23942
  }
23943
+ class GoError extends Error {
23944
+ }
22913
23945
  /**
22914
23946
  * Attempts to parse the preferred Go version from the `go.mod` file.
22915
23947
  *
@@ -22928,6 +23960,11 @@ async function parseGoModVersion(modulePath) {
22928
23960
  if (major === 1 && minor >= GO_MIN_VERSION && full) {
22929
23961
  version = full;
22930
23962
  }
23963
+ else if (!isNaN(minor)) {
23964
+ const err = new GoError(`Unsupported Go version ${major}.${minor} in ${file}`);
23965
+ err.code = 'ERR_UNSUPPORTED_GO_VERSION';
23966
+ throw err;
23967
+ }
22931
23968
  else {
22932
23969
  console.log(`Warning: Unknown Go version in ${file}`);
22933
23970
  }
@@ -22967,7 +24004,10 @@ const build_utils_1 = __webpack_require__(3445);
22967
24004
  Object.defineProperty(exports, "shouldServe", ({ enumerable: true, get: function () { return build_utils_1.shouldServe; } }));
22968
24005
  const TMP = os_1.tmpdir();
22969
24006
  const go_helpers_1 = __webpack_require__(3097);
22970
- const handlerFileName = `handler${go_helpers_1.OUT_EXTENSION}`;
24007
+ // in order to allow the user to have `main.go`,
24008
+ // we need our `main.go` to be called something else
24009
+ const MAIN_GO_FILENAME = 'main__vc__go__.go';
24010
+ const HANDLER_FILENAME = `handler${go_helpers_1.OUT_EXTENSION}`;
22971
24011
  // Initialize private git repo for Go Modules
22972
24012
  async function initPrivateGit(credentials) {
22973
24013
  const gitCredentialsPath = path_1.join(os_1.homedir(), '.git-credentials');
@@ -23004,15 +24044,21 @@ async function build({ files, entrypoint, config, workPath, meta = {}, }) {
23004
24044
  // keep track of file system actions we need to undo
23005
24045
  // the keys "from" and "to" refer to what needs to be done
23006
24046
  // in order to undo the action, not what the original action was
23007
- const undoFileActions = [];
23008
- const undoDirectoryCreation = [];
23009
- const undoFunctionRenames = [];
24047
+ const undo = {
24048
+ fileActions: [],
24049
+ directoryCreation: [],
24050
+ functionRenames: [],
24051
+ };
24052
+ const env = build_utils_1.cloneEnv(process.env, meta.env, {
24053
+ GOARCH: 'amd64',
24054
+ GOOS: 'linux',
24055
+ });
23010
24056
  try {
23011
- if (process.env.GIT_CREDENTIALS) {
24057
+ if (env.GIT_CREDENTIALS) {
23012
24058
  build_utils_1.debug('Initialize Git credentials...');
23013
- await initPrivateGit(process.env.GIT_CREDENTIALS);
24059
+ await initPrivateGit(env.GIT_CREDENTIALS);
23014
24060
  }
23015
- if (process.env.GO111MODULE) {
24061
+ if (env.GO111MODULE) {
23016
24062
  console.log(`\nManually assigning 'GO111MODULE' is not recommended.
23017
24063
 
23018
24064
  By default:
@@ -23027,290 +24073,82 @@ async function build({ files, entrypoint, config, workPath, meta = {}, }) {
23027
24073
  const renamedEntrypoint = getRenamedEntrypoint(entrypoint);
23028
24074
  if (renamedEntrypoint) {
23029
24075
  await fs_extra_1.move(path_1.join(workPath, entrypoint), path_1.join(workPath, renamedEntrypoint));
23030
- undoFileActions.push({
24076
+ undo.fileActions.push({
23031
24077
  to: path_1.join(workPath, entrypoint),
23032
24078
  from: path_1.join(workPath, renamedEntrypoint),
23033
24079
  });
23034
24080
  entrypoint = renamedEntrypoint;
23035
24081
  }
23036
24082
  const entrypointAbsolute = path_1.join(workPath, entrypoint);
23037
- const entrypointArr = entrypoint.split(path_1.posix.sep);
23038
- build_utils_1.debug(`Parsing AST for "${entrypoint}"`);
23039
- let analyzed;
23040
- try {
23041
- const goModAbsPath = await findGoModPath(workPath);
23042
- if (goModAbsPath) {
23043
- build_utils_1.debug(`Found ${goModAbsPath}"`);
23044
- }
23045
- analyzed = await go_helpers_1.getAnalyzedEntrypoint(workPath, entrypointAbsolute, path_1.dirname(goModAbsPath));
23046
- }
23047
- catch (err) {
23048
- console.error(`Failed to parse AST for "${entrypoint}"`);
23049
- throw err;
23050
- }
23051
- if (!analyzed) {
23052
- const err = new Error(`Could not find an exported function in "${entrypoint}"
23053
- Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
23054
- `);
23055
- console.error(err.message);
23056
- throw err;
23057
- }
23058
- const parsedAnalyzed = JSON.parse(analyzed);
23059
- // find `go.mod` in modFiles
23060
24083
  const entrypointDirname = path_1.dirname(entrypointAbsolute);
23061
- let isGoModExist = false;
23062
- let goModPath = '';
23063
- let isGoModInRootDir = false;
23064
- const modFileRefs = await build_utils_1.glob('**/*.mod', workPath);
23065
- const modFiles = Object.keys(modFileRefs);
23066
- for (const file of modFiles) {
23067
- const fileDirname = path_1.dirname(file);
23068
- if (file === 'go.mod') {
23069
- isGoModExist = true;
23070
- isGoModInRootDir = true;
23071
- goModPath = path_1.join(workPath, fileDirname);
23072
- }
23073
- else if (file.endsWith('go.mod')) {
23074
- if (entrypointDirname === fileDirname) {
23075
- isGoModExist = true;
23076
- goModPath = path_1.join(workPath, fileDirname);
23077
- build_utils_1.debug(`Found file dirname equals entrypoint dirname: ${fileDirname}`);
23078
- break;
23079
- }
23080
- if (!isGoModInRootDir && config.zeroConfig && file === 'api/go.mod') {
23081
- // We didn't find `/go.mod` but we found `/api/go.mod` so move it to the root
23082
- isGoModExist = true;
23083
- isGoModInRootDir = true;
23084
- goModPath = path_1.join(fileDirname, '..');
23085
- const pathParts = file.split(path_1.sep);
23086
- pathParts.pop(); // Remove go.mod
23087
- pathParts.pop(); // Remove api
23088
- pathParts.push('go.mod');
23089
- const newRoot = pathParts.join(path_1.sep);
23090
- const newFsPath = path_1.join(workPath, newRoot);
23091
- build_utils_1.debug(`Moving api/go.mod to root: ${file} to ${newFsPath}`);
23092
- await fs_extra_1.move(file, newFsPath);
23093
- undoFileActions.push({
23094
- to: file,
23095
- from: newFsPath,
23096
- });
23097
- const oldSumPath = path_1.join(path_1.dirname(file), 'go.sum');
23098
- const newSumPath = path_1.join(path_1.dirname(newFsPath), 'go.sum');
23099
- if (await fs_extra_1.pathExists(oldSumPath)) {
23100
- build_utils_1.debug(`Moving api/go.sum to root: ${oldSumPath} to ${newSumPath}`);
23101
- await fs_extra_1.move(oldSumPath, newSumPath);
23102
- undoFileActions.push({
23103
- to: oldSumPath,
23104
- from: newSumPath,
23105
- });
23106
- }
23107
- break;
23108
- }
23109
- }
24084
+ const { goModPath, isGoModInRootDir } = await findGoModPath(entrypointDirname, workPath);
24085
+ if (!goModPath && (await fs_extra_1.pathExists(path_1.join(workPath, 'vendor')))) {
24086
+ throw new Error('`go.mod` is required to use a `vendor` directory.');
24087
+ }
24088
+ const analyzed = await go_helpers_1.getAnalyzedEntrypoint({
24089
+ entrypoint,
24090
+ modulePath: goModPath ? path_1.dirname(goModPath) : undefined,
24091
+ workPath,
24092
+ });
24093
+ // check if package name other than main
24094
+ // using `go.mod` way building the handler
24095
+ const packageName = analyzed.packageName;
24096
+ if (goModPath && packageName === 'main') {
24097
+ throw new Error('Please change `package main` to `package handler`');
23110
24098
  }
23111
- const input = entrypointDirname;
24099
+ // rename the Go handler function name in the original entrypoint file
24100
+ const originalFunctionName = analyzed.functionName;
24101
+ const handlerFunctionName = getNewHandlerFunctionName(originalFunctionName, entrypoint);
24102
+ await renameHandlerFunction(entrypointAbsolute, originalFunctionName, handlerFunctionName);
24103
+ undo.functionRenames.push({
24104
+ fsPath: originalEntrypointAbsolute,
24105
+ from: handlerFunctionName,
24106
+ to: originalFunctionName,
24107
+ });
23112
24108
  const includedFiles = {};
23113
24109
  if (config && config.includeFiles) {
23114
24110
  const patterns = Array.isArray(config.includeFiles)
23115
24111
  ? config.includeFiles
23116
24112
  : [config.includeFiles];
23117
24113
  for (const pattern of patterns) {
23118
- const fsFiles = await build_utils_1.glob(pattern, input);
24114
+ const fsFiles = await build_utils_1.glob(pattern, entrypointDirname);
23119
24115
  for (const [assetName, asset] of Object.entries(fsFiles)) {
23120
24116
  includedFiles[assetName] = asset;
23121
24117
  }
23122
24118
  }
23123
24119
  }
23124
- const originalFunctionName = parsedAnalyzed.functionName;
23125
- const handlerFunctionName = getNewHandlerFunctionName(originalFunctionName, entrypoint);
23126
- await renameHandlerFunction(entrypointAbsolute, originalFunctionName, handlerFunctionName);
23127
- undoFunctionRenames.push({
23128
- fsPath: originalEntrypointAbsolute,
23129
- from: handlerFunctionName,
23130
- to: originalFunctionName,
23131
- });
23132
- if (!isGoModExist) {
23133
- if (await fs_extra_1.pathExists(path_1.join(workPath, 'vendor'))) {
23134
- throw new Error('`go.mod` is required to use a `vendor` directory.');
23135
- }
23136
- }
23137
- // check if package name other than main
23138
- // using `go.mod` way building the handler
23139
- const packageName = parsedAnalyzed.packageName;
23140
- if (isGoModExist && packageName === 'main') {
23141
- throw new Error('Please change `package main` to `package handler`');
23142
- }
23143
- const outDir = await build_utils_1.getWriteableDirectory();
23144
- // in order to allow the user to have `main.go`,
23145
- // we need our `main.go` to be called something else
23146
- const mainGoFileName = 'main__vc__go__.go';
24120
+ const modulePath = goModPath ? path_1.dirname(goModPath) : undefined;
23147
24121
  const go = await go_helpers_1.createGo({
23148
- modulePath: goModPath,
24122
+ modulePath,
23149
24123
  opts: {
23150
24124
  cwd: entrypointDirname,
23151
- env: {
23152
- GOARCH: 'amd64',
23153
- GOOS: 'linux',
23154
- },
24125
+ env,
23155
24126
  },
23156
24127
  workPath,
23157
24128
  });
23158
- if (packageName !== 'main') {
23159
- if (!isGoModExist) {
23160
- try {
23161
- const defaultGoModContent = `module ${packageName}`;
23162
- await fs_extra_1.writeFile(path_1.join(entrypointDirname, 'go.mod'), defaultGoModContent);
23163
- undoFileActions.push({
23164
- to: undefined,
23165
- from: path_1.join(entrypointDirname, 'go.mod'),
23166
- });
23167
- // remove the `go.sum` file that will be generated as well
23168
- undoFileActions.push({
23169
- to: undefined,
23170
- from: path_1.join(entrypointDirname, 'go.sum'),
23171
- });
23172
- }
23173
- catch (err) {
23174
- console.error(`Failed to create default go.mod for ${packageName}`);
23175
- throw err;
23176
- }
23177
- }
23178
- const modMainGoContents = await fs_extra_1.readFile(__webpack_require__.ab + "main.go", 'utf8');
23179
- let goPackageName = `${packageName}/${packageName}`;
23180
- const goFuncName = `${packageName}.${handlerFunctionName}`;
23181
- if (isGoModExist) {
23182
- const goModContents = await fs_extra_1.readFile(path_1.join(goModPath, 'go.mod'), 'utf8');
23183
- const usrModName = goModContents.split('\n')[0].split(' ')[1];
23184
- if (entrypointArr.length > 1 && isGoModInRootDir) {
23185
- const cleanPackagePath = [...entrypointArr];
23186
- cleanPackagePath.pop();
23187
- goPackageName = `${usrModName}/${cleanPackagePath.join('/')}`;
23188
- }
23189
- else {
23190
- goPackageName = `${usrModName}/${packageName}`;
23191
- }
23192
- }
23193
- const mainModGoContents = modMainGoContents
23194
- .replace('__VC_HANDLER_PACKAGE_NAME', goPackageName)
23195
- .replace('__VC_HANDLER_FUNC_NAME', goFuncName);
23196
- if (isGoModExist && isGoModInRootDir) {
23197
- build_utils_1.debug('[mod-root] Write main file to ' + downloadPath);
23198
- await fs_extra_1.writeFile(path_1.join(downloadPath, mainGoFileName), mainModGoContents);
23199
- undoFileActions.push({
23200
- to: undefined,
23201
- from: path_1.join(downloadPath, mainGoFileName),
23202
- });
23203
- }
23204
- else if (isGoModExist && !isGoModInRootDir) {
23205
- build_utils_1.debug('[mod-other] Write main file to ' + goModPath);
23206
- await fs_extra_1.writeFile(path_1.join(goModPath, mainGoFileName), mainModGoContents);
23207
- undoFileActions.push({
23208
- to: undefined,
23209
- from: path_1.join(goModPath, mainGoFileName),
23210
- });
23211
- }
23212
- else {
23213
- build_utils_1.debug('[entrypoint] Write main file to ' + entrypointDirname);
23214
- await fs_extra_1.writeFile(path_1.join(entrypointDirname, mainGoFileName), mainModGoContents);
23215
- undoFileActions.push({
23216
- to: undefined,
23217
- from: path_1.join(entrypointDirname, mainGoFileName),
23218
- });
23219
- }
23220
- // move user go file to folder
23221
- try {
23222
- // default path
23223
- let finalDestination = path_1.join(entrypointDirname, packageName, entrypoint);
23224
- // if `entrypoint` include folder, only use filename
23225
- if (entrypointArr.length > 1) {
23226
- finalDestination = path_1.join(entrypointDirname, packageName, entrypointArr[entrypointArr.length - 1]);
23227
- }
23228
- if (path_1.dirname(entrypointAbsolute) === goModPath || !isGoModExist) {
23229
- build_utils_1.debug(`moving entrypoint "${entrypointAbsolute}" to "${finalDestination}"`);
23230
- await fs_extra_1.move(entrypointAbsolute, finalDestination);
23231
- undoFileActions.push({
23232
- to: entrypointAbsolute,
23233
- from: finalDestination,
23234
- });
23235
- undoDirectoryCreation.push(path_1.dirname(finalDestination));
23236
- }
23237
- }
23238
- catch (err) {
23239
- console.error('Failed to move entry to package folder');
23240
- throw err;
23241
- }
23242
- let baseGoModPath = '';
23243
- if (isGoModExist && isGoModInRootDir) {
23244
- baseGoModPath = downloadPath;
23245
- }
23246
- else if (isGoModExist && !isGoModInRootDir) {
23247
- baseGoModPath = goModPath;
23248
- }
23249
- else {
23250
- baseGoModPath = entrypointDirname;
23251
- }
23252
- build_utils_1.debug('Tidy `go.mod` file...');
23253
- try {
23254
- // ensure go.mod up-to-date
23255
- await go.mod();
23256
- }
23257
- catch (err) {
23258
- console.error('failed to `go mod tidy`');
23259
- throw err;
23260
- }
23261
- build_utils_1.debug('Running `go build`...');
23262
- const destPath = path_1.join(outDir, handlerFileName);
23263
- try {
23264
- const src = [path_1.join(baseGoModPath, mainGoFileName)];
23265
- await go.build(src, destPath);
23266
- }
23267
- catch (err) {
23268
- console.error('failed to `go build`');
23269
- throw err;
23270
- }
24129
+ const outDir = await build_utils_1.getWriteableDirectory();
24130
+ const buildOptions = {
24131
+ downloadPath,
24132
+ entrypoint,
24133
+ entrypointAbsolute,
24134
+ entrypointDirname,
24135
+ go,
24136
+ goModPath,
24137
+ handlerFunctionName,
24138
+ isGoModInRootDir,
24139
+ outDir,
24140
+ packageName,
24141
+ undo,
24142
+ };
24143
+ if (packageName === 'main') {
24144
+ await buildHandlerAsPackageMain(buildOptions);
23271
24145
  }
23272
24146
  else {
23273
- // legacy mode
23274
- // we need `main.go` in the same dir as the entrypoint,
23275
- // otherwise `go build` will refuse to build
23276
- const originalMainGoContents = await fs_extra_1.readFile(__webpack_require__.ab + "main.go", 'utf8');
23277
- const mainGoContents = originalMainGoContents
23278
- .replace('"__VC_HANDLER_PACKAGE_NAME"', '')
23279
- .replace('__VC_HANDLER_FUNC_NAME', handlerFunctionName);
23280
- // Go doesn't like to build files in different directories,
23281
- // so now we place `main.go` together with the user code
23282
- await fs_extra_1.writeFile(path_1.join(entrypointDirname, mainGoFileName), mainGoContents);
23283
- undoFileActions.push({
23284
- to: undefined,
23285
- from: path_1.join(entrypointDirname, mainGoFileName),
23286
- });
23287
- // `go get` will look at `*.go` (note we set `cwd`), parse the `import`s
23288
- // and download any packages that aren't part of the stdlib
23289
- build_utils_1.debug('Running `go get`...');
23290
- try {
23291
- await go.get();
23292
- }
23293
- catch (err) {
23294
- console.error('Failed to `go get`');
23295
- throw err;
23296
- }
23297
- build_utils_1.debug('Running `go build`...');
23298
- const destPath = path_1.join(outDir, handlerFileName);
23299
- try {
23300
- const src = [
23301
- path_1.join(entrypointDirname, mainGoFileName),
23302
- entrypointAbsolute,
23303
- ].map(file => path_1.normalize(file));
23304
- await go.build(src, destPath);
23305
- }
23306
- catch (err) {
23307
- console.error('failed to `go build`');
23308
- throw err;
23309
- }
24147
+ await buildHandlerWithGoMod(buildOptions);
23310
24148
  }
23311
- const lambda = await build_utils_1.createLambda({
24149
+ const lambda = new build_utils_1.Lambda({
23312
24150
  files: { ...(await build_utils_1.glob('**', outDir)), ...includedFiles },
23313
- handler: handlerFileName,
24151
+ handler: HANDLER_FILENAME,
23314
24152
  runtime: 'go1.x',
23315
24153
  supportsWrapper: true,
23316
24154
  environment: {},
@@ -23320,12 +24158,12 @@ async function build({ files, entrypoint, config, workPath, meta = {}, }) {
23320
24158
  };
23321
24159
  }
23322
24160
  catch (error) {
23323
- build_utils_1.debug('Go Builder Error: ' + error);
24161
+ build_utils_1.debug(`Go Builder Error: ${error}`);
23324
24162
  throw error;
23325
24163
  }
23326
24164
  finally {
23327
24165
  try {
23328
- await cleanupFileSystem(undoFileActions, undoDirectoryCreation, undoFunctionRenames);
24166
+ await cleanupFileSystem(undo);
23329
24167
  }
23330
24168
  catch (error) {
23331
24169
  if (error instanceof Error) {
@@ -23336,6 +24174,156 @@ async function build({ files, entrypoint, config, workPath, meta = {}, }) {
23336
24174
  }
23337
24175
  }
23338
24176
  exports.build = build;
24177
+ /**
24178
+ * Build the Go function where the package name is not `"main"`. If a `go.mod`
24179
+ * does not exist, a default one will be used.
24180
+ */
24181
+ async function buildHandlerWithGoMod({ downloadPath, entrypoint, entrypointAbsolute, entrypointDirname, go, goModPath, handlerFunctionName, isGoModInRootDir, outDir, packageName, undo, }) {
24182
+ build_utils_1.debug(`Building Go handler as package "${packageName}" (with${goModPath ? '' : 'out'} go.mod)`);
24183
+ let goModDirname;
24184
+ if (goModPath !== undefined) {
24185
+ goModDirname = path_1.dirname(goModPath);
24186
+ // first we backup the original
24187
+ const backupFile = path_1.join(goModDirname, `__vc_go.mod.bak`);
24188
+ await fs_extra_1.copy(goModPath, backupFile);
24189
+ undo.fileActions.push({
24190
+ to: goModPath,
24191
+ from: backupFile,
24192
+ });
24193
+ const goSumPath = path_1.join(goModDirname, 'go.sum');
24194
+ const isGoSumExists = await fs_extra_1.pathExists(goSumPath);
24195
+ if (!isGoSumExists) {
24196
+ // remove the `go.sum` file that will be generated as well
24197
+ undo.fileActions.push({
24198
+ to: undefined,
24199
+ from: goSumPath,
24200
+ });
24201
+ }
24202
+ }
24203
+ const entrypointArr = entrypoint.split(path_1.posix.sep);
24204
+ let goPackageName = `${packageName}/${packageName}`;
24205
+ const goFuncName = `${packageName}.${handlerFunctionName}`;
24206
+ // if we have a go.mod, determine the relative path of the entrypoint to the
24207
+ // go.mod directory and use that for the import package name in main.go
24208
+ const relPackagePath = goModDirname
24209
+ ? path_1.posix.relative(goModDirname, entrypointDirname)
24210
+ : '';
24211
+ if (relPackagePath) {
24212
+ goPackageName = path_1.posix.join(packageName, relPackagePath);
24213
+ }
24214
+ let mainGoFile;
24215
+ if (goModPath && isGoModInRootDir) {
24216
+ build_utils_1.debug(`[mod-root] Write main file to ${downloadPath}`);
24217
+ mainGoFile = path_1.join(downloadPath, MAIN_GO_FILENAME);
24218
+ }
24219
+ else if (goModDirname && !isGoModInRootDir) {
24220
+ build_utils_1.debug(`[mod-other] Write main file to ${goModDirname}`);
24221
+ mainGoFile = path_1.join(goModDirname, MAIN_GO_FILENAME);
24222
+ }
24223
+ else {
24224
+ build_utils_1.debug(`[entrypoint] Write main file to ${entrypointDirname}`);
24225
+ mainGoFile = path_1.join(entrypointDirname, MAIN_GO_FILENAME);
24226
+ }
24227
+ await Promise.all([
24228
+ writeEntrypoint(mainGoFile, goPackageName, goFuncName),
24229
+ writeGoMod({
24230
+ destDir: goModDirname ? goModDirname : entrypointDirname,
24231
+ goModPath,
24232
+ packageName,
24233
+ }),
24234
+ ]);
24235
+ undo.fileActions.push({
24236
+ to: undefined,
24237
+ from: mainGoFile,
24238
+ });
24239
+ // move user go file to folder
24240
+ try {
24241
+ // default path
24242
+ let finalDestination = path_1.join(entrypointDirname, packageName, entrypoint);
24243
+ // if `entrypoint` include folder, only use filename
24244
+ if (entrypointArr.length > 1) {
24245
+ finalDestination = path_1.join(entrypointDirname, packageName, entrypointArr[entrypointArr.length - 1]);
24246
+ }
24247
+ if (!goModPath || path_1.dirname(entrypointAbsolute) === path_1.dirname(goModPath)) {
24248
+ build_utils_1.debug(`moving entrypoint "${entrypointAbsolute}" to "${finalDestination}"`);
24249
+ await fs_extra_1.move(entrypointAbsolute, finalDestination);
24250
+ undo.fileActions.push({
24251
+ to: entrypointAbsolute,
24252
+ from: finalDestination,
24253
+ });
24254
+ undo.directoryCreation.push(path_1.dirname(finalDestination));
24255
+ }
24256
+ }
24257
+ catch (err) {
24258
+ console.error('Failed to move entry to package folder');
24259
+ throw err;
24260
+ }
24261
+ let baseGoModPath = '';
24262
+ if (goModPath && isGoModInRootDir) {
24263
+ baseGoModPath = downloadPath;
24264
+ }
24265
+ else if (goModPath && !isGoModInRootDir) {
24266
+ baseGoModPath = path_1.dirname(goModPath);
24267
+ }
24268
+ else {
24269
+ baseGoModPath = entrypointDirname;
24270
+ }
24271
+ build_utils_1.debug('Tidy `go.mod` file...');
24272
+ try {
24273
+ // ensure go.mod up-to-date
24274
+ await go.mod();
24275
+ }
24276
+ catch (err) {
24277
+ console.error('failed to `go mod tidy`');
24278
+ throw err;
24279
+ }
24280
+ build_utils_1.debug('Running `go build`...');
24281
+ const destPath = path_1.join(outDir, HANDLER_FILENAME);
24282
+ try {
24283
+ const src = [path_1.join(baseGoModPath, MAIN_GO_FILENAME)];
24284
+ await go.build(src, destPath);
24285
+ }
24286
+ catch (err) {
24287
+ console.error('failed to `go build`');
24288
+ throw err;
24289
+ }
24290
+ }
24291
+ /**
24292
+ * Builds the wrapped Go function using the legacy mode where package name is
24293
+ * `"main"` and we need `main.go` in the same dir as the entrypoint, otherwise
24294
+ * `go build` will refuse to build.
24295
+ */
24296
+ async function buildHandlerAsPackageMain({ entrypointAbsolute, entrypointDirname, go, handlerFunctionName, outDir, undo, }) {
24297
+ build_utils_1.debug('Building Go handler as package "main" (legacy)');
24298
+ await writeEntrypoint(path_1.join(entrypointDirname, MAIN_GO_FILENAME), '', handlerFunctionName);
24299
+ undo.fileActions.push({
24300
+ to: undefined,
24301
+ from: path_1.join(entrypointDirname, MAIN_GO_FILENAME),
24302
+ });
24303
+ // `go get` will look at `*.go` (note we set `cwd`), parse the `import`s
24304
+ // and download any packages that aren't part of the stdlib
24305
+ build_utils_1.debug('Running `go get`...');
24306
+ try {
24307
+ await go.get();
24308
+ }
24309
+ catch (err) {
24310
+ console.error('Failed to `go get`');
24311
+ throw err;
24312
+ }
24313
+ build_utils_1.debug('Running `go build`...');
24314
+ const destPath = path_1.join(outDir, HANDLER_FILENAME);
24315
+ try {
24316
+ const src = [
24317
+ path_1.join(entrypointDirname, MAIN_GO_FILENAME),
24318
+ entrypointAbsolute,
24319
+ ].map(file => path_1.normalize(file));
24320
+ await go.build(src, destPath);
24321
+ }
24322
+ catch (err) {
24323
+ console.error('failed to `go build`');
24324
+ throw err;
24325
+ }
24326
+ }
23339
24327
  async function renameHandlerFunction(fsPath, from, to) {
23340
24328
  let fileContents = await fs_extra_1.readFile(fsPath, 'utf8');
23341
24329
  // This regex has to walk a fine line where it replaces the most-likely occurrences
@@ -23362,13 +24350,16 @@ function getNewHandlerFunctionName(originalFunctionName, entrypoint) {
23362
24350
  return newHandlerName;
23363
24351
  }
23364
24352
  exports.getNewHandlerFunctionName = getNewHandlerFunctionName;
23365
- async function cleanupFileSystem(undoFileActions, undoDirectoryCreation, undoFunctionRenames) {
24353
+ /**
24354
+ * Remove any temporary files, directories, and file changes.
24355
+ */
24356
+ async function cleanupFileSystem({ fileActions, directoryCreation, functionRenames, }) {
23366
24357
  // we have to undo the actions in reverse order in cases
23367
24358
  // where one file was moved multiple times, which happens
23368
24359
  // using files that start with brackets
23369
- for (const action of undoFileActions.reverse()) {
24360
+ for (const action of fileActions.reverse()) {
23370
24361
  if (action.to) {
23371
- await fs_extra_1.move(action.from, action.to);
24362
+ await fs_extra_1.move(action.from, action.to, { overwrite: true });
23372
24363
  }
23373
24364
  else {
23374
24365
  await fs_extra_1.remove(action.from);
@@ -23376,10 +24367,10 @@ async function cleanupFileSystem(undoFileActions, undoDirectoryCreation, undoFun
23376
24367
  }
23377
24368
  // after files are moved back, we can undo function renames
23378
24369
  // these reference the original file location
23379
- for (const rename of undoFunctionRenames) {
24370
+ for (const rename of functionRenames) {
23380
24371
  await renameHandlerFunction(rename.fsPath, rename.from, rename.to);
23381
24372
  }
23382
- const undoDirectoryPromises = undoDirectoryCreation.map(async (directory) => {
24373
+ const undoDirectoryPromises = directoryCreation.map(async (directory) => {
23383
24374
  const contents = await fs_extra_1.readdir(directory);
23384
24375
  // only delete an empty directory
23385
24376
  // if it has contents, either something went wrong during cleanup or this
@@ -23391,16 +24382,32 @@ async function cleanupFileSystem(undoFileActions, undoDirectoryCreation, undoFun
23391
24382
  });
23392
24383
  await Promise.all(undoDirectoryPromises);
23393
24384
  }
23394
- async function findGoModPath(workPath) {
23395
- let checkPath = path_1.join(workPath, 'go.mod');
23396
- if (await fs_extra_1.pathExists(checkPath)) {
23397
- return checkPath;
23398
- }
23399
- checkPath = path_1.join(workPath, 'api/go.mod');
23400
- if (await fs_extra_1.pathExists(checkPath)) {
23401
- return checkPath;
24385
+ /**
24386
+ * Attempts to find a `go.mod` starting in the entrypoint directory and
24387
+ * scanning up the directory tree.
24388
+ * @param entrypointDir The entrypoint directory (e.g. `/path/to/project/api`)
24389
+ * @param workPath The work path (e.g. `/path/to/project`)
24390
+ * @returns The absolute path to the `go.mod` and a flag if the `go.mod` is in
24391
+ * the work path root
24392
+ */
24393
+ async function findGoModPath(entrypointDir, workPath) {
24394
+ let goModPath = undefined;
24395
+ let isGoModInRootDir = false;
24396
+ let dir = entrypointDir;
24397
+ while (!isGoModInRootDir) {
24398
+ isGoModInRootDir = dir === workPath;
24399
+ const goMod = path_1.join(dir, 'go.mod');
24400
+ if (await fs_extra_1.pathExists(goMod)) {
24401
+ goModPath = goMod;
24402
+ build_utils_1.debug(`Found ${goModPath}"`);
24403
+ break;
24404
+ }
24405
+ dir = path_1.dirname(dir);
23402
24406
  }
23403
- return '';
24407
+ return {
24408
+ goModPath,
24409
+ isGoModInRootDir,
24410
+ };
23404
24411
  }
23405
24412
  function isPortInfo(v) {
23406
24413
  return v && typeof v.port === 'number';
@@ -23420,9 +24427,126 @@ async function copyDevServer(functionName, dest) {
23420
24427
  const patched = data.replace('__HANDLER_FUNC_NAME', functionName);
23421
24428
  await fs_extra_1.writeFile(path_1.join(dest, 'vercel-dev-server-main.go'), patched);
23422
24429
  }
23423
- async function writeDefaultGoMod(entrypointDirname, packageName) {
23424
- const defaultGoModContent = `module ${packageName}`;
23425
- await fs_extra_1.writeFile(path_1.join(entrypointDirname, 'go.mod'), defaultGoModContent, 'utf-8');
24430
+ async function writeEntrypoint(dest, goPackageName, goFuncName) {
24431
+ const modMainGoContents = await fs_extra_1.readFile(__webpack_require__.ab + "main.go", 'utf8');
24432
+ const mainModGoContents = modMainGoContents
24433
+ .replace('__VC_HANDLER_PACKAGE_NAME', goPackageName)
24434
+ .replace('__VC_HANDLER_FUNC_NAME', goFuncName);
24435
+ await fs_extra_1.writeFile(dest, mainModGoContents, 'utf-8');
24436
+ }
24437
+ /**
24438
+ * Writes a `go.mod` file in the specified directory. If a `go.mod` file
24439
+ * exists, then update the module name and any relative `replace` statements,
24440
+ * otherwise write the minimum module name.
24441
+ * @param workPath The work path; required if `goModPath` exists
24442
+ * @param goModPath The path to the `go.mod`, or `undefined` if not found
24443
+ * @param destDir The directory to write the `go.mod` to
24444
+ * @param packageName The module name to inject into the `go.mod`
24445
+ */
24446
+ async function writeGoMod({ destDir, goModPath, packageName, }) {
24447
+ let contents = `module ${packageName}`;
24448
+ if (goModPath) {
24449
+ const goModRelPath = path_1.relative(destDir, path_1.dirname(goModPath));
24450
+ const goModContents = await fs_extra_1.readFile(goModPath, 'utf-8');
24451
+ contents = goModContents
24452
+ .replace(/^module\s+.+$/m, contents)
24453
+ .replace(/^(replace .+=>\s*)(.+)$/gm, (orig, replaceStmt, replacePath) => {
24454
+ if (replacePath.startsWith('.')) {
24455
+ return replaceStmt + path_1.join(goModRelPath, replacePath);
24456
+ }
24457
+ return orig;
24458
+ });
24459
+ // get the module name, then add the 'replace' mapping if it doesn't
24460
+ // already exist
24461
+ const matches = goModContents.match(/module\s+(.+)/);
24462
+ const moduleName = matches ? matches[1] : null;
24463
+ if (moduleName) {
24464
+ let relPath = path_1.normalize(goModRelPath);
24465
+ if (!relPath.endsWith('/')) {
24466
+ relPath += '/';
24467
+ }
24468
+ const requireRE = new RegExp(`require\\s+${moduleName}`);
24469
+ const requireGroupRE = new RegExp(`require\\s*\\(.*${moduleName}.*\\)`, 's');
24470
+ if (!requireRE.test(contents) && !requireGroupRE.test(contents)) {
24471
+ contents += `require ${moduleName} v0.0.0-unpublished\n`;
24472
+ }
24473
+ const replaceRE = new RegExp(`replace.+=>\\s+${relPath}(\\s|$)`);
24474
+ if (!replaceRE.test(contents)) {
24475
+ contents += `replace ${moduleName} => ${relPath}\n`;
24476
+ }
24477
+ }
24478
+ }
24479
+ const destGoModPath = path_1.join(destDir, 'go.mod');
24480
+ build_utils_1.debug(`Writing ${destGoModPath}`);
24481
+ // console.log(contents);
24482
+ await fs_extra_1.writeFile(destGoModPath, contents, 'utf-8');
24483
+ }
24484
+ /**
24485
+ * Attempts to find the `go.work` file. It will stop once it hits the
24486
+ * `workPath`.
24487
+ * @param goWorkDir The directory under the `wordPath` to start searching.
24488
+ * @param workPath The project root to stop looking for the file.
24489
+ * @returns The path to the `go.work` file or `undefined`.
24490
+ */
24491
+ async function findGoWorkFile(goWorkDir, workPath) {
24492
+ while (!(await fs_extra_1.pathExists(path_1.join(goWorkDir, 'go.work')))) {
24493
+ if (goWorkDir === workPath) {
24494
+ return;
24495
+ }
24496
+ goWorkDir = path_1.dirname(goWorkDir);
24497
+ }
24498
+ return path_1.join(goWorkDir, 'go.work');
24499
+ }
24500
+ /**
24501
+ * For simple cases, a `go.work` file is not required. However when a Go
24502
+ * program requires source files outside the work path, we need a `go.work` so
24503
+ * Go can find the root of the project being built.
24504
+ * @param destDir The destination directory to write the `go.work` file.
24505
+ * @param workPath The path to the work directory.
24506
+ * @param modulePath The path to the directory containing the `go.mod`.
24507
+ */
24508
+ async function writeGoWork(destDir, workPath, modulePath) {
24509
+ const workspaces = new Set(['.']);
24510
+ const goWorkPath = await findGoWorkFile(modulePath || workPath, workPath);
24511
+ if (goWorkPath) {
24512
+ const contents = await fs_extra_1.readFile(goWorkPath, 'utf-8');
24513
+ const addPath = (path) => {
24514
+ if (path) {
24515
+ if (path.startsWith('.')) {
24516
+ workspaces.add(path_1.relative(destDir, path_1.join(workPath, path)));
24517
+ }
24518
+ else {
24519
+ workspaces.add(path);
24520
+ }
24521
+ }
24522
+ };
24523
+ // find grouped paths
24524
+ const multiRE = /use\s*\(([^)]+)/g;
24525
+ let match = multiRE.exec(contents);
24526
+ while (match) {
24527
+ if (match[1]) {
24528
+ for (const line of match[1].split(/\r?\n/)) {
24529
+ addPath(line.trim());
24530
+ }
24531
+ }
24532
+ match = multiRE.exec(contents);
24533
+ }
24534
+ // find single paths
24535
+ const singleRE = /use\s+(?!\()(.+)/g;
24536
+ match = singleRE.exec(contents);
24537
+ while (match) {
24538
+ addPath(match[1].trim());
24539
+ match = singleRE.exec(contents);
24540
+ }
24541
+ }
24542
+ else if (modulePath) {
24543
+ workspaces.add(path_1.relative(destDir, modulePath));
24544
+ }
24545
+ const contents = `use (\n${Array.from(workspaces)
24546
+ .map(w => ` ${w}\n`)
24547
+ .join('')})\n`;
24548
+ // console.log(contents);
24549
+ await fs_extra_1.writeFile(path_1.join(destDir, 'go.work'), contents, 'utf-8');
23426
24550
  }
23427
24551
  async function startDevServer(opts) {
23428
24552
  const { entrypoint, workPath, meta = {} } = opts;
@@ -23437,20 +24561,22 @@ async function startDevServer(opts) {
23437
24561
  const tmp = path_1.join(devCacheDir, 'go', Math.random().toString(32).substring(2));
23438
24562
  const tmpPackage = path_1.join(tmp, entrypointDir);
23439
24563
  await fs_extra_1.mkdirp(tmpPackage);
23440
- let goModAbsPathDir = '';
23441
- if (await fs_extra_1.pathExists(path_1.join(workPath, 'go.mod'))) {
23442
- goModAbsPathDir = workPath;
23443
- }
23444
- const analyzedRaw = await go_helpers_1.getAnalyzedEntrypoint(workPath, entrypointWithExt, goModAbsPathDir);
23445
- if (!analyzedRaw) {
23446
- throw new Error(`Could not find an exported function in "${entrypointWithExt}"
23447
- Learn more: https://vercel.com/docs/runtimes#official-runtimes/go`);
23448
- }
23449
- const analyzed = JSON.parse(analyzedRaw);
24564
+ const { goModPath } = await findGoModPath(path_1.join(workPath, entrypointDir), workPath);
24565
+ const modulePath = goModPath ? path_1.dirname(goModPath) : undefined;
24566
+ const analyzed = await go_helpers_1.getAnalyzedEntrypoint({
24567
+ entrypoint: entrypointWithExt,
24568
+ modulePath,
24569
+ workPath,
24570
+ });
23450
24571
  await Promise.all([
23451
24572
  copyEntrypoint(entrypointWithExt, tmpPackage),
23452
24573
  copyDevServer(analyzed.functionName, tmpPackage),
23453
- goModAbsPathDir ? null : writeDefaultGoMod(tmp, analyzed.packageName),
24574
+ writeGoMod({
24575
+ destDir: tmp,
24576
+ goModPath,
24577
+ packageName: analyzed.packageName,
24578
+ }),
24579
+ writeGoWork(tmp, workPath, modulePath),
23454
24580
  ]);
23455
24581
  const portFile = path_1.join(TMP, `vercel-dev-port-${Math.random().toString(32).substring(2)}`);
23456
24582
  const env = build_utils_1.cloneEnv(process.env, meta.env, {
@@ -23462,7 +24588,7 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go`);
23462
24588
  // more info.
23463
24589
  // build the dev server
23464
24590
  const go = await go_helpers_1.createGo({
23465
- modulePath: goModAbsPathDir,
24591
+ modulePath,
23466
24592
  opts: {
23467
24593
  cwd: tmp,
23468
24594
  env,
@@ -23554,7 +24680,7 @@ async function prepareCache({ workPath, }) {
23554
24680
  //
23555
24681
  // On the next build, the local cache will be restored and `createGo()` will
23556
24682
  // use it unless the preferred Go version changed in the `go.mod`.
23557
- const goCacheDir = path_1.join(workPath, go_helpers_1.cacheDir);
24683
+ const goCacheDir = path_1.join(workPath, go_helpers_1.localCacheDir);
23558
24684
  const stat = await fs_extra_1.lstat(goCacheDir);
23559
24685
  if (stat.isSymbolicLink()) {
23560
24686
  const goGlobalCacheDir = await fs_extra_1.readlink(goCacheDir);
@@ -23562,7 +24688,7 @@ async function prepareCache({ workPath, }) {
23562
24688
  await fs_extra_1.unlink(goCacheDir);
23563
24689
  await fs_extra_1.move(goGlobalCacheDir, goCacheDir);
23564
24690
  }
23565
- const cache = await build_utils_1.glob(`${go_helpers_1.cacheDir}/**`, workPath);
24691
+ const cache = await build_utils_1.glob(`${go_helpers_1.localCacheDir}/**`, workPath);
23566
24692
  return cache;
23567
24693
  }
23568
24694
  exports.prepareCache = prepareCache;