dxfl 0.3.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # v0.3.2
2
+
3
+ - update `@aws-sdk/client-s3` 3.983.0 → 3.1004.0
4
+ - `deploy`: fix failed request not being retried
5
+ - AWS\_\* environment variables now override guichet credentials
6
+
7
+ # v0.3.1
8
+
9
+ - fix `deuxfleurs.toml`: always pass the user-provided value of index_page to garage
10
+
1
11
  # v0.3.0
2
12
 
3
13
  - improve `list` presentation
package/dist/auth.js CHANGED
@@ -109,6 +109,11 @@ export function openApiConf() {
109
109
  }
110
110
  export function login(username) {
111
111
  return __awaiter(this, void 0, void 0, function* () {
112
+ if (username == undefined) {
113
+ username = yield read({
114
+ prompt: "username: ",
115
+ });
116
+ }
112
117
  const password = yield read({
113
118
  prompt: "password: ",
114
119
  silent: true,
package/dist/bucket.js CHANGED
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import fs from "fs";
10
+ import fs from "fs/promises";
11
11
  import mime from "mime";
12
12
  import { DeleteObjectCommand, DeleteObjectsCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
13
13
  import { PromisePool } from "@supercharge/promise-pool";
@@ -17,19 +17,18 @@ import { GuichetApi } from "./guichet.js";
17
17
  import { parseEtag, toChunks, formatBytesHuman } from "./utils.js";
18
18
  export function getBucketCredentials(name) {
19
19
  return __awaiter(this, void 0, void 0, function* () {
20
+ const creds = credentialsFromEnv();
21
+ if (creds !== undefined) {
22
+ process.stdout.write("Using credentials from environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY\n");
23
+ return creds;
24
+ }
20
25
  if (yield apiConfExists()) {
21
26
  const guichet = new GuichetApi(yield openApiConf());
22
27
  return yield credentialsFromApi(guichet, name);
23
28
  }
24
- else {
25
- const creds = credentialsFromEnv();
26
- if (creds === undefined) {
27
- throw new ErrorMsg("Failed to load credentials.\n" +
28
- "You need to run 'dxfl login', " +
29
- "or define the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.");
30
- }
31
- return creds;
32
- }
29
+ throw new ErrorMsg("Failed to load credentials.\n" +
30
+ "You need to run 'dxfl login', " +
31
+ "or define the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.");
33
32
  });
34
33
  }
35
34
  function credentialsFromEnv() {
@@ -153,7 +152,12 @@ export function uploadFile(bucket, s3Path, localPath) {
153
152
  if (ContentType && ContentType.startsWith("text/")) {
154
153
  ContentType = ContentType + "; charset=utf-8";
155
154
  }
156
- const Body = fs.createReadStream(localPath);
155
+ // NB: we read the entire file into memory instead of creating a stream from
156
+ // the file (which would allow streaming the data). Indeed, using a stream
157
+ // results in transcient network errors being throwned instead of being
158
+ // retried by the AWS SDK: https://github.com/aws/aws-sdk-js-v3/issues/6770
159
+ // which we want to avoid...
160
+ const Body = yield fs.readFile(localPath);
157
161
  const params = { Bucket: bucket.name, Key: s3Path, Body, ContentType };
158
162
  yield wrapS3Call(`upload "${s3Path}"`, [200], () => bucket.client.send(new PutObjectCommand(params)));
159
163
  });
package/dist/index.js CHANGED
@@ -6,11 +6,11 @@ import { deploy } from "./deploy.js";
6
6
  import { empty } from "./empty.js";
7
7
  import { vhostsList } from "./vhosts.js";
8
8
  import { inspect } from "./inspect.js";
9
- program.name("dxfl").description("Deuxfleurs CLI tool").version("0.3.0");
9
+ program.name("dxfl").description("Deuxfleurs CLI tool").version("0.3.2");
10
10
  program
11
11
  .command("login")
12
12
  .description("Link your Deuxfleurs account with this tool.")
13
- .argument("<username>", "your account username")
13
+ .argument("[username]", "your account username")
14
14
  .action(username => withHandleErrors(() => login(username)));
15
15
  program
16
16
  .command("list")
@@ -143,8 +143,8 @@ function unescape(s) {
143
143
  }
144
144
  }
145
145
  function interpConfig(rawcfg) {
146
- var _a, _b, _c, _d, _e;
147
- function interpRedirect(i, r) {
146
+ var _a, _b, _c, _d, _e, _f;
147
+ function interpRedirect(r) {
148
148
  var _a, _b;
149
149
  const rfrom = withErrorMsg(() => unescape(r.from), msg => `from: ${msg}`);
150
150
  const rto = withErrorMsg(() => unescape(r.to), msg => `to: ${msg}`);
@@ -264,7 +264,7 @@ function interpConfig(rawcfg) {
264
264
  return s !== null && s !== void 0 ? s : def;
265
265
  };
266
266
  // use index.html as default index page
267
- const index_page = withDefault(rawcfg.index_page, "index.html");
267
+ const index_page = (_a = rawcfg.index_page) !== null && _a !== void 0 ? _a : "index.html";
268
268
  // use error.html as default error page
269
269
  const error_page = withDefault(rawcfg.error_page, "error.html");
270
270
  let cfg = {
@@ -274,9 +274,9 @@ function interpConfig(rawcfg) {
274
274
  object_redirects: new Map(),
275
275
  cors_rules: [],
276
276
  };
277
- for (const [i, raw] of ((_a = rawcfg.redirects) !== null && _a !== void 0 ? _a : []).entries()) {
277
+ for (const [i, raw] of ((_b = rawcfg.redirects) !== null && _b !== void 0 ? _b : []).entries()) {
278
278
  // `i+1` is only used for display: start counting redirects from 1 instead of 0
279
- const r = withErrorMsg(() => interpRedirect(i + 1, raw), msg => `Redirect ${i + 1}: ${msg}`);
279
+ const r = withErrorMsg(() => interpRedirect(raw), msg => `Redirect ${i + 1}: ${msg}`);
280
280
  if (r.kind == "bucket") {
281
281
  cfg.bucket_redirects.push(r.r);
282
282
  }
@@ -287,15 +287,15 @@ function interpConfig(rawcfg) {
287
287
  cfg.object_redirects.set(r.from, r.to);
288
288
  }
289
289
  }
290
- for (const [_, raw] of ((_b = rawcfg.cors) !== null && _b !== void 0 ? _b : []).entries()) {
290
+ for (const [_, raw] of ((_c = rawcfg.cors) !== null && _c !== void 0 ? _c : []).entries()) {
291
291
  const interpRawArray = (x) => {
292
292
  return typeof x === "string" ? [x] : x;
293
293
  };
294
294
  cfg.cors_rules.push({
295
295
  allowed_origins: interpRawArray(raw.allowed_origins),
296
- allowed_methods: interpRawArray((_c = raw.allowed_methods) !== null && _c !== void 0 ? _c : ["GET", "HEAD"]),
297
- allowed_headers: interpRawArray((_d = raw.allowed_methods) !== null && _d !== void 0 ? _d : []),
298
- expose_headers: interpRawArray((_e = raw.expose_headers) !== null && _e !== void 0 ? _e : []),
296
+ allowed_methods: interpRawArray((_d = raw.allowed_methods) !== null && _d !== void 0 ? _d : ["GET", "HEAD"]),
297
+ allowed_headers: interpRawArray((_e = raw.allowed_methods) !== null && _e !== void 0 ? _e : []),
298
+ expose_headers: interpRawArray((_f = raw.expose_headers) !== null && _f !== void 0 ? _f : []),
299
299
  });
300
300
  }
301
301
  return cfg;
@@ -431,10 +431,10 @@ export function putBucketWebsiteConfig(bucket, index_page, error_page, bucket_re
431
431
  return __awaiter(this, void 0, void 0, function* () {
432
432
  // TODO: printing to show what changes are being applied?
433
433
  const WebsiteConfiguration = {};
434
- if (error_page) {
434
+ if (error_page != undefined) {
435
435
  WebsiteConfiguration.ErrorDocument = { Key: error_page };
436
436
  }
437
- if (index_page) {
437
+ if (index_page != undefined) {
438
438
  WebsiteConfiguration.IndexDocument = { Suffix: index_page };
439
439
  }
440
440
  if (bucket_redirects.length > 0) {
@@ -485,7 +485,7 @@ export function putCorsRules(bucket, cors_rules) {
485
485
  ExposeHeaders: rule.expose_headers,
486
486
  });
487
487
  }
488
- yield wrapS3Call(`when writing the bucket CORS config`, [200], () => bucket.client.send(new PutBucketCorsCommand({
488
+ yield wrapS3Call(`write the bucket CORS config`, [200], () => bucket.client.send(new PutBucketCorsCommand({
489
489
  Bucket: bucket.name,
490
490
  CORSConfiguration: { CORSRules },
491
491
  })));
@@ -3,7 +3,7 @@ name: Deploy with GitHub Actions
3
3
  # You will need to:
4
4
  # 1. Get (from Guichet web interface):
5
5
  # - Your access keys (ID and secret): in the "S3" tab of your website
6
- # - The website id: your sub-domain (the part before .web.deuxfleurs.fr) or your full custom domain (e.g. your-domain.com)
6
+ # - The website id: your sub-domain (e.g. something.deuxfleurs.eu|page) or your full custom domain (e.g. your-domain.com)
7
7
  # 2. Setup the access keys as secrets in GitHub web interface (https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/using-secrets-in-github-actions), named in this example key_id and key_secret
8
8
  # 3. If you use a deuxfleurs.toml config, be sure the dxfl deploy command is launch in the current directory its in.
9
9
 
@@ -3,7 +3,7 @@
3
3
  # You will need to:
4
4
  # 1. Get (from Guichet web interface):
5
5
  # - Your access keys (ID and secret): in the "S3" tab of your website
6
- # - The website id: your sub-domain (the part before .web.deuxfleurs.fr) or your full custom domain (e.g. your-domain.com)
6
+ # - The website id: your sub-domain (e.g. something.deuxfleurs.eu|page) or your full custom domain (e.g. your-domain.com)
7
7
  # 2. Setup the access keys as secrets in Woodpecker web interface (https://woodpecker-ci.org/docs/usage/secrets), named in this example key_id and key_secret
8
8
  # 3. If you use a deuxfleurs.toml config, be sure the dxfl deploy command is launch in the current directory its in.
9
9
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dxfl",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "",
5
5
  "license": "EUPL-1.2",
6
6
  "author": "Deuxfleurs Team <coucou@deuxfleurs.fr>",
@@ -20,18 +20,18 @@
20
20
  "prettier-check": "npx prettier . --check"
21
21
  },
22
22
  "dependencies": {
23
- "@aws-sdk/client-s3": "^3.750.0",
24
- "@commander-js/extra-typings": "^13.1.0",
23
+ "@aws-sdk/client-s3": "^3.1004.0",
24
+ "@commander-js/extra-typings": "^14.0.0",
25
25
  "@supercharge/promise-pool": "^3.2.0",
26
- "@types/node": "^22.13.5",
26
+ "@types/node": "^25.2.1",
27
27
  "cli-color": "^2.0.4",
28
- "commander": "^13.1.0",
29
- "fast-uri": "^3.0.6",
28
+ "commander": "^14.0.3",
29
+ "fast-uri": "^3.1.0",
30
30
  "guichet-sdk-ts": "^0.1.0",
31
- "mime": "^4.0.6",
32
- "read": "^4.1.0",
33
- "smol-toml": "^1.3.4",
34
- "typescript": "^5.7.3",
31
+ "mime": "^4.1.0",
32
+ "read": "^5.0.1",
33
+ "smol-toml": "^1.6.0",
34
+ "typescript": "^5.9.3",
35
35
  "zod": "^3.24.4",
36
36
  "zod-validation-error": "^3.4.1"
37
37
  },