@reventlessdev/reventless-seed 1.0.0-alpha.16 → 1.0.0-alpha.18
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 +14 -0
- package/lib/bs/.compiler.log +2 -2
- package/lib/bs/ReventlessSeed.cmi +0 -0
- package/lib/bs/ReventlessSeed.cmt +0 -0
- package/lib/bs/ReventlessSeed.mlmap +3 -0
- package/lib/bs/compiler-info.json +1 -1
- package/lib/bs/src/Seed-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed.ast +0 -0
- package/lib/bs/src/Seed.res +1 -0
- package/lib/bs/src/Seed.res.mjs +3 -0
- package/lib/bs/src/Seed_Client-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Client-ReventlessSeed.cmj +0 -0
- package/lib/bs/src/Seed_Client-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Client.ast +0 -0
- package/lib/bs/src/Seed_Client.res +67 -11
- package/lib/bs/src/Seed_Client.res.mjs +60 -20
- package/lib/bs/src/Seed_Connect-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Connect-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Prompt-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Prompt-ReventlessSeed.cmj +0 -0
- package/lib/bs/src/Seed_Prompt-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Prompt.ast +0 -0
- package/lib/bs/src/Seed_Prompt.res +82 -15
- package/lib/bs/src/Seed_Prompt.res.mjs +59 -7
- package/lib/bs/src/Seed_Runner-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Runner-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Runner.res.mjs +1 -1
- package/lib/bs/src/Seed_Upload-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Upload-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Users-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Users-ReventlessSeed.cmj +0 -0
- package/lib/bs/src/Seed_Users-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Users.ast +0 -0
- package/lib/bs/src/Seed_Users.res +80 -0
- package/lib/bs/src/Seed_Users.res.mjs +90 -0
- package/lib/bs/tests/Seed_ClientTest-ReventlessSeed.cmi +0 -0
- package/lib/bs/tests/Seed_ClientTest-ReventlessSeed.cmj +0 -0
- package/lib/bs/tests/Seed_ClientTest-ReventlessSeed.cmt +0 -0
- package/lib/bs/tests/Seed_ClientTest.ast +0 -0
- package/lib/bs/tests/Seed_ClientTest.res +59 -0
- package/lib/bs/tests/Seed_ClientTest.res.mjs +64 -0
- package/lib/bs/tests/Seed_PromptTest-ReventlessSeed.cmi +0 -0
- package/lib/bs/tests/Seed_PromptTest-ReventlessSeed.cmt +0 -0
- package/lib/bs/tests/Seed_RandomTest-ReventlessSeed.cmt +0 -0
- package/lib/bs/tests/Seed_UsersTest-ReventlessSeed.cmi +0 -0
- package/lib/bs/tests/Seed_UsersTest-ReventlessSeed.cmj +0 -0
- package/lib/bs/tests/Seed_UsersTest-ReventlessSeed.cmt +0 -0
- package/lib/bs/tests/Seed_UsersTest.ast +0 -0
- package/lib/bs/tests/Seed_UsersTest.res +92 -0
- package/lib/bs/tests/Seed_UsersTest.res.mjs +95 -0
- package/lib/ocaml/.compiler.log +2 -2
- package/lib/ocaml/ReventlessSeed.cmi +0 -0
- package/lib/ocaml/ReventlessSeed.cmt +0 -0
- package/lib/ocaml/ReventlessSeed.mlmap +3 -0
- package/lib/ocaml/Seed-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed.ast +0 -0
- package/lib/ocaml/Seed.res +1 -0
- package/lib/ocaml/Seed_Client-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Client-ReventlessSeed.cmj +0 -0
- package/lib/ocaml/Seed_Client-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Client.ast +0 -0
- package/lib/ocaml/Seed_Client.res +67 -11
- package/lib/ocaml/Seed_ClientTest-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_ClientTest-ReventlessSeed.cmj +0 -0
- package/lib/ocaml/Seed_ClientTest-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_ClientTest.ast +0 -0
- package/lib/ocaml/Seed_ClientTest.res +59 -0
- package/lib/ocaml/Seed_Connect-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Connect-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Prompt-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Prompt-ReventlessSeed.cmj +0 -0
- package/lib/ocaml/Seed_Prompt-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Prompt.ast +0 -0
- package/lib/ocaml/Seed_Prompt.res +82 -15
- package/lib/ocaml/Seed_PromptTest-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_PromptTest-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_RandomTest-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Runner-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Runner-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Upload-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Upload-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Users-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Users-ReventlessSeed.cmj +0 -0
- package/lib/ocaml/Seed_Users-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Users.ast +0 -0
- package/lib/ocaml/Seed_Users.res +80 -0
- package/lib/ocaml/Seed_UsersTest-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_UsersTest-ReventlessSeed.cmj +0 -0
- package/lib/ocaml/Seed_UsersTest-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_UsersTest.ast +0 -0
- package/lib/ocaml/Seed_UsersTest.res +92 -0
- package/package.json +2 -1
- package/src/Seed.res +1 -0
- package/src/Seed.res.mjs +3 -0
- package/src/Seed_Client.res +67 -11
- package/src/Seed_Client.res.mjs +60 -20
- package/src/Seed_Prompt.res +82 -15
- package/src/Seed_Prompt.res.mjs +59 -7
- package/src/Seed_Runner.res.mjs +1 -1
- package/src/Seed_Users.res +80 -0
- package/src/Seed_Users.res.mjs +90 -0
- package/tests/Seed_ClientTest.res +59 -0
- package/tests/Seed_ClientTest.res.mjs +64 -0
- package/tests/Seed_UsersTest.res +92 -0
- package/tests/Seed_UsersTest.res.mjs +95 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
open JestGlobals
|
|
2
|
+
|
|
3
|
+
// `.reventless/users.yaml` is hand-maintained and shared with the auth adapter,
|
|
4
|
+
// so the seed reads it defensively: it must survive the comment blocks both
|
|
5
|
+
// copies carry, must not reorder the accounts (the first one is the prompt's
|
|
6
|
+
// default, so order IS the contract), and must never throw — a broken file costs
|
|
7
|
+
// the menu, not the run.
|
|
8
|
+
|
|
9
|
+
let document = `
|
|
10
|
+
# Local dev users — a comment block like the real file carries.
|
|
11
|
+
|
|
12
|
+
- username: admin
|
|
13
|
+
password: admin
|
|
14
|
+
groups: [Admin, Shopper]
|
|
15
|
+
userId: local-admin
|
|
16
|
+
|
|
17
|
+
- username: shopper
|
|
18
|
+
password: Shopper-2026!
|
|
19
|
+
groups: [Shopper]
|
|
20
|
+
|
|
21
|
+
- username: noGroups
|
|
22
|
+
password: pw
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
describe("Seed_Users.parseString:", () => {
|
|
26
|
+
testSync("reads every account, in the order the file defines them", () => {
|
|
27
|
+
let users = Seed_Users.parseString(document)
|
|
28
|
+
expect(users->Array.map(u => u.Seed_Users.username))->Expect.toEqual([
|
|
29
|
+
"admin",
|
|
30
|
+
"shopper",
|
|
31
|
+
"noGroups",
|
|
32
|
+
])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
testSync("carries the password beside the username", () => {
|
|
36
|
+
let users = Seed_Users.parseString(document)
|
|
37
|
+
expect(users->Array.map(u => u.Seed_Users.password))->Expect.toEqual([
|
|
38
|
+
"admin",
|
|
39
|
+
"Shopper-2026!",
|
|
40
|
+
"pw",
|
|
41
|
+
])
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
testSync("keeps the groups, and reads a missing groups key as none", () => {
|
|
45
|
+
let users = Seed_Users.parseString(document)
|
|
46
|
+
expect(users->Array.map(u => u.Seed_Users.groups))->Expect.toEqual([
|
|
47
|
+
["Admin", "Shopper"],
|
|
48
|
+
["Shopper"],
|
|
49
|
+
[],
|
|
50
|
+
])
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// An entry half-written by hand is the likely flaw in this file. Dropping it
|
|
54
|
+
// keeps the other accounts selectable; failing the parse would not.
|
|
55
|
+
testSync("skips an entry that names no password", () => {
|
|
56
|
+
let users = Seed_Users.parseString(`
|
|
57
|
+
- username: admin
|
|
58
|
+
password: admin
|
|
59
|
+
- username: halfWritten
|
|
60
|
+
groups: [Shopper]
|
|
61
|
+
`)
|
|
62
|
+
expect(users->Array.map(u => u.Seed_Users.username))->Expect.toEqual(["admin"])
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
testSync("yields no accounts for a document that is not a list", () => {
|
|
66
|
+
expect(Seed_Users.parseString("users: {}")->Array.length)->Expect.toBe(0)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
// The whole point of returning accounts rather than raising: the caller falls
|
|
70
|
+
// back to prompting, and it can only do that if nothing here escapes.
|
|
71
|
+
testSync("yields no accounts for malformed YAML instead of throwing", () => {
|
|
72
|
+
expect(Seed_Users.parseString("- username: [unclosed")->Array.length)->Expect.toBe(0)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe("Seed_Users.load:", () => {
|
|
77
|
+
testSync("is silent about a file that is not there", () => {
|
|
78
|
+
expect(Seed_Users.load(~path="/nonexistent/.reventless/users.yaml"))->Expect.toBe(None)
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
describe("Seed_Users.label:", () => {
|
|
83
|
+
testSync("names the groups an account carries", () => {
|
|
84
|
+
expect(
|
|
85
|
+
Seed_Users.label({username: "admin", password: "x", groups: ["Admin", "Shopper"]}),
|
|
86
|
+
)->Expect.toBe("admin [Admin, Shopper]")
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
testSync("is the bare username when the file records no groups", () => {
|
|
90
|
+
expect(Seed_Users.label({username: "admin", password: "x", groups: []}))->Expect.toBe("admin")
|
|
91
|
+
})
|
|
92
|
+
})
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Seed_Users$ReventlessSeed from "../src/Seed_Users.res.mjs";
|
|
4
|
+
|
|
5
|
+
let document = `
|
|
6
|
+
# Local dev users — a comment block like the real file carries.
|
|
7
|
+
|
|
8
|
+
- username: admin
|
|
9
|
+
password: admin
|
|
10
|
+
groups: [Admin, Shopper]
|
|
11
|
+
userId: local-admin
|
|
12
|
+
|
|
13
|
+
- username: shopper
|
|
14
|
+
password: Shopper-2026!
|
|
15
|
+
groups: [Shopper]
|
|
16
|
+
|
|
17
|
+
- username: noGroups
|
|
18
|
+
password: pw
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
globalThis.describe("Seed_Users.parseString:", () => {
|
|
22
|
+
globalThis.test("reads every account, in the order the file defines them", () => {
|
|
23
|
+
let users = Seed_Users$ReventlessSeed.parseString(document);
|
|
24
|
+
globalThis.expect(users.map(u => u.username)).toEqual([
|
|
25
|
+
"admin",
|
|
26
|
+
"shopper",
|
|
27
|
+
"noGroups"
|
|
28
|
+
]);
|
|
29
|
+
});
|
|
30
|
+
globalThis.test("carries the password beside the username", () => {
|
|
31
|
+
let users = Seed_Users$ReventlessSeed.parseString(document);
|
|
32
|
+
globalThis.expect(users.map(u => u.password)).toEqual([
|
|
33
|
+
"admin",
|
|
34
|
+
"Shopper-2026!",
|
|
35
|
+
"pw"
|
|
36
|
+
]);
|
|
37
|
+
});
|
|
38
|
+
globalThis.test("keeps the groups, and reads a missing groups key as none", () => {
|
|
39
|
+
let users = Seed_Users$ReventlessSeed.parseString(document);
|
|
40
|
+
globalThis.expect(users.map(u => u.groups)).toEqual([
|
|
41
|
+
[
|
|
42
|
+
"Admin",
|
|
43
|
+
"Shopper"
|
|
44
|
+
],
|
|
45
|
+
["Shopper"],
|
|
46
|
+
[]
|
|
47
|
+
]);
|
|
48
|
+
});
|
|
49
|
+
globalThis.test("skips an entry that names no password", () => {
|
|
50
|
+
let users = Seed_Users$ReventlessSeed.parseString(`
|
|
51
|
+
- username: admin
|
|
52
|
+
password: admin
|
|
53
|
+
- username: halfWritten
|
|
54
|
+
groups: [Shopper]
|
|
55
|
+
`);
|
|
56
|
+
globalThis.expect(users.map(u => u.username)).toEqual(["admin"]);
|
|
57
|
+
});
|
|
58
|
+
globalThis.test("yields no accounts for a document that is not a list", () => {
|
|
59
|
+
globalThis.expect(Seed_Users$ReventlessSeed.parseString("users: {}").length).toBe(0);
|
|
60
|
+
});
|
|
61
|
+
globalThis.test("yields no accounts for malformed YAML instead of throwing", () => {
|
|
62
|
+
globalThis.expect(Seed_Users$ReventlessSeed.parseString("- username: [unclosed").length).toBe(0);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
globalThis.describe("Seed_Users.load:", () => {
|
|
67
|
+
globalThis.test("is silent about a file that is not there", () => {
|
|
68
|
+
globalThis.expect(Seed_Users$ReventlessSeed.load("/nonexistent/.reventless/users.yaml")).toBe(undefined);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
globalThis.describe("Seed_Users.label:", () => {
|
|
73
|
+
globalThis.test("names the groups an account carries", () => {
|
|
74
|
+
globalThis.expect(Seed_Users$ReventlessSeed.label({
|
|
75
|
+
username: "admin",
|
|
76
|
+
password: "x",
|
|
77
|
+
groups: [
|
|
78
|
+
"Admin",
|
|
79
|
+
"Shopper"
|
|
80
|
+
]
|
|
81
|
+
})).toBe("admin [Admin, Shopper]");
|
|
82
|
+
});
|
|
83
|
+
globalThis.test("is the bare username when the file records no groups", () => {
|
|
84
|
+
globalThis.expect(Seed_Users$ReventlessSeed.label({
|
|
85
|
+
username: "admin",
|
|
86
|
+
password: "x",
|
|
87
|
+
groups: []
|
|
88
|
+
})).toBe("admin");
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
export {
|
|
93
|
+
document,
|
|
94
|
+
}
|
|
95
|
+
/* Not a pure module */
|