dxfl 0.6.1 → 0.6.2
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/.prettierignore +1 -0
- package/CHANGELOG.md +4 -0
- package/README.md +6 -2
- package/dist/deploy.js +5 -9
- package/dist/index.js +1 -1
- package/dist/website_config.js +35 -19
- package/npm-shrinkwrap.json +8 -4
- package/package.json +4 -2
package/.prettierignore
CHANGED
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -191,10 +191,13 @@ git clone https://git.deuxfleurs.fr/Deuxfleurs/dxfl
|
|
|
191
191
|
cd dxfl
|
|
192
192
|
npm install
|
|
193
193
|
# build and install the tool as the `dxfl` command
|
|
194
|
-
npm
|
|
194
|
+
npm run build
|
|
195
195
|
dxfl
|
|
196
196
|
# alternatively, run the tool from the sources directly
|
|
197
197
|
npx dxfl
|
|
198
|
+
# rebuild automatically on changes with:
|
|
199
|
+
npm run dev
|
|
200
|
+
|
|
198
201
|
```
|
|
199
202
|
|
|
200
203
|
### Code formatting
|
|
@@ -220,7 +223,8 @@ Then to publish a release:
|
|
|
220
223
|
vim CHANGELOG.md # update the version and its content in this file
|
|
221
224
|
vim package.json # update the version in this file
|
|
222
225
|
vim index.ts # update the version in this file
|
|
223
|
-
npm install # update the version in the lock file
|
|
226
|
+
npm install # update the version in the lock file and check security audit
|
|
227
|
+
npm shrinkwrap # make suuuure the lock file is up to date
|
|
224
228
|
npm run prettier # fix potential coding style problem
|
|
225
229
|
git commit -a -m 'set version 0.1.5' # commit your change
|
|
226
230
|
git push # send update
|
package/dist/deploy.js
CHANGED
|
@@ -14,7 +14,7 @@ import { deleteBucketFile, deleteBucketFiles, getBucketCredentials, getBucket, g
|
|
|
14
14
|
import { ErrorMsg } from "./error.js";
|
|
15
15
|
import { fileContentType, supportedHeaders, } from "./headers.js";
|
|
16
16
|
import { confirmationPrompt, filterMap, formatBytesHuman, formatCount, getFileMd5, gzipFile, mapEq, mkTmpDir, sum, websiteIdBestEffort, } from "./utils.js";
|
|
17
|
-
import { evalHeadersRules, equalBucketRedirect, getBucketConfig, putBucketWebsiteConfig, readConfigFile, } from "./website_config.js";
|
|
17
|
+
import { evalHeadersRules, equalBucketRedirect, equalCorsRules, getBucketConfig, putBucketWebsiteConfig, putCorsRules, readConfigFile, } from "./website_config.js";
|
|
18
18
|
// Walks through the local directory at path `dir`, and for each file it contains, returns :
|
|
19
19
|
// - `localPath`: its path on the local filesystem (includes `dir`). On windows, this path
|
|
20
20
|
// will typically use `\` as separator.
|
|
@@ -263,11 +263,7 @@ function printPlan(plan, details) {
|
|
|
263
263
|
const oredirects_updated = plan.redirects.filter(r => r.action == "update");
|
|
264
264
|
const oredirects_deleted = plan.redirects.filter(r => r.action == "delete");
|
|
265
265
|
// check whether CORS rules changed
|
|
266
|
-
|
|
267
|
-
// plan.cors_rules.from,
|
|
268
|
-
// plan.cors_rules.to,
|
|
269
|
-
// );
|
|
270
|
-
const cors_changed = false;
|
|
266
|
+
const cors_changed = !equalCorsRules(plan.cors_rules.from, plan.cors_rules.to);
|
|
271
267
|
// print
|
|
272
268
|
if (details == "summary") {
|
|
273
269
|
const sizeRemote = sum([...plan.remoteFiles.values()].map(f => { var _a; return (_a = f.size) !== null && _a !== void 0 ? _a : 0; }));
|
|
@@ -407,9 +403,9 @@ function applyDeployPlan(bucket, plan) {
|
|
|
407
403
|
// Apply bucket redirects & global config
|
|
408
404
|
yield putBucketWebsiteConfig(bucket, plan.index_page.to, plan.error_page.to, plan.bucket_redirects.to);
|
|
409
405
|
// Apply CORS rules
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
406
|
+
if (!equalCorsRules(plan.cors_rules.from, plan.cors_rules.to)) {
|
|
407
|
+
yield putCorsRules(bucket, plan.cors_rules.to);
|
|
408
|
+
}
|
|
413
409
|
// Modify headers
|
|
414
410
|
yield PromisePool.for(plan.modifyHeaders)
|
|
415
411
|
.withConcurrency(50)
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { deploy } from "./deploy.js";
|
|
|
6
6
|
import { empty } from "./empty.js";
|
|
7
7
|
import { list } from "./vhosts.js";
|
|
8
8
|
import { inspect } from "./inspect.js";
|
|
9
|
-
program.name("dxfl").description("Deuxfleurs CLI tool").version("0.6.
|
|
9
|
+
program.name("dxfl").description("Deuxfleurs CLI tool").version("0.6.2");
|
|
10
10
|
program
|
|
11
11
|
.command("login")
|
|
12
12
|
.description("Link your Deuxfleurs account with this tool.")
|
package/dist/website_config.js
CHANGED
|
@@ -13,7 +13,7 @@ import URI from "fast-uri";
|
|
|
13
13
|
import picomatch from "picomatch";
|
|
14
14
|
import { z as zod } from "zod";
|
|
15
15
|
import { fromError as zodError } from "zod-validation-error";
|
|
16
|
-
import { DeleteBucketCorsCommand, GetBucketWebsiteCommand, PutBucketWebsiteCommand, PutBucketCorsCommand, } from "@aws-sdk/client-s3";
|
|
16
|
+
import { DeleteBucketCorsCommand, GetBucketCorsCommand, GetBucketWebsiteCommand, PutBucketWebsiteCommand, PutBucketCorsCommand, S3ServiceException, } from "@aws-sdk/client-s3";
|
|
17
17
|
import { ErrorMsg, withErrorMsg, wrapS3Call } from "./error.js";
|
|
18
18
|
import { supportedHeaders } from "./headers.js";
|
|
19
19
|
import { getBucketFilesDetails } from "./bucket.js";
|
|
@@ -375,14 +375,12 @@ export function getBucketConfig(bucket, files) {
|
|
|
375
375
|
// - A Head command for each file in the bucket to collect object redirects.
|
|
376
376
|
// (This can become relatively slow for buckets with thousands of files,
|
|
377
377
|
// but I don't know of a better way.)
|
|
378
|
-
var _a, _b;
|
|
379
|
-
const [website, details] = yield Promise.all([
|
|
378
|
+
var _a, _b, _c, _d, _e, _f;
|
|
379
|
+
const [website, cors, details] = yield Promise.all([
|
|
380
380
|
// 204 "No Content" is returned when there is no existing website config
|
|
381
381
|
wrapS3Call(`read the bucket website config`, [200, 204], () => bucket.client.send(new GetBucketWebsiteCommand({ Bucket: bucket.name }))),
|
|
382
|
-
//
|
|
383
|
-
|
|
384
|
-
// bucket.client.send(new GetBucketCorsCommand({ Bucket: bucket.name })),
|
|
385
|
-
// ),
|
|
382
|
+
// 404 is returned when there are no existing CORS rules
|
|
383
|
+
wrapS3Call(`read the bucket CORS config`, [200, 404], () => getBucketCors(bucket)),
|
|
386
384
|
getBucketFilesDetails(bucket, files),
|
|
387
385
|
]);
|
|
388
386
|
// Collect object redirects
|
|
@@ -393,8 +391,7 @@ export function getBucketConfig(bucket, files) {
|
|
|
393
391
|
}
|
|
394
392
|
}
|
|
395
393
|
// Interpret bucket redirects
|
|
396
|
-
if (website.RedirectAllRequestsTo
|
|
397
|
-
"HostName" in website.RedirectAllRequestsTo) {
|
|
394
|
+
if (website.RedirectAllRequestsTo) {
|
|
398
395
|
// NB: garage does not currently support RedirectAllRequestsTo so this should never happen
|
|
399
396
|
throw new ErrorMsg(`remote website configuration: RedirectAllRequestsTo is specified; ` +
|
|
400
397
|
`this is currently unsupported by dxfl`);
|
|
@@ -468,16 +465,16 @@ export function getBucketConfig(bucket, files) {
|
|
|
468
465
|
}
|
|
469
466
|
// Interpret CORS rules
|
|
470
467
|
let cors_rules = [];
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
468
|
+
if (cors.CORSRules) {
|
|
469
|
+
for (const rule of cors.CORSRules) {
|
|
470
|
+
cors_rules.push({
|
|
471
|
+
allowed_origins: (_c = rule.AllowedOrigins) !== null && _c !== void 0 ? _c : [],
|
|
472
|
+
allowed_methods: (_d = rule.AllowedMethods) !== null && _d !== void 0 ? _d : [],
|
|
473
|
+
allowed_headers: (_e = rule.AllowedHeaders) !== null && _e !== void 0 ? _e : [],
|
|
474
|
+
expose_headers: (_f = rule.ExposeHeaders) !== null && _f !== void 0 ? _f : [],
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
481
478
|
// Interpret headers
|
|
482
479
|
let headers = new Map();
|
|
483
480
|
for (const [file, { headers: file_headers }] of details) {
|
|
@@ -493,6 +490,25 @@ export function getBucketConfig(bucket, files) {
|
|
|
493
490
|
};
|
|
494
491
|
});
|
|
495
492
|
}
|
|
493
|
+
function getBucketCors(bucket) {
|
|
494
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
495
|
+
var _a;
|
|
496
|
+
try {
|
|
497
|
+
return yield bucket.client.send(new GetBucketCorsCommand({ Bucket: bucket.name }));
|
|
498
|
+
}
|
|
499
|
+
catch (e) {
|
|
500
|
+
if (e instanceof S3ServiceException && ((_a = e.$response) === null || _a === void 0 ? void 0 : _a.statusCode) == 404) {
|
|
501
|
+
return {
|
|
502
|
+
CORSRules: [],
|
|
503
|
+
$metadata: e.$metadata,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
throw e;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
}
|
|
496
512
|
////////////// Applying a configuration to S3
|
|
497
513
|
// applies the bucket-wide part of the website configuration
|
|
498
514
|
export function putBucketWebsiteConfig(bucket, index_page, error_page, bucket_redirects) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dxfl",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "dxfl",
|
|
9
|
-
"version": "0.6.
|
|
9
|
+
"version": "0.6.2",
|
|
10
10
|
"license": "EUPL-1.2",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@aws-sdk/client-s3": "^3.1014.0",
|
|
@@ -1854,7 +1854,9 @@
|
|
|
1854
1854
|
"hasInstallScript": true,
|
|
1855
1855
|
"license": "MIT",
|
|
1856
1856
|
"optional": true,
|
|
1857
|
-
"os": [
|
|
1857
|
+
"os": [
|
|
1858
|
+
"darwin"
|
|
1859
|
+
],
|
|
1858
1860
|
"engines": {
|
|
1859
1861
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
|
1860
1862
|
}
|
|
@@ -1944,7 +1946,9 @@
|
|
|
1944
1946
|
"version": "4.1.0",
|
|
1945
1947
|
"resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz",
|
|
1946
1948
|
"integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==",
|
|
1947
|
-
"funding": [
|
|
1949
|
+
"funding": [
|
|
1950
|
+
"https://github.com/sponsors/broofa"
|
|
1951
|
+
],
|
|
1948
1952
|
"license": "MIT",
|
|
1949
1953
|
"bin": {
|
|
1950
1954
|
"mime": "bin/cli.js"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dxfl",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "EUPL-1.2",
|
|
6
6
|
"author": "Deuxfleurs Team <coucou@deuxfleurs.fr>",
|
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
"node": ">=20.0.0"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
|
+
"build": "npx tsc && npm link",
|
|
21
|
+
"dev": "npm link && npx onchange \"**/*.ts\" -- npx tsc",
|
|
20
22
|
"prepare": "npx tsc",
|
|
21
23
|
"prettier": "npx prettier . --write",
|
|
22
|
-
"prettier-watch": "npx
|
|
24
|
+
"prettier-watch": "npx onchange \"**/*\" -- npx prettier --write --ignore-unknown {{changed}}",
|
|
23
25
|
"prettier-check": "npx prettier . --check"
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|