@reventlessdev/reventless-aws 3.0.0-alpha.355 → 3.0.0-alpha.356

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.
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
4
4
  import * as Stdlib_Result from "@rescript/runtime/lib/es6/Stdlib_Result.js";
5
+ import * as CliArgs$Reventless from "@reventlessdev/reventless-spec/src/CliArgs.res.mjs";
5
6
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
6
7
  import * as ClientDynamodb from "@aws-sdk/client-dynamodb";
7
8
  import * as DynamoDb_DynamoDb$AwsSdk from "@reventlessdev/rescript-aws-sdk/src/DynamoDb_DynamoDb.res.mjs";
@@ -15,123 +16,41 @@ import * as Auth_ActiveRoleStore_Schema$ReventlessAws from "../src/adapter/Auth/
15
16
  let defaultPoolName = "ReventlessIdentity";
16
17
 
17
18
  function parseArgs(argv) {
18
- let acc = {
19
- TAG: "Ok",
20
- _0: {
21
- poolName: defaultPoolName,
22
- providerId: undefined,
23
- loginIdentifier: Auth_LoginIdentifier$ReventlessAws.default,
24
- signUpMode: Auth_SignUpMode$ReventlessAws.default,
25
- help: false
26
- }
27
- };
28
- let i = 0;
29
- let count = argv.length;
30
- while (i < count) {
31
- let flag = argv[i];
32
- let value = argv[i + 1 | 0];
33
- let match = acc;
34
- let exit = 0;
35
- if (match.TAG === "Ok") {
36
- let a = match._0;
37
- let exit$1 = 0;
38
- switch (flag) {
39
- case "--login-identifier" :
40
- if (value !== undefined) {
41
- acc = Stdlib_Result.map(Auth_LoginIdentifier$ReventlessAws.parse(value), loginIdentifier => ({
42
- poolName: a.poolName,
43
- providerId: a.providerId,
44
- loginIdentifier: loginIdentifier,
45
- signUpMode: a.signUpMode,
46
- help: a.help
47
- }));
48
- i = i + 2 | 0;
49
- } else {
50
- exit = 1;
51
- }
52
- break;
53
- case "--name" :
54
- if (value !== undefined) {
55
- acc = {
56
- TAG: "Ok",
57
- _0: {
58
- poolName: value,
59
- providerId: a.providerId,
60
- loginIdentifier: a.loginIdentifier,
61
- signUpMode: a.signUpMode,
62
- help: a.help
63
- }
64
- };
65
- i = i + 2 | 0;
66
- } else {
67
- exit = 1;
68
- }
69
- break;
70
- case "--provider-id" :
71
- if (value !== undefined) {
72
- acc = {
73
- TAG: "Ok",
74
- _0: {
75
- poolName: a.poolName,
76
- providerId: value,
77
- loginIdentifier: a.loginIdentifier,
78
- signUpMode: a.signUpMode,
79
- help: a.help
80
- }
81
- };
82
- i = i + 2 | 0;
83
- } else {
84
- exit = 1;
85
- }
86
- break;
87
- case "--sign-up-mode" :
88
- if (value !== undefined) {
89
- acc = Stdlib_Result.map(Auth_SignUpMode$ReventlessAws.parse(value), signUpMode => ({
90
- poolName: a.poolName,
91
- providerId: a.providerId,
92
- loginIdentifier: a.loginIdentifier,
93
- signUpMode: signUpMode,
94
- help: a.help
95
- }));
96
- i = i + 2 | 0;
97
- } else {
98
- exit = 1;
99
- }
100
- break;
101
- case "--help" :
102
- case "-h" :
103
- exit$1 = 2;
104
- break;
105
- default:
106
- acc = {
107
- TAG: "Error",
108
- _0: `unknown argument "` + flag + `"`
109
- };
110
- }
111
- if (exit$1 === 2) {
112
- acc = {
19
+ return Stdlib_Result.flatMap(Stdlib_Result.flatMap(CliArgs$Reventless.parse([
20
+ "name",
21
+ "provider-id",
22
+ "login-identifier",
23
+ "sign-up-mode"
24
+ ], undefined, undefined, undefined, argv), CliArgs$Reventless.noPositionals), a => {
25
+ let v = CliArgs$Reventless.string(a, "login-identifier");
26
+ let loginIdentifier = v !== undefined ? Auth_LoginIdentifier$ReventlessAws.parse(v) : ({
27
+ TAG: "Ok",
28
+ _0: Auth_LoginIdentifier$ReventlessAws.default
29
+ });
30
+ let v$1 = CliArgs$Reventless.string(a, "sign-up-mode");
31
+ let signUpMode = v$1 !== undefined ? Auth_SignUpMode$ReventlessAws.parse(v$1) : ({
32
+ TAG: "Ok",
33
+ _0: Auth_SignUpMode$ReventlessAws.default
34
+ });
35
+ if (loginIdentifier.TAG === "Ok") {
36
+ if (signUpMode.TAG === "Ok") {
37
+ return {
113
38
  TAG: "Ok",
114
39
  _0: {
115
- poolName: a.poolName,
116
- providerId: a.providerId,
117
- loginIdentifier: a.loginIdentifier,
118
- signUpMode: a.signUpMode,
119
- help: true
40
+ poolName: Stdlib_Option.getOr(CliArgs$Reventless.string(a, "name"), defaultPoolName),
41
+ providerId: CliArgs$Reventless.string(a, "provider-id"),
42
+ loginIdentifier: loginIdentifier._0,
43
+ signUpMode: signUpMode._0,
44
+ help: CliArgs$Reventless.help(a)
120
45
  }
121
46
  };
122
- i = i + 1 | 0;
47
+ } else {
48
+ return signUpMode;
123
49
  }
124
50
  } else {
125
- i = count;
126
- }
127
- if (exit === 1) {
128
- acc = {
129
- TAG: "Error",
130
- _0: flag + ` needs a value`
131
- };
51
+ return loginIdentifier;
132
52
  }
133
- };
134
- return acc;
53
+ });
135
54
  }
136
55
 
137
56
  let _loginIdentifiers = Auth_LoginIdentifier$ReventlessAws.all.map(Auth_LoginIdentifier$ReventlessAws.toString).join(" | ");
@@ -143,6 +62,8 @@ let _signUpModes = Auth_SignUpMode$ReventlessAws.all.map(Auth_SignUpMode$Reventl
143
62
  let _defaultSignUpMode = Auth_SignUpMode$ReventlessAws.toString(Auth_SignUpMode$ReventlessAws.default);
144
63
 
145
64
  let usage = `
65
+ Usage: provision-identity [--name <name>] [--provider-id <id>] [--login-identifier <a>] [--sign-up-mode <m>]
66
+
146
67
  Provision a Reventless identity provider and its active-role store.
147
68
 
148
69
  --name <name> Pool name to create or adopt (default: ` + defaultPoolName + `)
@@ -369,29 +290,17 @@ is needed on a pool created here and on one a stack created for itself alike. Se
369
290
  [ProvisionAdmin].`;
370
291
  }
371
292
 
372
- async function run() {
373
- let e = parseArgs(process.argv.slice(2, process.argv.length));
293
+ async function run(args) {
294
+ let e = await resolvePool(args);
374
295
  if (e.TAG !== "Ok") {
375
296
  return e;
376
297
  }
377
- let args = e._0;
378
- if (args.help) {
379
- console.log(usage);
380
- return {
381
- TAG: "Ok",
382
- _0: undefined
383
- };
384
- }
385
- let e$1 = await resolvePool(args);
298
+ let providerId = e._0;
299
+ let tableName = Auth_ActiveRoleStore_Schema$ReventlessAws.derivedStoreName(providerId);
300
+ let e$1 = await provisionStore(tableName);
386
301
  if (e$1.TAG !== "Ok") {
387
302
  return e$1;
388
303
  }
389
- let providerId = e$1._0;
390
- let tableName = Auth_ActiveRoleStore_Schema$ReventlessAws.derivedStoreName(providerId);
391
- let e$2 = await provisionStore(tableName);
392
- if (e$2.TAG !== "Ok") {
393
- return e$2;
394
- }
395
304
  console.log(nextSteps(providerId));
396
305
  return {
397
306
  TAG: "Ok",
@@ -399,21 +308,29 @@ async function run() {
399
308
  };
400
309
  }
401
310
 
402
- async function main() {
403
- let message;
404
- try {
405
- message = await run();
406
- } catch (raw_exn) {
407
- let exn = Primitive_exceptions.internalToException(raw_exn);
408
- console.error(`provision-identity: ` + Util_AwsError$ReventlessAws.describe(exn));
311
+ let cli = {
312
+ bin: "provision-identity",
313
+ usage: usage,
314
+ parse: parseArgs
315
+ };
316
+
317
+ function main() {
318
+ return CliArgs$Reventless.run(cli, undefined, undefined, async args => {
319
+ let message;
320
+ try {
321
+ message = await run(args);
322
+ } catch (raw_exn) {
323
+ let exn = Primitive_exceptions.internalToException(raw_exn);
324
+ console.error(`provision-identity: ` + Util_AwsError$ReventlessAws.describe(exn));
325
+ process.exit(1);
326
+ return;
327
+ }
328
+ if (message.TAG === "Ok") {
329
+ return;
330
+ }
331
+ console.error(`provision-identity: ` + message._0);
409
332
  process.exit(1);
410
- return;
411
- }
412
- if (message.TAG === "Ok") {
413
- return;
414
- }
415
- console.error(`provision-identity: ` + message._0);
416
- process.exit(1);
333
+ });
417
334
  }
418
335
 
419
336
  let Schema;
@@ -436,6 +353,7 @@ export {
436
353
  provisionStore,
437
354
  nextSteps,
438
355
  run,
356
+ cli,
439
357
  main,
440
358
  }
441
359
  /* _loginIdentifiers Not a pure module */
@@ -0,0 +1,94 @@
1
+ open JestGlobals
2
+
3
+ // How this package's five bins behave on the command line, as a person or a
4
+ // script meets them: help anywhere answers with the usage and exit 0, a usage
5
+ // mistake names itself and shows the usage on stderr with exit 2. Exit 1 is
6
+ // left to a run that failed, so a caller can tell the two apart.
7
+
8
+ module CliArgs = Reventless.CliArgs
9
+
10
+ let answersLikeEveryTool = (cli: CliArgs.cli<'args>, ~mistake, ~message) =>
11
+ test(`${cli.bin}: --help and a usage mistake`, async () => {
12
+ let usage = cli.usage->String.trim
13
+ expect(usage->String.startsWith(`Usage: ${cli.bin} `))->toBe(true)
14
+ let help = {CliArgs.stdout: [usage], stderr: [], exitCode: Some(0), reachedMain: false}
15
+ expect(await CliArgs.observe(cli, ["-h"]))->toEqual(help)
16
+ // Help wins: whoever asks what a tool takes is least sure of their arguments.
17
+ expect(await CliArgs.observe(cli, mistake->Array.concat(["--help"])))->toEqual(help)
18
+ expect(await CliArgs.observe(cli, mistake))->toEqual({
19
+ CliArgs.stdout: [],
20
+ stderr: [`${cli.bin}: ${message}\n\n${usage}`],
21
+ exitCode: Some(2),
22
+ reachedMain: false,
23
+ })
24
+ })
25
+
26
+ describe("every bin", () => {
27
+ answersLikeEveryTool(
28
+ DeployApp.cli,
29
+ ~mistake=["up", "--stak", "x"],
30
+ ~message=`unknown argument "--stak"`,
31
+ )
32
+ answersLikeEveryTool(
33
+ BakeManifest.cli,
34
+ ~mistake=["--stak", "x"],
35
+ ~message=`unknown argument "--stak"`,
36
+ )
37
+ answersLikeEveryTool(
38
+ ProvisionAccounts.cli,
39
+ ~mistake=["--pool", "x"],
40
+ ~message=`unknown argument "--pool"`,
41
+ )
42
+ answersLikeEveryTool(
43
+ ProvisionAdmin.cli,
44
+ ~mistake=["--email", "me@example.com", "stray"],
45
+ ~message=`unknown argument "stray"`,
46
+ )
47
+ answersLikeEveryTool(
48
+ ProvisionIdentity.cli,
49
+ ~mistake=["--provider_id", "x"],
50
+ ~message=`unknown argument "--provider_id"`,
51
+ )
52
+ })
53
+
54
+ describe("a string flag's value", () => {
55
+ // Read literally, `--manifest --stack try` deploys with the manifest
56
+ // "--stack". Nobody who typed it meant that.
57
+ testSync("is never the next flag", () =>
58
+ expect(DeployApp.parseArgs(["up", "--manifest", "--stack", "try"]))->toEqual(
59
+ Error("--manifest needs a value"),
60
+ )
61
+ )
62
+
63
+ testSync("may be given inline", () =>
64
+ expect(DeployApp.parseArgs(["down", "--manifest=../m.yaml", "--stack=try"]))->toEqual(
65
+ Ok({DeployApp.command: Some(Down), manifest: Some("../m.yaml"), stack: "try", help: false}),
66
+ )
67
+ )
68
+
69
+ testSync("--since may be empty inline, as CI can pass it", () =>
70
+ expect(BakeManifest.parseArgs(["--since="])->Result.map(a => a.since))->toEqual(Ok(None))
71
+ )
72
+ })
73
+
74
+ describe("a bare invocation", () => {
75
+ test("deploy-app has to be told up or down", async () => {
76
+ let observed = await CliArgs.observe(DeployApp.cli, [])
77
+ expect((
78
+ observed.exitCode,
79
+ observed.stderr->Array.get(0)->Option.map(e => e->String.split("\n")->Array.getUnsafe(0)),
80
+ ))->toEqual((Some(2), Some("deploy-app: say `up` or `down`")))
81
+ })
82
+
83
+ test("provision-admin has to be told whom to make", async () => {
84
+ let observed = await CliArgs.observe(ProvisionAdmin.cli, [])
85
+ expect(observed.exitCode)->toEqual(Some(2))
86
+ expect(observed.stderr->Array.join("")->String.includes("--email is required"))->toBe(true)
87
+ })
88
+
89
+ test("the tools that need nothing run", async () => {
90
+ expect((await CliArgs.observe(BakeManifest.cli, [])).reachedMain)->toBe(true)
91
+ expect((await CliArgs.observe(ProvisionAccounts.cli, [])).reachedMain)->toBe(true)
92
+ expect((await CliArgs.observe(ProvisionIdentity.cli, [])).reachedMain)->toBe(true)
93
+ })
94
+ })
@@ -0,0 +1,125 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
4
+ import * as Stdlib_Result from "@rescript/runtime/lib/es6/Stdlib_Result.js";
5
+ import * as CliArgs$Reventless from "@reventlessdev/reventless-spec/src/CliArgs.res.mjs";
6
+ import * as DeployApp$ReventlessAws from "../scripts/DeployApp.res.mjs";
7
+ import * as BakeManifest$ReventlessAws from "../scripts/BakeManifest.res.mjs";
8
+ import * as ProvisionAdmin$ReventlessAws from "../scripts/ProvisionAdmin.res.mjs";
9
+ import * as ProvisionAccounts$ReventlessAws from "../scripts/ProvisionAccounts.res.mjs";
10
+ import * as ProvisionIdentity$ReventlessAws from "../scripts/ProvisionIdentity.res.mjs";
11
+
12
+ function answersLikeEveryTool(cli, mistake, message) {
13
+ globalThis.test(cli.bin + `: --help and a usage mistake`, async () => {
14
+ let usage = cli.usage.trim();
15
+ globalThis.expect(usage.startsWith(`Usage: ` + cli.bin + ` `)).toBe(true);
16
+ let help_stdout = [usage];
17
+ let help_stderr = [];
18
+ let help_exitCode = 0;
19
+ let help = {
20
+ stdout: help_stdout,
21
+ stderr: help_stderr,
22
+ exitCode: help_exitCode,
23
+ reachedMain: false
24
+ };
25
+ globalThis.expect(await CliArgs$Reventless.observe(cli, ["-h"])).toEqual(help);
26
+ globalThis.expect(await CliArgs$Reventless.observe(cli, mistake.concat(["--help"]))).toEqual(help);
27
+ globalThis.expect(await CliArgs$Reventless.observe(cli, mistake)).toEqual({
28
+ stdout: [],
29
+ stderr: [cli.bin + `: ` + message + `\n\n` + usage],
30
+ exitCode: 2,
31
+ reachedMain: false
32
+ });
33
+ });
34
+ }
35
+
36
+ globalThis.describe("every bin", () => {
37
+ answersLikeEveryTool(DeployApp$ReventlessAws.cli, [
38
+ "up",
39
+ "--stak",
40
+ "x"
41
+ ], `unknown argument "--stak"`);
42
+ answersLikeEveryTool(BakeManifest$ReventlessAws.cli, [
43
+ "--stak",
44
+ "x"
45
+ ], `unknown argument "--stak"`);
46
+ answersLikeEveryTool(ProvisionAccounts$ReventlessAws.cli, [
47
+ "--pool",
48
+ "x"
49
+ ], `unknown argument "--pool"`);
50
+ answersLikeEveryTool(ProvisionAdmin$ReventlessAws.cli, [
51
+ "--email",
52
+ "me@example.com",
53
+ "stray"
54
+ ], `unknown argument "stray"`);
55
+ answersLikeEveryTool(ProvisionIdentity$ReventlessAws.cli, [
56
+ "--provider_id",
57
+ "x"
58
+ ], `unknown argument "--provider_id"`);
59
+ });
60
+
61
+ globalThis.describe("a string flag's value", () => {
62
+ globalThis.test("is never the next flag", () => {
63
+ globalThis.expect(DeployApp$ReventlessAws.parseArgs([
64
+ "up",
65
+ "--manifest",
66
+ "--stack",
67
+ "try"
68
+ ])).toEqual({
69
+ TAG: "Error",
70
+ _0: "--manifest needs a value"
71
+ });
72
+ });
73
+ globalThis.test("may be given inline", () => {
74
+ globalThis.expect(DeployApp$ReventlessAws.parseArgs([
75
+ "down",
76
+ "--manifest=../m.yaml",
77
+ "--stack=try"
78
+ ])).toEqual({
79
+ TAG: "Ok",
80
+ _0: {
81
+ command: "Down",
82
+ manifest: "../m.yaml",
83
+ stack: "try",
84
+ help: false
85
+ }
86
+ });
87
+ });
88
+ globalThis.test("--since may be empty inline, as CI can pass it", () => {
89
+ globalThis.expect(Stdlib_Result.map(BakeManifest$ReventlessAws.parseArgs(["--since="]), a => a.since)).toEqual({
90
+ TAG: "Ok",
91
+ _0: undefined
92
+ });
93
+ });
94
+ });
95
+
96
+ globalThis.describe("a bare invocation", () => {
97
+ globalThis.test("deploy-app has to be told up or down", async () => {
98
+ let observed = await CliArgs$Reventless.observe(DeployApp$ReventlessAws.cli, []);
99
+ globalThis.expect([
100
+ observed.exitCode,
101
+ Stdlib_Option.map(observed.stderr[0], e => e.split("\n")[0])
102
+ ]).toEqual([
103
+ 2,
104
+ "deploy-app: say `up` or `down`"
105
+ ]);
106
+ });
107
+ globalThis.test("provision-admin has to be told whom to make", async () => {
108
+ let observed = await CliArgs$Reventless.observe(ProvisionAdmin$ReventlessAws.cli, []);
109
+ globalThis.expect(observed.exitCode).toEqual(2);
110
+ globalThis.expect(observed.stderr.join("").includes("--email is required")).toBe(true);
111
+ });
112
+ globalThis.test("the tools that need nothing run", async () => {
113
+ globalThis.expect((await CliArgs$Reventless.observe(BakeManifest$ReventlessAws.cli, [])).reachedMain).toBe(true);
114
+ globalThis.expect((await CliArgs$Reventless.observe(ProvisionAccounts$ReventlessAws.cli, [])).reachedMain).toBe(true);
115
+ globalThis.expect((await CliArgs$Reventless.observe(ProvisionIdentity$ReventlessAws.cli, [])).reachedMain).toBe(true);
116
+ });
117
+ });
118
+
119
+ let CliArgs;
120
+
121
+ export {
122
+ CliArgs,
123
+ answersLikeEveryTool,
124
+ }
125
+ /* Not a pure module */