permaweb-deploy 2.1.0 → 2.3.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/.eslintrc.js +1 -1
- package/README.md +103 -22
- package/dist/index.js +75 -51
- package/dist/turbo/index.js +141 -138
- package/package.json +3 -3
- package/src/index.js +60 -33
- package/src/turbo/index.js +41 -32
package/.eslintrc.js
CHANGED
|
@@ -22,7 +22,7 @@ module.exports = {
|
|
|
22
22
|
{
|
|
23
23
|
groups: [
|
|
24
24
|
['^react', '^@?\\w'],
|
|
25
|
-
['^arweave', '@
|
|
25
|
+
['^arweave', '@ar.io/sdk', '@ardrive/turbo-sdk', '@permaweb/aoconnect', '^@?\\w'],
|
|
26
26
|
['^\\u0000'],
|
|
27
27
|
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
|
|
28
28
|
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
|
package/README.md
CHANGED
|
@@ -1,28 +1,68 @@
|
|
|
1
|
-
# Permaweb
|
|
1
|
+
# Permaweb Deployment Package
|
|
2
2
|
|
|
3
|
-
Inspired by the [cookbook github action deployment guide](https://cookbook.arweave.dev/guides/deployment/github-action.html), `permaweb-deploy` is a Node.js command-line tool designed to streamline the deployment of
|
|
3
|
+
Inspired by the [cookbook github action deployment guide](https://cookbook.arweave.dev/guides/deployment/github-action.html), `permaweb-deploy` is a Node.js command-line tool designed to streamline the deployment of web applications to the permaweb using Arweave. It simplifies the process by uploading your build folder, creating Arweave manifests, and updating ArNS (Arweave Name Service) records via ANT (Arweave Name Token) with the transaction ID.
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
-
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
6
|
+
|
|
7
|
+
- **Turbo SDK Integration:** Uses Turbo SDK for fast, reliable file uploads to Arweave
|
|
8
|
+
- **Arweave Manifest v0.2.0:** Creates manifests with fallback support for SPAs
|
|
9
|
+
- **ArNS Updates:** Updates ArNS records via ANT with new transaction IDs and metadata
|
|
10
|
+
- **Automated Workflow:** Integrates with GitHub Actions for continuous deployment
|
|
11
|
+
- **Git Hash Tagging:** Automatically tags deployments with Git commit hashes
|
|
12
|
+
- **404 Fallback Detection:** Automatically detects and sets 404.html as fallback
|
|
13
|
+
- **Network Support:** Supports mainnet, testnet, and custom ARIO process IDs
|
|
9
14
|
|
|
10
15
|
### Installation
|
|
16
|
+
|
|
11
17
|
Install the package using npm:
|
|
18
|
+
|
|
12
19
|
```bash
|
|
13
20
|
npm install permaweb-deploy
|
|
14
21
|
```
|
|
15
22
|
|
|
23
|
+
For development use:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install permaweb-deploy --save-dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For Yarn users:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn add permaweb-deploy --dev --ignore-engines
|
|
33
|
+
```
|
|
34
|
+
|
|
16
35
|
### Prerequisites
|
|
36
|
+
|
|
17
37
|
Before using `permaweb-deploy`, you must:
|
|
18
|
-
1. Encode your Arweave wallet key in base64 format and set it as a GitHub secret:
|
|
19
38
|
|
|
39
|
+
1. **Arweave Wallet:** Have an Arweave wallet with Turbo Credits for uploading
|
|
40
|
+
2. **ArNS Name:** Own or control an ArNS name (which has an associated ANT process)
|
|
41
|
+
3. **Wallet Encoding:** Encode your Arweave wallet key in base64 format:
|
|
20
42
|
```bash
|
|
21
43
|
base64 -i wallet.json | pbcopy
|
|
22
44
|
```
|
|
23
|
-
|
|
45
|
+
4. **GitHub Secret:** Set the encoded wallet as a GitHub secret named `DEPLOY_KEY`
|
|
46
|
+
|
|
47
|
+
⚠️ **Important:** Use a dedicated wallet for deployments to minimize security risks. Ensure your wallet has sufficient Turbo Credits for uploads.
|
|
48
|
+
|
|
49
|
+
### CLI Options
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
permaweb-deploy [options]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Option | Alias | Description | Default | Required |
|
|
56
|
+
| ----------------- | ----- | -------------------------------------- | --------- | -------- |
|
|
57
|
+
| `--arns-name` | `-n` | ArNS name for deployment | - | ✅ |
|
|
58
|
+
| `--ario-process` | `-p` | ARIO process ID or "mainnet"/"testnet" | `mainnet` | ❌ |
|
|
59
|
+
| `--deploy-folder` | `-d` | Folder to deploy | `./dist` | ❌ |
|
|
60
|
+
| `--deploy-file` | `-f` | File to deploy | `./dist` | ❌ |
|
|
61
|
+
| `--undername` | `-u` | ANT undername to update | `@` | ❌ |
|
|
62
|
+
| `--ttl-seconds` | `-t` | ArNS TTL Seconds | `3600` | ❌ |
|
|
24
63
|
|
|
25
64
|
### Usage
|
|
65
|
+
|
|
26
66
|
To deploy your application, ensure you have a build script and a deployment script in your `package.json`:
|
|
27
67
|
|
|
28
68
|
```json
|
|
@@ -32,11 +72,16 @@ To deploy your application, ensure you have a build script and a deployment scri
|
|
|
32
72
|
}
|
|
33
73
|
```
|
|
34
74
|
|
|
35
|
-
|
|
75
|
+
**Example with custom options:**
|
|
36
76
|
|
|
37
|
-
|
|
77
|
+
```bash
|
|
78
|
+
permaweb-deploy --arns-name "your-arns-name" --deploy-folder "./build" --undername "app"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Replace `<ARNS_NAME>` with your ArNS name. You can also specify testnet, mainnet, and custom process IDs for the ARIO process to use.
|
|
82
|
+
|
|
83
|
+
**Mainnet (default) config:**
|
|
38
84
|
|
|
39
|
-
Maninnet (default) config:
|
|
40
85
|
```json
|
|
41
86
|
"scripts": {
|
|
42
87
|
"build": "your-build-command",
|
|
@@ -44,7 +89,8 @@ Maninnet (default) config:
|
|
|
44
89
|
}
|
|
45
90
|
```
|
|
46
91
|
|
|
47
|
-
Testnet config
|
|
92
|
+
**Testnet config:**
|
|
93
|
+
|
|
48
94
|
```json
|
|
49
95
|
"scripts": {
|
|
50
96
|
"build": "your-build-command",
|
|
@@ -52,7 +98,8 @@ Testnet config:
|
|
|
52
98
|
}
|
|
53
99
|
```
|
|
54
100
|
|
|
55
|
-
Custom process ID config
|
|
101
|
+
**Custom process ID config:**
|
|
102
|
+
|
|
56
103
|
```json
|
|
57
104
|
"scripts": {
|
|
58
105
|
"build": "your-build-command",
|
|
@@ -60,8 +107,26 @@ Custom process ID config:
|
|
|
60
107
|
}
|
|
61
108
|
```
|
|
62
109
|
|
|
110
|
+
### Manual CLI Deployment
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
DEPLOY_KEY=$(base64 -i wallet.json) npx permaweb-deploy --arns-name <ARNS_NAME>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Technical Details
|
|
117
|
+
|
|
118
|
+
- **Upload Service:** Uses Turbo SDK for fast, reliable file uploads to Arweave
|
|
119
|
+
- **Manifest Format:** Creates Arweave manifests using version 0.2.0 specification
|
|
120
|
+
- **Fallback Support:** Automatically detects `404.html` and sets it as fallback, otherwise uses `index.html`
|
|
121
|
+
- **Upload Timeout:** 10-second timeout per file upload for reliability
|
|
122
|
+
- **ArNS Record TTL:** Sets 3600 seconds (1 hour) TTL for ArNS records via ANT
|
|
123
|
+
- **Deployment Tags:** Automatically adds `App-Name: Permaweb-Deploy` and Git hash tags
|
|
124
|
+
- **Network Support:** Supports mainnet, testnet, and custom ARIO process IDs
|
|
125
|
+
|
|
63
126
|
### GitHub Actions Workflow
|
|
127
|
+
|
|
64
128
|
To automate the deployment, set up a GitHub Actions workflow as follows:
|
|
129
|
+
|
|
65
130
|
```yaml
|
|
66
131
|
name: publish
|
|
67
132
|
|
|
@@ -74,8 +139,8 @@ jobs:
|
|
|
74
139
|
publish:
|
|
75
140
|
runs-on: ubuntu-latest
|
|
76
141
|
steps:
|
|
77
|
-
- uses: actions/checkout@
|
|
78
|
-
- uses: actions/setup-node@
|
|
142
|
+
- uses: actions/checkout@v4
|
|
143
|
+
- uses: actions/setup-node@v4
|
|
79
144
|
with:
|
|
80
145
|
node-version: 20.x
|
|
81
146
|
- run: npm install
|
|
@@ -84,13 +149,29 @@ jobs:
|
|
|
84
149
|
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
|
|
85
150
|
```
|
|
86
151
|
|
|
87
|
-
###
|
|
152
|
+
### Security & Best Practices
|
|
88
153
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
154
|
+
- **Dedicated Wallet:** Always use a dedicated wallet for deployments to minimize security risks
|
|
155
|
+
- **Wallet Encoding:** The wallet must be base64 encoded to be used in the deployment script
|
|
156
|
+
- **ArNS Name:** The ArNS Name must be passed so that the ANT Process can be resolved to update the target undername or root record
|
|
157
|
+
- **Turbo Credits:** Ensure your wallet has sufficient Turbo Credits before deployment
|
|
158
|
+
- **Secret Management:** Keep your `DEPLOY_KEY` secret secure and never commit it to your repository
|
|
159
|
+
- **Build Security:** Always check your build for exposed environmental secrets before deployment, as data on Arweave is permanent
|
|
160
|
+
|
|
161
|
+
### Troubleshooting
|
|
162
|
+
|
|
163
|
+
- **Error: "ARNS_NAME not configured":** Ensure you're passing the `--arns-name` flag with a valid ArNS name
|
|
164
|
+
- **Error: "DEPLOY_KEY not configured":** Verify your base64 encoded wallet is set as the `DEPLOY_KEY` environment variable
|
|
165
|
+
- **Error: "deploy-folder does not exist":** Check that your build folder exists and the path is correct
|
|
166
|
+
- **Error: "deploy-file does not exist":** Check that your build file exists and the path is correct
|
|
167
|
+
- **Error: "ARNS name does not exist":** Verify the ArNS name is correct and exists in the specified network
|
|
168
|
+
- **Upload timeouts:** Files have a 10-second upload timeout. Large files may fail and require optimization
|
|
169
|
+
- **Insufficient Turbo Credits:** Ensure your wallet has enough Turbo Credits for the deployment
|
|
170
|
+
|
|
171
|
+
### Dependencies
|
|
92
172
|
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
- **
|
|
173
|
+
- **@ar.io/sdk:** - For ANT operations and ArNS management
|
|
174
|
+
- **@ardrive/turbo-sdk:** - For fast file uploads to Arweave
|
|
175
|
+
- **@permaweb/aoconnect:** - For AO network connectivity
|
|
176
|
+
- **mime-types:** - For automatic content type detection
|
|
177
|
+
- **yargs:** - For CLI argument parsing
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
5
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6
|
-
value: true
|
|
7
|
-
});
|
|
8
|
-
exports.getTagValue = getTagValue;
|
|
9
|
-
var _sdk = require("@ar.io/sdk");
|
|
10
4
|
var _fs = _interopRequireDefault(require("fs"));
|
|
11
5
|
var _yargs = _interopRequireDefault(require("yargs"));
|
|
12
6
|
var _helpers = require("yargs/helpers");
|
|
7
|
+
var _sdk = require("@ar.io/sdk");
|
|
8
|
+
var _turboSdk = require("@ardrive/turbo-sdk");
|
|
13
9
|
var _aoconnect = require("@permaweb/aoconnect");
|
|
14
|
-
var _turbo =
|
|
10
|
+
var _turbo = require("./turbo");
|
|
15
11
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
16
|
-
function
|
|
12
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
13
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { if (r) i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n;else { var o = function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); }; o("next", 0), o("throw", 1), o("return", 2); } }, _regeneratorDefine2(e, r, n, t); }
|
|
17
14
|
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
18
15
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
19
16
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
@@ -39,6 +36,15 @@ var argv = (0, _yargs["default"])((0, _helpers.hideBin)(process.argv)).option('a
|
|
|
39
36
|
type: 'string',
|
|
40
37
|
description: 'Folder to deploy.',
|
|
41
38
|
"default": './dist'
|
|
39
|
+
}).option('deploy-file', {
|
|
40
|
+
alias: 'f',
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'File to deploy.'
|
|
43
|
+
}).option('ttl-seconds', {
|
|
44
|
+
alias: 't',
|
|
45
|
+
type: 'number',
|
|
46
|
+
description: 'ArNS TTL Seconds',
|
|
47
|
+
"default": 3600
|
|
42
48
|
}).option('undername', {
|
|
43
49
|
alias: 'u',
|
|
44
50
|
type: 'string',
|
|
@@ -47,26 +53,17 @@ var argv = (0, _yargs["default"])((0, _helpers.hideBin)(process.argv)).option('a
|
|
|
47
53
|
}).argv;
|
|
48
54
|
var DEPLOY_KEY = process.env.DEPLOY_KEY;
|
|
49
55
|
var ARNS_NAME = argv.arnsName;
|
|
56
|
+
var TTL_SECONDS = argv.ttlSeconds;
|
|
50
57
|
var ARIO_PROCESS = argv.arioProcess;
|
|
51
58
|
if (ARIO_PROCESS === 'mainnet') {
|
|
52
59
|
ARIO_PROCESS = _sdk.ARIO_MAINNET_PROCESS_ID;
|
|
53
60
|
} else if (ARIO_PROCESS === 'testnet') {
|
|
54
61
|
ARIO_PROCESS = _sdk.ARIO_TESTNET_PROCESS_ID;
|
|
55
62
|
}
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return list[i].value;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return STORAGE.none;
|
|
65
|
-
}
|
|
66
|
-
_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
67
|
-
var jwk, ario, arnsNameRecord, manifestId, signer, ant;
|
|
68
|
-
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
69
|
-
while (1) switch (_context.prev = _context.next) {
|
|
63
|
+
_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
64
|
+
var jwk, ario, arnsNameRecord, txId, turbo, signer, ant, _t;
|
|
65
|
+
return _regenerator().w(function (_context) {
|
|
66
|
+
while (1) switch (_context.n) {
|
|
70
67
|
case 0:
|
|
71
68
|
if (!ARIO_PROCESS || !arweaveTxIdRegex.test(ARIO_PROCESS)) {
|
|
72
69
|
console.error('ARIO_PROCESS must be a valid Arweave transaction ID, or "mainnet" or "testnet"');
|
|
@@ -80,16 +77,21 @@ _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
|
80
77
|
console.error('ARNS_NAME not configured');
|
|
81
78
|
process.exit(1);
|
|
82
79
|
}
|
|
83
|
-
if (
|
|
84
|
-
console.error('
|
|
80
|
+
if (!Number.isFinite(TTL_SECONDS) || TTL_SECONDS < 60 || TTL_SECONDS > 86400) {
|
|
81
|
+
console.error('TTL_SECONDS must be a number between 60 and 86400 seconds');
|
|
85
82
|
process.exit(1);
|
|
86
83
|
}
|
|
87
|
-
if (argv.
|
|
88
|
-
console.error(
|
|
84
|
+
if (argv.deployFile && !_fs["default"].existsSync(argv.deployFile)) {
|
|
85
|
+
console.error("deploy-file [".concat(argv.deployFolder, "] does not exist"));
|
|
89
86
|
process.exit(1);
|
|
87
|
+
} else {
|
|
88
|
+
if (!_fs["default"].existsSync(argv.deployFolder)) {
|
|
89
|
+
console.error("deploy-folder [".concat(argv.deployFolder, "] does not exist"));
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
90
92
|
}
|
|
91
|
-
if (
|
|
92
|
-
console.error(
|
|
93
|
+
if (argv.undername.length === 0) {
|
|
94
|
+
console.error('undername must be set');
|
|
93
95
|
process.exit(1);
|
|
94
96
|
}
|
|
95
97
|
jwk = JSON.parse(Buffer.from(DEPLOY_KEY, 'base64').toString('utf-8'));
|
|
@@ -98,34 +100,57 @@ _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
|
98
100
|
processId: ARIO_PROCESS,
|
|
99
101
|
ao: (0, _aoconnect.connect)({
|
|
100
102
|
MODE: 'legacy',
|
|
101
|
-
CU_URL:
|
|
103
|
+
CU_URL: 'https://cu.ardrive.io'
|
|
102
104
|
})
|
|
103
105
|
})
|
|
104
106
|
});
|
|
105
|
-
_context.
|
|
107
|
+
_context.n = 1;
|
|
106
108
|
return ario.getArNSRecord({
|
|
107
109
|
name: ARNS_NAME
|
|
108
110
|
})["catch"](function (e) {
|
|
109
111
|
console.error("ARNS name [".concat(ARNS_NAME, "] does not exist"));
|
|
110
112
|
process.exit(1);
|
|
111
113
|
});
|
|
112
|
-
case
|
|
113
|
-
arnsNameRecord = _context.
|
|
114
|
-
_context.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
case 1:
|
|
115
|
+
arnsNameRecord = _context.v;
|
|
116
|
+
_context.p = 2;
|
|
117
|
+
if (!argv.deployFile) {
|
|
118
|
+
_context.n = 4;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
turbo = _turboSdk.TurboFactory.authenticated({
|
|
122
|
+
privateKey: jwk
|
|
123
|
+
});
|
|
124
|
+
_context.n = 3;
|
|
125
|
+
return (0, _turbo.uploadFile)(argv.deployFile, turbo);
|
|
126
|
+
case 3:
|
|
127
|
+
txId = _context.v.id;
|
|
128
|
+
_context.n = 6;
|
|
129
|
+
break;
|
|
130
|
+
case 4:
|
|
131
|
+
_context.n = 5;
|
|
132
|
+
return (0, _turbo.uploadDirectory)(argv, jwk);
|
|
133
|
+
case 5:
|
|
134
|
+
txId = _context.v;
|
|
135
|
+
case 6:
|
|
136
|
+
console.log('-------------------- DEPLOY DETAILS --------------------');
|
|
137
|
+
console.log("Tx ID: ".concat(txId));
|
|
138
|
+
console.log("ArNS Name: ".concat(ARNS_NAME));
|
|
139
|
+
console.log("Undername: ".concat(argv.undername));
|
|
140
|
+
console.log("ANT: ".concat(arnsNameRecord.processId));
|
|
141
|
+
console.log("AR IO Process: ".concat(ARIO_PROCESS));
|
|
142
|
+
console.log("TTL Seconds: ".concat(TTL_SECONDS));
|
|
143
|
+
console.log('--------------------------------------------------------');
|
|
119
144
|
signer = new _sdk.ArweaveSigner(jwk);
|
|
120
145
|
ant = _sdk.ANT.init({
|
|
121
146
|
processId: arnsNameRecord.processId,
|
|
122
147
|
signer: signer
|
|
123
148
|
}); // Update the ANT record (assumes the JWK is a controller or owner)
|
|
124
|
-
_context.
|
|
149
|
+
_context.n = 7;
|
|
125
150
|
return ant.setRecord({
|
|
126
151
|
undername: argv.undername,
|
|
127
|
-
transactionId:
|
|
128
|
-
ttlSeconds:
|
|
152
|
+
transactionId: txId,
|
|
153
|
+
ttlSeconds: TTL_SECONDS
|
|
129
154
|
}, {
|
|
130
155
|
tags: [{
|
|
131
156
|
name: 'App-Name',
|
|
@@ -135,18 +160,17 @@ _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
|
135
160
|
value: process.env.GITHUB_SHA
|
|
136
161
|
}] : []))
|
|
137
162
|
});
|
|
138
|
-
case
|
|
139
|
-
console.log("Deployed TxId [".concat(
|
|
140
|
-
_context.
|
|
163
|
+
case 7:
|
|
164
|
+
console.log("Deployed TxId [".concat(txId, "] to name [").concat(ARNS_NAME, "] for ANT [").concat(arnsNameRecord.processId, "] using undername [").concat(argv.undername, "]"));
|
|
165
|
+
_context.n = 9;
|
|
141
166
|
break;
|
|
142
|
-
case
|
|
143
|
-
_context.
|
|
144
|
-
|
|
145
|
-
console.error('Deployment failed:',
|
|
167
|
+
case 8:
|
|
168
|
+
_context.p = 8;
|
|
169
|
+
_t = _context.v;
|
|
170
|
+
console.error('Deployment failed:', _t);
|
|
146
171
|
process.exit(1); // Exit with error code
|
|
147
|
-
case
|
|
148
|
-
|
|
149
|
-
return _context.stop();
|
|
172
|
+
case 9:
|
|
173
|
+
return _context.a(2);
|
|
150
174
|
}
|
|
151
|
-
}, _callee, null, [[
|
|
175
|
+
}, _callee, null, [[2, 8]]);
|
|
152
176
|
}))();
|
package/dist/turbo/index.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
3
|
Object.defineProperty(exports, "__esModule", {
|
|
5
4
|
value: true
|
|
6
5
|
});
|
|
7
|
-
exports
|
|
8
|
-
|
|
6
|
+
exports.uploadDirectory = uploadDirectory;
|
|
7
|
+
exports.uploadFile = uploadFile;
|
|
9
8
|
var _fs = _interopRequireDefault(require("fs"));
|
|
10
9
|
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
|
11
10
|
var _path = _interopRequireDefault(require("path"));
|
|
12
11
|
var _stream = require("stream");
|
|
12
|
+
var _turboSdk = require("@ardrive/turbo-sdk");
|
|
13
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
14
|
-
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
15
14
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
16
15
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
17
16
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
17
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
18
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { if (r) i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n;else { var o = function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); }; o("next", 0), o("throw", 1), o("return", 2); } }, _regeneratorDefine2(e, r, n, t); }
|
|
18
19
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
19
20
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
20
21
|
// Gets MIME types for each file to tag the upload
|
|
@@ -22,24 +23,72 @@ function getContentType(filePath) {
|
|
|
22
23
|
var res = _mimeTypes["default"].lookup(filePath);
|
|
23
24
|
return res || 'application/octet-stream';
|
|
24
25
|
}
|
|
25
|
-
function
|
|
26
|
-
return
|
|
26
|
+
function uploadFile(_x, _x2) {
|
|
27
|
+
return _uploadFile.apply(this, arguments);
|
|
28
|
+
}
|
|
29
|
+
function _uploadFile() {
|
|
30
|
+
_uploadFile = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(path, turbo) {
|
|
31
|
+
var fileSize, contentType, uploadResult, _t;
|
|
32
|
+
return _regenerator().w(function (_context) {
|
|
33
|
+
while (1) switch (_context.n) {
|
|
34
|
+
case 0:
|
|
35
|
+
console.log("Uploading file: ".concat(path, "..."));
|
|
36
|
+
_context.p = 1;
|
|
37
|
+
fileSize = _fs["default"].statSync(path).size;
|
|
38
|
+
contentType = getContentType(path);
|
|
39
|
+
_context.n = 2;
|
|
40
|
+
return turbo.uploadFile({
|
|
41
|
+
fileStreamFactory: function fileStreamFactory() {
|
|
42
|
+
return _fs["default"].createReadStream(path);
|
|
43
|
+
},
|
|
44
|
+
fileSizeFactory: function fileSizeFactory() {
|
|
45
|
+
return fileSize;
|
|
46
|
+
},
|
|
47
|
+
signal: AbortSignal.timeout(10000),
|
|
48
|
+
// Cancel the upload after 10 seconds
|
|
49
|
+
dataItemOpts: {
|
|
50
|
+
tags: [{
|
|
51
|
+
name: 'Content-Type',
|
|
52
|
+
value: contentType
|
|
53
|
+
}, {
|
|
54
|
+
name: 'App-Name',
|
|
55
|
+
value: 'Permaweb-Deploy'
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
case 2:
|
|
60
|
+
uploadResult = _context.v;
|
|
61
|
+
console.log("Uploaded ".concat(path, " with id:"), uploadResult.id);
|
|
62
|
+
return _context.a(2, uploadResult);
|
|
63
|
+
case 3:
|
|
64
|
+
_context.p = 3;
|
|
65
|
+
_t = _context.v;
|
|
66
|
+
console.error("Error uploading file ".concat(path, ":"), _t);
|
|
67
|
+
case 4:
|
|
68
|
+
return _context.a(2);
|
|
69
|
+
}
|
|
70
|
+
}, _callee, null, [[1, 3]]);
|
|
71
|
+
}));
|
|
72
|
+
return _uploadFile.apply(this, arguments);
|
|
73
|
+
}
|
|
74
|
+
function uploadDirectory(_x3, _x4) {
|
|
75
|
+
return _uploadDirectory.apply(this, arguments);
|
|
27
76
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
77
|
+
function _uploadDirectory() {
|
|
78
|
+
_uploadDirectory = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(argv, jwk) {
|
|
30
79
|
var turbo, deployFolder, newManifest, processFiles, _processFiles, uploadManifest, _uploadManifest, manifestId;
|
|
31
|
-
return
|
|
32
|
-
while (1) switch (_context4.
|
|
80
|
+
return _regenerator().w(function (_context4) {
|
|
81
|
+
while (1) switch (_context4.n) {
|
|
33
82
|
case 0:
|
|
34
83
|
_uploadManifest = function _uploadManifest3() {
|
|
35
|
-
_uploadManifest = _asyncToGenerator(
|
|
36
|
-
var manifestString, uploadResult;
|
|
37
|
-
return
|
|
38
|
-
while (1) switch (_context3.
|
|
84
|
+
_uploadManifest = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(manifest) {
|
|
85
|
+
var manifestString, uploadResult, _t4;
|
|
86
|
+
return _regenerator().w(function (_context3) {
|
|
87
|
+
while (1) switch (_context3.n) {
|
|
39
88
|
case 0:
|
|
40
|
-
_context3.
|
|
89
|
+
_context3.p = 0;
|
|
41
90
|
manifestString = JSON.stringify(manifest);
|
|
42
|
-
_context3.
|
|
91
|
+
_context3.n = 1;
|
|
43
92
|
return turbo.uploadFile({
|
|
44
93
|
fileStreamFactory: function fileStreamFactory() {
|
|
45
94
|
return _stream.Readable.from(Buffer.from(manifestString));
|
|
@@ -58,143 +107,98 @@ function _TurboDeploy() {
|
|
|
58
107
|
}]
|
|
59
108
|
}
|
|
60
109
|
});
|
|
61
|
-
case
|
|
62
|
-
uploadResult = _context3.
|
|
63
|
-
return _context3.
|
|
64
|
-
case
|
|
65
|
-
_context3.
|
|
66
|
-
|
|
67
|
-
console.error('Error uploading manifest:',
|
|
68
|
-
return _context3.
|
|
69
|
-
case 12:
|
|
70
|
-
case "end":
|
|
71
|
-
return _context3.stop();
|
|
110
|
+
case 1:
|
|
111
|
+
uploadResult = _context3.v;
|
|
112
|
+
return _context3.a(2, uploadResult.id);
|
|
113
|
+
case 2:
|
|
114
|
+
_context3.p = 2;
|
|
115
|
+
_t4 = _context3.v;
|
|
116
|
+
console.error('Error uploading manifest:', _t4);
|
|
117
|
+
return _context3.a(2, null);
|
|
72
118
|
}
|
|
73
|
-
},
|
|
119
|
+
}, _callee3, null, [[0, 2]]);
|
|
74
120
|
}));
|
|
75
121
|
return _uploadManifest.apply(this, arguments);
|
|
76
122
|
};
|
|
77
|
-
uploadManifest = function _uploadManifest2(
|
|
123
|
+
uploadManifest = function _uploadManifest2(_x6) {
|
|
78
124
|
return _uploadManifest.apply(this, arguments);
|
|
79
125
|
};
|
|
80
126
|
_processFiles = function _processFiles3() {
|
|
81
|
-
_processFiles = _asyncToGenerator(
|
|
82
|
-
var files, _iterator, _step,
|
|
83
|
-
return
|
|
84
|
-
while (1) switch (_context2.
|
|
127
|
+
_processFiles = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(dir) {
|
|
128
|
+
var files, _iterator, _step, file, filePath, relativePath, uploadResult, _t2, _t3;
|
|
129
|
+
return _regenerator().w(function (_context2) {
|
|
130
|
+
while (1) switch (_context2.n) {
|
|
85
131
|
case 0:
|
|
86
132
|
files = _fs["default"].readdirSync(dir);
|
|
87
133
|
_iterator = _createForOfIteratorHelper(files);
|
|
88
|
-
_context2.
|
|
89
|
-
_loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
|
|
90
|
-
var file, filePath, relativePath, fileSize, contentType, uploadResult;
|
|
91
|
-
return _regeneratorRuntime().wrap(function _loop$(_context) {
|
|
92
|
-
while (1) switch (_context.prev = _context.next) {
|
|
93
|
-
case 0:
|
|
94
|
-
file = _step.value;
|
|
95
|
-
_context.prev = 1;
|
|
96
|
-
filePath = _path["default"].join(dir, file);
|
|
97
|
-
relativePath = _path["default"].relative(deployFolder, filePath);
|
|
98
|
-
if (!_fs["default"].statSync(filePath).isDirectory()) {
|
|
99
|
-
_context.next = 9;
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
_context.next = 7;
|
|
103
|
-
return processFiles(filePath);
|
|
104
|
-
case 7:
|
|
105
|
-
_context.next = 24;
|
|
106
|
-
break;
|
|
107
|
-
case 9:
|
|
108
|
-
console.log("Uploading file: ".concat(relativePath));
|
|
109
|
-
_context.prev = 10;
|
|
110
|
-
fileSize = _fs["default"].statSync(filePath).size;
|
|
111
|
-
contentType = getContentType(filePath);
|
|
112
|
-
_context.next = 15;
|
|
113
|
-
return turbo.uploadFile({
|
|
114
|
-
fileStreamFactory: function fileStreamFactory() {
|
|
115
|
-
return _fs["default"].createReadStream(filePath);
|
|
116
|
-
},
|
|
117
|
-
fileSizeFactory: function fileSizeFactory() {
|
|
118
|
-
return fileSize;
|
|
119
|
-
},
|
|
120
|
-
signal: AbortSignal.timeout(10000),
|
|
121
|
-
// cancel the upload after 10 seconds
|
|
122
|
-
dataItemOpts: {
|
|
123
|
-
tags: [{
|
|
124
|
-
name: 'Content-Type',
|
|
125
|
-
value: contentType
|
|
126
|
-
}, {
|
|
127
|
-
name: 'App-Name',
|
|
128
|
-
value: 'Permaweb-Deploy'
|
|
129
|
-
}]
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
case 15:
|
|
133
|
-
uploadResult = _context.sent;
|
|
134
|
-
console.log("Uploaded ".concat(relativePath, " with id:"), uploadResult.id);
|
|
135
|
-
// adds uploaded file txId to the new manifest json
|
|
136
|
-
newManifest.paths[relativePath] = {
|
|
137
|
-
id: uploadResult.id
|
|
138
|
-
};
|
|
139
|
-
if (file === '404.html') {
|
|
140
|
-
// sets manifest fallback to 404.html if found
|
|
141
|
-
newManifest.fallback.id = uploadResult.id;
|
|
142
|
-
}
|
|
143
|
-
_context.next = 24;
|
|
144
|
-
break;
|
|
145
|
-
case 21:
|
|
146
|
-
_context.prev = 21;
|
|
147
|
-
_context.t0 = _context["catch"](10);
|
|
148
|
-
console.error("Error uploading file ".concat(relativePath, ":"), _context.t0);
|
|
149
|
-
case 24:
|
|
150
|
-
_context.next = 29;
|
|
151
|
-
break;
|
|
152
|
-
case 26:
|
|
153
|
-
_context.prev = 26;
|
|
154
|
-
_context.t1 = _context["catch"](1);
|
|
155
|
-
console.error('ERROR:', _context.t1);
|
|
156
|
-
case 29:
|
|
157
|
-
case "end":
|
|
158
|
-
return _context.stop();
|
|
159
|
-
}
|
|
160
|
-
}, _loop, null, [[1, 26], [10, 21]]);
|
|
161
|
-
});
|
|
134
|
+
_context2.p = 1;
|
|
162
135
|
_iterator.s();
|
|
163
|
-
case
|
|
136
|
+
case 2:
|
|
164
137
|
if ((_step = _iterator.n()).done) {
|
|
165
|
-
_context2.
|
|
138
|
+
_context2.n = 10;
|
|
166
139
|
break;
|
|
167
140
|
}
|
|
168
|
-
|
|
141
|
+
file = _step.value;
|
|
142
|
+
_context2.p = 3;
|
|
143
|
+
filePath = _path["default"].join(dir, file);
|
|
144
|
+
relativePath = _path["default"].relative(deployFolder, filePath);
|
|
145
|
+
if (!_fs["default"].statSync(filePath).isDirectory()) {
|
|
146
|
+
_context2.n = 5;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
_context2.n = 4;
|
|
150
|
+
return processFiles(filePath);
|
|
151
|
+
case 4:
|
|
152
|
+
_context2.n = 7;
|
|
153
|
+
break;
|
|
154
|
+
case 5:
|
|
155
|
+
_context2.n = 6;
|
|
156
|
+
return uploadFile(filePath, turbo);
|
|
157
|
+
case 6:
|
|
158
|
+
uploadResult = _context2.v;
|
|
159
|
+
// Adds uploaded file txId to the new manifest json
|
|
160
|
+
newManifest.paths[relativePath] = {
|
|
161
|
+
id: uploadResult.id
|
|
162
|
+
};
|
|
163
|
+
if (file === '404.html') {
|
|
164
|
+
// Sets manifest fallback to 404.html if found
|
|
165
|
+
newManifest.fallback.id = uploadResult.id;
|
|
166
|
+
}
|
|
169
167
|
case 7:
|
|
170
|
-
_context2.
|
|
168
|
+
_context2.n = 9;
|
|
171
169
|
break;
|
|
170
|
+
case 8:
|
|
171
|
+
_context2.p = 8;
|
|
172
|
+
_t2 = _context2.v;
|
|
173
|
+
console.error('ERROR:', _t2);
|
|
172
174
|
case 9:
|
|
173
|
-
_context2.
|
|
175
|
+
_context2.n = 2;
|
|
176
|
+
break;
|
|
177
|
+
case 10:
|
|
178
|
+
_context2.n = 12;
|
|
174
179
|
break;
|
|
175
180
|
case 11:
|
|
176
|
-
_context2.
|
|
177
|
-
|
|
178
|
-
_iterator.e(
|
|
179
|
-
case
|
|
180
|
-
_context2.
|
|
181
|
+
_context2.p = 11;
|
|
182
|
+
_t3 = _context2.v;
|
|
183
|
+
_iterator.e(_t3);
|
|
184
|
+
case 12:
|
|
185
|
+
_context2.p = 12;
|
|
181
186
|
_iterator.f();
|
|
182
|
-
return _context2.
|
|
183
|
-
case
|
|
184
|
-
|
|
185
|
-
return _context2.stop();
|
|
187
|
+
return _context2.f(12);
|
|
188
|
+
case 13:
|
|
189
|
+
return _context2.a(2);
|
|
186
190
|
}
|
|
187
|
-
},
|
|
191
|
+
}, _callee2, null, [[3, 8], [1, 11, 12, 13]]);
|
|
188
192
|
}));
|
|
189
193
|
return _processFiles.apply(this, arguments);
|
|
190
194
|
};
|
|
191
|
-
processFiles = function _processFiles2(
|
|
195
|
+
processFiles = function _processFiles2(_x5) {
|
|
192
196
|
return _processFiles.apply(this, arguments);
|
|
193
197
|
};
|
|
194
198
|
turbo = _turboSdk.TurboFactory.authenticated({
|
|
195
199
|
privateKey: jwk
|
|
196
200
|
});
|
|
197
|
-
deployFolder = argv.deployFolder; //Uses Arweave manifest version 0.2.0, which supports fallbacks
|
|
201
|
+
deployFolder = argv.deployFolder; // Uses Arweave manifest version 0.2.0, which supports fallbacks
|
|
198
202
|
newManifest = {
|
|
199
203
|
manifest: 'arweave/paths',
|
|
200
204
|
version: '0.2.0',
|
|
@@ -203,29 +207,28 @@ function _TurboDeploy() {
|
|
|
203
207
|
},
|
|
204
208
|
fallback: {},
|
|
205
209
|
paths: {}
|
|
206
|
-
}; //
|
|
207
|
-
_context4.
|
|
210
|
+
}; // Starts processing files in the selected directory
|
|
211
|
+
_context4.n = 1;
|
|
208
212
|
return processFiles(deployFolder);
|
|
209
|
-
case
|
|
213
|
+
case 1:
|
|
210
214
|
if (!newManifest.fallback.id) {
|
|
211
|
-
//
|
|
215
|
+
// If no 404.html file is found, manifest fallback is set to the txId of index.html
|
|
212
216
|
newManifest.fallback.id = newManifest.paths['index.html'].id;
|
|
213
217
|
}
|
|
214
|
-
_context4.
|
|
218
|
+
_context4.n = 2;
|
|
215
219
|
return uploadManifest(newManifest);
|
|
216
|
-
case
|
|
217
|
-
manifestId = _context4.
|
|
220
|
+
case 2:
|
|
221
|
+
manifestId = _context4.v;
|
|
218
222
|
if (!manifestId) {
|
|
219
|
-
_context4.
|
|
223
|
+
_context4.n = 3;
|
|
220
224
|
break;
|
|
221
225
|
}
|
|
222
226
|
console.log("Manifest uploaded with Id: ".concat(manifestId));
|
|
223
|
-
return _context4.
|
|
224
|
-
case
|
|
225
|
-
|
|
226
|
-
return _context4.stop();
|
|
227
|
+
return _context4.a(2, manifestId);
|
|
228
|
+
case 3:
|
|
229
|
+
return _context4.a(2);
|
|
227
230
|
}
|
|
228
|
-
},
|
|
231
|
+
}, _callee4);
|
|
229
232
|
}));
|
|
230
|
-
return
|
|
233
|
+
return _uploadDirectory.apply(this, arguments);
|
|
231
234
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "permaweb-deploy",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Permaweb
|
|
3
|
+
"version": "2.3.0",
|
|
4
|
+
"description": "Permaweb App Deployment Package",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "babel src --out-dir dist"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@ar.io/sdk": "^3.10.1",
|
|
14
14
|
"@ardrive/turbo-sdk": "^1.17.0",
|
|
15
|
-
"@permaweb/aoconnect": "^0.0.
|
|
15
|
+
"@permaweb/aoconnect": "^0.0.85",
|
|
16
16
|
"mime-types": "^2.1.35",
|
|
17
17
|
"yargs": "17.7.2"
|
|
18
18
|
},
|
package/src/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { ANT, AOProcess, ARIO, ARIO_MAINNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, ArweaveSigner } from '@ar.io/sdk';
|
|
4
3
|
import fs from 'fs';
|
|
5
4
|
import yargs from 'yargs';
|
|
6
5
|
import { hideBin } from 'yargs/helpers';
|
|
7
6
|
|
|
7
|
+
import { ANT, AOProcess, ARIO, ARIO_MAINNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, ArweaveSigner } from '@ar.io/sdk';
|
|
8
|
+
import { TurboFactory } from '@ardrive/turbo-sdk';
|
|
8
9
|
import { connect } from '@permaweb/aoconnect';
|
|
9
10
|
|
|
10
|
-
import
|
|
11
|
+
import { uploadDirectory, uploadFile } from './turbo';
|
|
11
12
|
|
|
12
13
|
const arweaveTxIdRegex = /^[a-zA-Z0-9-_]{43}$/;
|
|
13
14
|
|
|
@@ -31,6 +32,17 @@ const argv = yargs(hideBin(process.argv))
|
|
|
31
32
|
description: 'Folder to deploy.',
|
|
32
33
|
default: './dist',
|
|
33
34
|
})
|
|
35
|
+
.option('deploy-file', {
|
|
36
|
+
alias: 'f',
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'File to deploy.'
|
|
39
|
+
})
|
|
40
|
+
.option('ttl-seconds', {
|
|
41
|
+
alias: 't',
|
|
42
|
+
type: 'number',
|
|
43
|
+
description: 'ArNS TTL Seconds',
|
|
44
|
+
default: 3600
|
|
45
|
+
})
|
|
34
46
|
.option('undername', {
|
|
35
47
|
alias: 'u',
|
|
36
48
|
type: 'string',
|
|
@@ -40,6 +52,7 @@ const argv = yargs(hideBin(process.argv))
|
|
|
40
52
|
|
|
41
53
|
const DEPLOY_KEY = process.env.DEPLOY_KEY;
|
|
42
54
|
const ARNS_NAME = argv.arnsName;
|
|
55
|
+
const TTL_SECONDS = argv.ttlSeconds;
|
|
43
56
|
let ARIO_PROCESS = argv.arioProcess;
|
|
44
57
|
if (ARIO_PROCESS === 'mainnet') {
|
|
45
58
|
ARIO_PROCESS = ARIO_MAINNET_PROCESS_ID;
|
|
@@ -47,17 +60,6 @@ if (ARIO_PROCESS === 'mainnet') {
|
|
|
47
60
|
ARIO_PROCESS = ARIO_TESTNET_PROCESS_ID;
|
|
48
61
|
}
|
|
49
62
|
|
|
50
|
-
export function getTagValue(list, name) {
|
|
51
|
-
for (let i = 0; i < list.length; i++) {
|
|
52
|
-
if (list[i]) {
|
|
53
|
-
if (list[i].name === name) {
|
|
54
|
-
return list[i].value;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return STORAGE.none;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
63
|
(async () => {
|
|
62
64
|
if (!ARIO_PROCESS || !arweaveTxIdRegex.test(ARIO_PROCESS)) {
|
|
63
65
|
console.error('ARIO_PROCESS must be a valid Arweave transaction ID, or "mainnet" or "testnet"');
|
|
@@ -74,38 +76,62 @@ export function getTagValue(list, name) {
|
|
|
74
76
|
process.exit(1);
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
console.error('deploy folder must not be empty');
|
|
79
|
+
if (!Number.isFinite(TTL_SECONDS) || TTL_SECONDS < 60 || TTL_SECONDS > 86400) {
|
|
80
|
+
console.error('TTL_SECONDS must be a number between 60 and 86400 seconds');
|
|
80
81
|
process.exit(1);
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
if (argv.
|
|
84
|
-
console.error(
|
|
84
|
+
if (argv.deployFile && !fs.existsSync(argv.deployFile)) {
|
|
85
|
+
console.error(`deploy-file [${argv.deployFolder}] does not exist`);
|
|
85
86
|
process.exit(1);
|
|
86
87
|
}
|
|
88
|
+
else {
|
|
89
|
+
if (!fs.existsSync(argv.deployFolder)) {
|
|
90
|
+
console.error(`deploy-folder [${argv.deployFolder}] does not exist`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
87
94
|
|
|
88
|
-
if (
|
|
89
|
-
console.error(
|
|
95
|
+
if (argv.undername.length === 0) {
|
|
96
|
+
console.error('undername must be set');
|
|
90
97
|
process.exit(1);
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
const jwk = JSON.parse(Buffer.from(DEPLOY_KEY, 'base64').toString('utf-8'));
|
|
94
|
-
const ario = ARIO.init({
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
const ario = ARIO.init({
|
|
102
|
+
process: new AOProcess({
|
|
103
|
+
processId: ARIO_PROCESS,
|
|
104
|
+
ao: connect({
|
|
105
|
+
MODE: 'legacy',
|
|
106
|
+
CU_URL: 'https://cu.ardrive.io'
|
|
107
|
+
})
|
|
99
108
|
})
|
|
100
|
-
})
|
|
101
|
-
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const arnsNameRecord = await ario.getArNSRecord({ name: ARNS_NAME }).catch((e) => {
|
|
102
112
|
console.error(`ARNS name [${ARNS_NAME}] does not exist`);
|
|
103
113
|
process.exit(1);
|
|
104
114
|
});
|
|
105
115
|
|
|
106
|
-
|
|
107
116
|
try {
|
|
108
|
-
|
|
117
|
+
let txId;
|
|
118
|
+
if (argv.deployFile) {
|
|
119
|
+
const turbo = TurboFactory.authenticated({ privateKey: jwk });
|
|
120
|
+
txId = (await uploadFile(argv.deployFile, turbo)).id;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
txId = await uploadDirectory(argv, jwk);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log('-------------------- DEPLOY DETAILS --------------------');
|
|
127
|
+
console.log(`Tx ID: ${txId}`);
|
|
128
|
+
console.log(`ArNS Name: ${ARNS_NAME}`);
|
|
129
|
+
console.log(`Undername: ${argv.undername}`);
|
|
130
|
+
console.log(`ANT: ${arnsNameRecord.processId}`);
|
|
131
|
+
console.log(`AR IO Process: ${ARIO_PROCESS}`);
|
|
132
|
+
console.log(`TTL Seconds: ${TTL_SECONDS}`);
|
|
133
|
+
console.log('--------------------------------------------------------');
|
|
134
|
+
|
|
109
135
|
const signer = new ArweaveSigner(jwk);
|
|
110
136
|
const ant = ANT.init({ processId: arnsNameRecord.processId, signer });
|
|
111
137
|
|
|
@@ -113,9 +139,10 @@ export function getTagValue(list, name) {
|
|
|
113
139
|
await ant.setRecord(
|
|
114
140
|
{
|
|
115
141
|
undername: argv.undername,
|
|
116
|
-
transactionId:
|
|
117
|
-
ttlSeconds:
|
|
118
|
-
},
|
|
142
|
+
transactionId: txId,
|
|
143
|
+
ttlSeconds: TTL_SECONDS,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
119
146
|
tags: [
|
|
120
147
|
{
|
|
121
148
|
name: 'App-Name',
|
|
@@ -129,7 +156,7 @@ export function getTagValue(list, name) {
|
|
|
129
156
|
}
|
|
130
157
|
);
|
|
131
158
|
|
|
132
|
-
console.log(`Deployed TxId [${
|
|
159
|
+
console.log(`Deployed TxId [${txId}] to name [${ARNS_NAME}] for ANT [${arnsNameRecord.processId}] using undername [${argv.undername}]`);
|
|
133
160
|
} catch (e) {
|
|
134
161
|
console.error('Deployment failed:', e);
|
|
135
162
|
process.exit(1); // Exit with error code
|
package/src/turbo/index.js
CHANGED
|
@@ -1,20 +1,47 @@
|
|
|
1
|
-
import { TurboFactory } from '@ardrive/turbo-sdk';
|
|
2
1
|
import fs from 'fs';
|
|
3
2
|
import mime from 'mime-types';
|
|
4
3
|
import path from 'path';
|
|
5
4
|
import { Readable } from 'stream';
|
|
6
5
|
|
|
6
|
+
import { TurboFactory } from '@ardrive/turbo-sdk';
|
|
7
|
+
|
|
7
8
|
// Gets MIME types for each file to tag the upload
|
|
8
9
|
function getContentType(filePath) {
|
|
9
10
|
const res = mime.lookup(filePath);
|
|
10
11
|
return res || 'application/octet-stream';
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export
|
|
14
|
+
export async function uploadFile(path, turbo) {
|
|
15
|
+
console.log(`Uploading file: ${path}...`);
|
|
16
|
+
try {
|
|
17
|
+
const fileSize = fs.statSync(path).size;
|
|
18
|
+
const contentType = getContentType(path);
|
|
19
|
+
const uploadResult = await turbo.uploadFile({
|
|
20
|
+
fileStreamFactory: () => fs.createReadStream(path),
|
|
21
|
+
fileSizeFactory: () => fileSize,
|
|
22
|
+
signal: AbortSignal.timeout(10_000), // Cancel the upload after 10 seconds
|
|
23
|
+
dataItemOpts: {
|
|
24
|
+
tags: [
|
|
25
|
+
{ name: 'Content-Type', value: contentType },
|
|
26
|
+
{ name: 'App-Name', value: 'Permaweb-Deploy' },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
console.log(`Uploaded ${path} with id:`, uploadResult.id);
|
|
32
|
+
|
|
33
|
+
return uploadResult;
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.error(`Error uploading file ${path}:`, err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function uploadDirectory(argv, jwk) {
|
|
14
40
|
const turbo = TurboFactory.authenticated({ privateKey: jwk });
|
|
15
41
|
|
|
16
42
|
const deployFolder = argv.deployFolder;
|
|
17
|
-
|
|
43
|
+
|
|
44
|
+
// Uses Arweave manifest version 0.2.0, which supports fallbacks
|
|
18
45
|
let newManifest = {
|
|
19
46
|
manifest: 'arweave/paths',
|
|
20
47
|
version: '0.2.0',
|
|
@@ -32,35 +59,17 @@ export default async function TurboDeploy(argv, jwk) {
|
|
|
32
59
|
const relativePath = path.relative(deployFolder, filePath);
|
|
33
60
|
|
|
34
61
|
if (fs.statSync(filePath).isDirectory()) {
|
|
35
|
-
//
|
|
62
|
+
// Recursively process all files in a directory
|
|
36
63
|
await processFiles(filePath);
|
|
37
64
|
} else {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
dataItemOpts: {
|
|
47
|
-
tags: [
|
|
48
|
-
{ name: 'Content-Type', value: contentType },
|
|
49
|
-
{ name: 'App-Name', value: 'Permaweb-Deploy' },
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
console.log(`Uploaded ${relativePath} with id:`, uploadResult.id);
|
|
55
|
-
// adds uploaded file txId to the new manifest json
|
|
56
|
-
newManifest.paths[relativePath] = { id: uploadResult.id };
|
|
57
|
-
|
|
58
|
-
if (file === '404.html') {
|
|
59
|
-
// sets manifest fallback to 404.html if found
|
|
60
|
-
newManifest.fallback.id = uploadResult.id;
|
|
61
|
-
}
|
|
62
|
-
} catch (err) {
|
|
63
|
-
console.error(`Error uploading file ${relativePath}:`, err);
|
|
65
|
+
const uploadResult = await uploadFile(filePath, turbo);
|
|
66
|
+
|
|
67
|
+
// Adds uploaded file txId to the new manifest json
|
|
68
|
+
newManifest.paths[relativePath] = { id: uploadResult.id };
|
|
69
|
+
|
|
70
|
+
if (file === '404.html') {
|
|
71
|
+
// Sets manifest fallback to 404.html if found
|
|
72
|
+
newManifest.fallback.id = uploadResult.id;
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
} catch (err) {
|
|
@@ -96,11 +105,11 @@ export default async function TurboDeploy(argv, jwk) {
|
|
|
96
105
|
}
|
|
97
106
|
}
|
|
98
107
|
|
|
99
|
-
//
|
|
108
|
+
// Starts processing files in the selected directory
|
|
100
109
|
await processFiles(deployFolder);
|
|
101
110
|
|
|
102
111
|
if (!newManifest.fallback.id) {
|
|
103
|
-
//
|
|
112
|
+
// If no 404.html file is found, manifest fallback is set to the txId of index.html
|
|
104
113
|
newManifest.fallback.id = newManifest.paths['index.html'].id;
|
|
105
114
|
}
|
|
106
115
|
|