@sundaeswap/sprinkles 0.6.0 → 0.7.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/dist/cjs/Sprinkle/__tests__/action-integration.test.js +590 -0
- package/dist/cjs/Sprinkle/__tests__/action-integration.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/action-registry.test.js +193 -0
- package/dist/cjs/Sprinkle/__tests__/action-registry.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/action-runner.test.js +304 -0
- package/dist/cjs/Sprinkle/__tests__/action-runner.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js +1110 -0
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js +722 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +138 -0
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js +713 -0
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js +334 -0
- package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js +749 -0
- package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js +61 -0
- package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.js +117 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js +202 -0
- package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js +87 -0
- package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js +345 -0
- package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js +212 -0
- package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js +372 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/index.js +127 -0
- package/dist/cjs/Sprinkle/actions/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js +415 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/registry.js +92 -0
- package/dist/cjs/Sprinkle/actions/registry.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/runner.js +190 -0
- package/dist/cjs/Sprinkle/actions/runner.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/tui-helpers.js +96 -0
- package/dist/cjs/Sprinkle/actions/tui-helpers.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/types.js +68 -0
- package/dist/cjs/Sprinkle/actions/types.js.map +1 -0
- package/dist/cjs/Sprinkle/index.js +451 -4
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/cjs/Sprinkle/prompts.js +12 -7
- package/dist/cjs/Sprinkle/prompts.js.map +1 -1
- package/dist/cjs/Sprinkle/type-guards.js +7 -1
- package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/action-integration.test.js +588 -0
- package/dist/esm/Sprinkle/__tests__/action-integration.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/action-registry.test.js +192 -0
- package/dist/esm/Sprinkle/__tests__/action-registry.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/action-runner.test.js +302 -0
- package/dist/esm/Sprinkle/__tests__/action-runner.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js +1107 -0
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js +720 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +138 -0
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js +712 -0
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js +332 -0
- package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js +747 -0
- package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js +55 -0
- package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/index.js +32 -0
- package/dist/esm/Sprinkle/actions/builtin/index.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/profile-actions.js +197 -0
- package/dist/esm/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/settings-actions.js +81 -0
- package/dist/esm/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js +340 -0
- package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js +207 -0
- package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js +361 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/esm/Sprinkle/actions/index.js +12 -0
- package/dist/esm/Sprinkle/actions/index.js.map +1 -0
- package/dist/esm/Sprinkle/actions/mcp-adapter.js +407 -0
- package/dist/esm/Sprinkle/actions/mcp-adapter.js.map +1 -0
- package/dist/esm/Sprinkle/actions/registry.js +85 -0
- package/dist/esm/Sprinkle/actions/registry.js.map +1 -0
- package/dist/esm/Sprinkle/actions/runner.js +182 -0
- package/dist/esm/Sprinkle/actions/runner.js.map +1 -0
- package/dist/esm/Sprinkle/actions/tui-helpers.js +91 -0
- package/dist/esm/Sprinkle/actions/tui-helpers.js.map +1 -0
- package/dist/esm/Sprinkle/actions/types.js +61 -0
- package/dist/esm/Sprinkle/actions/types.js.map +1 -0
- package/dist/esm/Sprinkle/index.js +299 -4
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/prompts.js +12 -7
- package/dist/esm/Sprinkle/prompts.js.map +1 -1
- package/dist/esm/Sprinkle/type-guards.js +3 -0
- package/dist/esm/Sprinkle/type-guards.js.map +1 -1
- package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts +39 -0
- package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/index.d.ts +26 -0
- package/dist/types/Sprinkle/actions/builtin/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts +55 -0
- package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts +32 -0
- package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts +70 -0
- package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts +50 -0
- package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts +104 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/index.d.ts +12 -0
- package/dist/types/Sprinkle/actions/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +92 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/registry.d.ts +42 -0
- package/dist/types/Sprinkle/actions/registry.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/runner.d.ts +45 -0
- package/dist/types/Sprinkle/actions/runner.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/tui-helpers.d.ts +53 -0
- package/dist/types/Sprinkle/actions/tui-helpers.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/types.d.ts +76 -0
- package/dist/types/Sprinkle/actions/types.d.ts.map +1 -0
- package/dist/types/Sprinkle/index.d.ts +81 -1
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
- package/dist/types/Sprinkle/type-guards.d.ts +4 -1
- package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +9 -2
- package/src/Sprinkle/__tests__/action-integration.test.ts +558 -0
- package/src/Sprinkle/__tests__/action-registry.test.ts +187 -0
- package/src/Sprinkle/__tests__/action-runner.test.ts +324 -0
- package/src/Sprinkle/__tests__/builtin-actions.test.ts +1022 -0
- package/src/Sprinkle/__tests__/cli-adapter.test.ts +715 -0
- package/src/Sprinkle/__tests__/fill-in-struct.test.ts +144 -0
- package/src/Sprinkle/__tests__/mcp-adapter.test.ts +718 -0
- package/src/Sprinkle/__tests__/tui-helpers.test.ts +325 -0
- package/src/Sprinkle/__tests__/wallet-transaction-actions.test.ts +695 -0
- package/src/Sprinkle/actions/builtin/blaze-helper.ts +89 -0
- package/src/Sprinkle/actions/builtin/index.ts +86 -0
- package/src/Sprinkle/actions/builtin/profile-actions.ts +229 -0
- package/src/Sprinkle/actions/builtin/settings-actions.ts +99 -0
- package/src/Sprinkle/actions/builtin/transaction-actions.ts +381 -0
- package/src/Sprinkle/actions/builtin/wallet-actions.ts +233 -0
- package/src/Sprinkle/actions/cli-adapter.ts +430 -0
- package/src/Sprinkle/actions/index.ts +32 -0
- package/src/Sprinkle/actions/mcp-adapter.ts +463 -0
- package/src/Sprinkle/actions/registry.ts +97 -0
- package/src/Sprinkle/actions/runner.ts +200 -0
- package/src/Sprinkle/actions/tui-helpers.ts +114 -0
- package/src/Sprinkle/actions/types.ts +91 -0
- package/src/Sprinkle/index.ts +395 -3
- package/src/Sprinkle/prompts.ts +118 -72
- package/src/Sprinkle/type-guards.ts +9 -0
|
@@ -0,0 +1,1110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _bunTest = require("bun:test");
|
|
4
|
+
var fs = _interopRequireWildcard(require("fs"));
|
|
5
|
+
var path = _interopRequireWildcard(require("path"));
|
|
6
|
+
var os = _interopRequireWildcard(require("os"));
|
|
7
|
+
var _typebox = require("@sinclair/typebox");
|
|
8
|
+
var _index = require("../index.js");
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
|
+
// Helper: write a minimal profile file into a tmp storage directory
|
|
11
|
+
function writeTestProfile(storagePath, id, name, settings, description) {
|
|
12
|
+
const dir = path.join(storagePath, "profiles");
|
|
13
|
+
fs.mkdirSync(dir, {
|
|
14
|
+
recursive: true
|
|
15
|
+
});
|
|
16
|
+
const meta = {
|
|
17
|
+
name,
|
|
18
|
+
description,
|
|
19
|
+
createdAt: new Date().toISOString(),
|
|
20
|
+
updatedAt: new Date().toISOString()
|
|
21
|
+
};
|
|
22
|
+
fs.writeFileSync(path.join(dir, `${id}.json`), JSON.stringify({
|
|
23
|
+
meta,
|
|
24
|
+
settings,
|
|
25
|
+
defaults: {}
|
|
26
|
+
}, null, 2), "utf-8");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Settings schema with a sensitive field for masking tests
|
|
30
|
+
const TestSchema = _typebox.Type.Object({
|
|
31
|
+
name: _typebox.Type.String(),
|
|
32
|
+
token: _typebox.Type.Optional(_typebox.Type.String({
|
|
33
|
+
sensitive: true
|
|
34
|
+
}))
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Simple schema without sensitive fields
|
|
38
|
+
const SimpleSchema = _typebox.Type.Object({
|
|
39
|
+
name: _typebox.Type.String()
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Helper: create a Sprinkle with a loaded profile ready for action execution
|
|
43
|
+
async function makeSprinkle(storagePath, profileId = "default", settings = {
|
|
44
|
+
name: "tester"
|
|
45
|
+
}) {
|
|
46
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, storagePath);
|
|
47
|
+
writeTestProfile(storagePath, profileId, "Default", settings);
|
|
48
|
+
await sprinkle.loadProfile(profileId);
|
|
49
|
+
return sprinkle;
|
|
50
|
+
}
|
|
51
|
+
(0, _bunTest.describe)("getBuiltinActions", () => {
|
|
52
|
+
(0, _bunTest.test)("returns an array of 14 actions", () => {
|
|
53
|
+
const actions = (0, _index.getBuiltinActions)();
|
|
54
|
+
(0, _bunTest.expect)(actions).toHaveLength(14);
|
|
55
|
+
});
|
|
56
|
+
(0, _bunTest.test)("all actions have a category", () => {
|
|
57
|
+
const actions = (0, _index.getBuiltinActions)();
|
|
58
|
+
const validCategories = ["sprinkles", "wallet", "transaction"];
|
|
59
|
+
for (const action of actions) {
|
|
60
|
+
(0, _bunTest.expect)(validCategories).toContain(action.category);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
(0, _bunTest.test)("returns actions with expected names", () => {
|
|
64
|
+
const names = (0, _index.getBuiltinActions)().map(a => a.name);
|
|
65
|
+
(0, _bunTest.expect)(names).toContain("list-profiles");
|
|
66
|
+
(0, _bunTest.expect)(names).toContain("get-profile");
|
|
67
|
+
(0, _bunTest.expect)(names).toContain("set-profile");
|
|
68
|
+
(0, _bunTest.expect)(names).toContain("create-profile");
|
|
69
|
+
(0, _bunTest.expect)(names).toContain("delete-profile");
|
|
70
|
+
(0, _bunTest.expect)(names).toContain("get-settings");
|
|
71
|
+
(0, _bunTest.expect)(names).toContain("update-settings");
|
|
72
|
+
});
|
|
73
|
+
(0, _bunTest.test)("all actions have inputSchema and outputSchema", () => {
|
|
74
|
+
const actions = (0, _index.getBuiltinActions)();
|
|
75
|
+
for (const action of actions) {
|
|
76
|
+
(0, _bunTest.expect)(action.inputSchema).toBeDefined();
|
|
77
|
+
(0, _bunTest.expect)(action.outputSchema).toBeDefined();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
(0, _bunTest.test)("built-in actions can be registered on a Sprinkle instance", () => {
|
|
81
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, os.tmpdir());
|
|
82
|
+
const actions = (0, _index.getBuiltinActions)();
|
|
83
|
+
for (const action of actions) {
|
|
84
|
+
sprinkle.registerAction(action);
|
|
85
|
+
}
|
|
86
|
+
(0, _bunTest.expect)(sprinkle.listActions()).toHaveLength(14);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// list-profiles
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
(0, _bunTest.describe)("list-profiles action", () => {
|
|
95
|
+
let tmpDir;
|
|
96
|
+
(0, _bunTest.beforeEach)(() => {
|
|
97
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
98
|
+
});
|
|
99
|
+
(0, _bunTest.afterEach)(() => {
|
|
100
|
+
fs.rmSync(tmpDir, {
|
|
101
|
+
recursive: true,
|
|
102
|
+
force: true
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
(0, _bunTest.test)("returns empty profiles array when no profiles exist", async () => {
|
|
106
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
107
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
108
|
+
sprinkle.registerAction(action);
|
|
109
|
+
}
|
|
110
|
+
const result = await sprinkle.runAction("list-profiles", {});
|
|
111
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
112
|
+
if (result.success) {
|
|
113
|
+
(0, _bunTest.expect)(result.data.profiles).toEqual([]);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
(0, _bunTest.test)("returns all profiles with expected fields", async () => {
|
|
117
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
118
|
+
name: "alice"
|
|
119
|
+
});
|
|
120
|
+
writeTestProfile(tmpDir, "bob", "Bob", {
|
|
121
|
+
name: "bob"
|
|
122
|
+
});
|
|
123
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
124
|
+
await sprinkle.loadProfile("alice");
|
|
125
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
126
|
+
sprinkle.registerAction(action);
|
|
127
|
+
}
|
|
128
|
+
const result = await sprinkle.runAction("list-profiles", {});
|
|
129
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
130
|
+
if (result.success) {
|
|
131
|
+
(0, _bunTest.expect)(result.data.profiles).toHaveLength(2);
|
|
132
|
+
const names = result.data.profiles.map(p => p.name);
|
|
133
|
+
(0, _bunTest.expect)(names).toContain("Alice");
|
|
134
|
+
(0, _bunTest.expect)(names).toContain("Bob");
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
(0, _bunTest.test)("includes activeProfileId when a profile is loaded", async () => {
|
|
138
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
139
|
+
name: "tester"
|
|
140
|
+
});
|
|
141
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
142
|
+
await sprinkle.loadProfile("default");
|
|
143
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
144
|
+
sprinkle.registerAction(action);
|
|
145
|
+
}
|
|
146
|
+
const result = await sprinkle.runAction("list-profiles", {});
|
|
147
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
148
|
+
if (result.success) {
|
|
149
|
+
(0, _bunTest.expect)(result.data.activeProfileId).toBe("default");
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
(0, _bunTest.test)("activeProfileId is undefined when no profile is loaded", async () => {
|
|
153
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
154
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
155
|
+
sprinkle.registerAction(action);
|
|
156
|
+
}
|
|
157
|
+
const result = await sprinkle.runAction("list-profiles", {});
|
|
158
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
159
|
+
if (result.success) {
|
|
160
|
+
(0, _bunTest.expect)(result.data.activeProfileId).toBeUndefined();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
(0, _bunTest.test)("each profile entry contains id, name, createdAt, updatedAt", async () => {
|
|
164
|
+
writeTestProfile(tmpDir, "alpha", "Alpha Profile", {
|
|
165
|
+
name: "alpha"
|
|
166
|
+
}, "A profile");
|
|
167
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
168
|
+
await sprinkle.loadProfile("alpha");
|
|
169
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
170
|
+
sprinkle.registerAction(action);
|
|
171
|
+
}
|
|
172
|
+
const result = await sprinkle.runAction("list-profiles", {});
|
|
173
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
174
|
+
if (result.success) {
|
|
175
|
+
const profile = result.data.profiles[0];
|
|
176
|
+
(0, _bunTest.expect)(profile.id).toBe("alpha");
|
|
177
|
+
(0, _bunTest.expect)(profile.name).toBe("Alpha Profile");
|
|
178
|
+
(0, _bunTest.expect)(profile.description).toBe("A profile");
|
|
179
|
+
(0, _bunTest.expect)(profile.createdAt).toBeDefined();
|
|
180
|
+
(0, _bunTest.expect)(profile.updatedAt).toBeDefined();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
// get-profile
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
(0, _bunTest.describe)("get-profile action", () => {
|
|
190
|
+
let tmpDir;
|
|
191
|
+
(0, _bunTest.beforeEach)(() => {
|
|
192
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
193
|
+
});
|
|
194
|
+
(0, _bunTest.afterEach)(() => {
|
|
195
|
+
fs.rmSync(tmpDir, {
|
|
196
|
+
recursive: true,
|
|
197
|
+
force: true
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
(0, _bunTest.test)("returns profile metadata and settings for a valid id", async () => {
|
|
201
|
+
writeTestProfile(tmpDir, "myprofile", "My Profile", {
|
|
202
|
+
name: "hello"
|
|
203
|
+
});
|
|
204
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
205
|
+
await sprinkle.loadProfile("myprofile");
|
|
206
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
207
|
+
sprinkle.registerAction(action);
|
|
208
|
+
}
|
|
209
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
210
|
+
id: "myprofile"
|
|
211
|
+
});
|
|
212
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
213
|
+
if (result.success) {
|
|
214
|
+
(0, _bunTest.expect)(result.data.id).toBe("myprofile");
|
|
215
|
+
(0, _bunTest.expect)(result.data.name).toBe("My Profile");
|
|
216
|
+
(0, _bunTest.expect)(result.data.settings).toBeDefined();
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
(0, _bunTest.test)("returns PROFILE_NOT_FOUND for unknown profile id", async () => {
|
|
220
|
+
writeTestProfile(tmpDir, "existing", "Existing", {
|
|
221
|
+
name: "x"
|
|
222
|
+
});
|
|
223
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
224
|
+
await sprinkle.loadProfile("existing");
|
|
225
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
226
|
+
sprinkle.registerAction(action);
|
|
227
|
+
}
|
|
228
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
229
|
+
id: "no-such-profile"
|
|
230
|
+
});
|
|
231
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
232
|
+
if (!result.success) {
|
|
233
|
+
(0, _bunTest.expect)(result.error.code).toBe("PROFILE_NOT_FOUND");
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
(0, _bunTest.test)("settings are returned when includeSensitive is not specified (defaults to masked)", async () => {
|
|
237
|
+
writeTestProfile(tmpDir, "prof1", "Prof1", {
|
|
238
|
+
name: "value"
|
|
239
|
+
});
|
|
240
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
241
|
+
await sprinkle.loadProfile("prof1");
|
|
242
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
243
|
+
sprinkle.registerAction(action);
|
|
244
|
+
}
|
|
245
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
246
|
+
id: "prof1"
|
|
247
|
+
});
|
|
248
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
249
|
+
if (result.success) {
|
|
250
|
+
(0, _bunTest.expect)(result.data.settings).toBeDefined();
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
(0, _bunTest.test)("returns raw settings when includeSensitive is true", async () => {
|
|
254
|
+
writeTestProfile(tmpDir, "prof2", "Prof2", {
|
|
255
|
+
name: "raw-value"
|
|
256
|
+
});
|
|
257
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
258
|
+
await sprinkle.loadProfile("prof2");
|
|
259
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
260
|
+
sprinkle.registerAction(action);
|
|
261
|
+
}
|
|
262
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
263
|
+
id: "prof2",
|
|
264
|
+
includeSensitive: true
|
|
265
|
+
});
|
|
266
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
267
|
+
if (result.success) {
|
|
268
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("raw-value");
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
(0, _bunTest.test)("error details include the requested id", async () => {
|
|
272
|
+
writeTestProfile(tmpDir, "existing", "Existing", {
|
|
273
|
+
name: "x"
|
|
274
|
+
});
|
|
275
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
276
|
+
await sprinkle.loadProfile("existing");
|
|
277
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
278
|
+
sprinkle.registerAction(action);
|
|
279
|
+
}
|
|
280
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
281
|
+
id: "ghost"
|
|
282
|
+
});
|
|
283
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
284
|
+
if (!result.success) {
|
|
285
|
+
(0, _bunTest.expect)(result.error.details).toMatchObject({
|
|
286
|
+
id: "ghost"
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
(0, _bunTest.test)("returns INVALID_PROFILE_ID for path traversal attempts", async () => {
|
|
291
|
+
writeTestProfile(tmpDir, "existing", "Existing", {
|
|
292
|
+
name: "x"
|
|
293
|
+
});
|
|
294
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
295
|
+
await sprinkle.loadProfile("existing");
|
|
296
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
297
|
+
sprinkle.registerAction(action);
|
|
298
|
+
}
|
|
299
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
300
|
+
id: "../etc/passwd"
|
|
301
|
+
});
|
|
302
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
303
|
+
if (!result.success) {
|
|
304
|
+
(0, _bunTest.expect)(result.error.code).toBe("INVALID_PROFILE_ID");
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
(0, _bunTest.test)("masks sensitive fields by default with TestSchema", async () => {
|
|
308
|
+
// Write profile with a sensitive token field
|
|
309
|
+
writeTestProfile(tmpDir, "sensitive-test", "Sensitive Test", {
|
|
310
|
+
name: "user",
|
|
311
|
+
token: "secret-api-key-12345"
|
|
312
|
+
});
|
|
313
|
+
const sprinkle = new _index.Sprinkle(TestSchema, tmpDir);
|
|
314
|
+
await sprinkle.loadProfile("sensitive-test");
|
|
315
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
316
|
+
sprinkle.registerAction(action);
|
|
317
|
+
}
|
|
318
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
319
|
+
id: "sensitive-test"
|
|
320
|
+
});
|
|
321
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
322
|
+
if (result.success) {
|
|
323
|
+
// Token should be masked
|
|
324
|
+
(0, _bunTest.expect)(result.data.settings.token).toBe("********");
|
|
325
|
+
// Name should not be masked
|
|
326
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("user");
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
(0, _bunTest.test)("returns raw sensitive fields when includeSensitive is true with TestSchema", async () => {
|
|
330
|
+
writeTestProfile(tmpDir, "sensitive-raw", "Sensitive Raw", {
|
|
331
|
+
name: "user",
|
|
332
|
+
token: "my-secret-token"
|
|
333
|
+
});
|
|
334
|
+
const sprinkle = new _index.Sprinkle(TestSchema, tmpDir);
|
|
335
|
+
await sprinkle.loadProfile("sensitive-raw");
|
|
336
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
337
|
+
sprinkle.registerAction(action);
|
|
338
|
+
}
|
|
339
|
+
const result = await sprinkle.runAction("get-profile", {
|
|
340
|
+
id: "sensitive-raw",
|
|
341
|
+
includeSensitive: true
|
|
342
|
+
});
|
|
343
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
344
|
+
if (result.success) {
|
|
345
|
+
// Token should NOT be masked
|
|
346
|
+
(0, _bunTest.expect)(result.data.settings.token).toBe("my-secret-token");
|
|
347
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("user");
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// ---------------------------------------------------------------------------
|
|
353
|
+
// set-profile
|
|
354
|
+
// ---------------------------------------------------------------------------
|
|
355
|
+
|
|
356
|
+
(0, _bunTest.describe)("set-profile action", () => {
|
|
357
|
+
let tmpDir;
|
|
358
|
+
(0, _bunTest.beforeEach)(() => {
|
|
359
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
360
|
+
});
|
|
361
|
+
(0, _bunTest.afterEach)(() => {
|
|
362
|
+
fs.rmSync(tmpDir, {
|
|
363
|
+
recursive: true,
|
|
364
|
+
force: true
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
(0, _bunTest.test)("switches active profile and returns id and name", async () => {
|
|
368
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
369
|
+
name: "alice"
|
|
370
|
+
});
|
|
371
|
+
writeTestProfile(tmpDir, "bob", "Bob", {
|
|
372
|
+
name: "bob"
|
|
373
|
+
});
|
|
374
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
375
|
+
await sprinkle.loadProfile("alice");
|
|
376
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
377
|
+
sprinkle.registerAction(action);
|
|
378
|
+
}
|
|
379
|
+
const result = await sprinkle.runAction("set-profile", {
|
|
380
|
+
id: "bob"
|
|
381
|
+
});
|
|
382
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
383
|
+
if (result.success) {
|
|
384
|
+
(0, _bunTest.expect)(result.data.id).toBe("bob");
|
|
385
|
+
(0, _bunTest.expect)(result.data.name).toBe("Bob");
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
(0, _bunTest.test)("active profile is actually changed after set-profile", async () => {
|
|
389
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
390
|
+
name: "alice"
|
|
391
|
+
});
|
|
392
|
+
writeTestProfile(tmpDir, "bob", "Bob", {
|
|
393
|
+
name: "bob"
|
|
394
|
+
});
|
|
395
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
396
|
+
await sprinkle.loadProfile("alice");
|
|
397
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
398
|
+
sprinkle.registerAction(action);
|
|
399
|
+
}
|
|
400
|
+
await sprinkle.runAction("set-profile", {
|
|
401
|
+
id: "bob"
|
|
402
|
+
});
|
|
403
|
+
(0, _bunTest.expect)(sprinkle.profileId).toBe("bob");
|
|
404
|
+
});
|
|
405
|
+
(0, _bunTest.test)("returns PROFILE_NOT_FOUND when switching to unknown profile", async () => {
|
|
406
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
407
|
+
name: "alice"
|
|
408
|
+
});
|
|
409
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
410
|
+
await sprinkle.loadProfile("alice");
|
|
411
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
412
|
+
sprinkle.registerAction(action);
|
|
413
|
+
}
|
|
414
|
+
const result = await sprinkle.runAction("set-profile", {
|
|
415
|
+
id: "nobody"
|
|
416
|
+
});
|
|
417
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
418
|
+
if (!result.success) {
|
|
419
|
+
(0, _bunTest.expect)(result.error.code).toBe("PROFILE_NOT_FOUND");
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// ---------------------------------------------------------------------------
|
|
425
|
+
// create-profile
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
|
|
428
|
+
(0, _bunTest.describe)("create-profile action", () => {
|
|
429
|
+
let tmpDir;
|
|
430
|
+
(0, _bunTest.beforeEach)(() => {
|
|
431
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
432
|
+
});
|
|
433
|
+
(0, _bunTest.afterEach)(() => {
|
|
434
|
+
fs.rmSync(tmpDir, {
|
|
435
|
+
recursive: true,
|
|
436
|
+
force: true
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
(0, _bunTest.test)("creates a new profile and returns id and name", async () => {
|
|
440
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
441
|
+
name: "x"
|
|
442
|
+
});
|
|
443
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
444
|
+
await sprinkle.loadProfile("default");
|
|
445
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
446
|
+
sprinkle.registerAction(action);
|
|
447
|
+
}
|
|
448
|
+
const result = await sprinkle.runAction("create-profile", {
|
|
449
|
+
name: "New Profile"
|
|
450
|
+
});
|
|
451
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
452
|
+
if (result.success) {
|
|
453
|
+
(0, _bunTest.expect)(result.data.name).toBe("New Profile");
|
|
454
|
+
(0, _bunTest.expect)(result.data.id).toBeDefined();
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
(0, _bunTest.test)("created profile file exists on disk", async () => {
|
|
458
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
459
|
+
name: "x"
|
|
460
|
+
});
|
|
461
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
462
|
+
await sprinkle.loadProfile("default");
|
|
463
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
464
|
+
sprinkle.registerAction(action);
|
|
465
|
+
}
|
|
466
|
+
const result = await sprinkle.runAction("create-profile", {
|
|
467
|
+
name: "Disk Profile"
|
|
468
|
+
});
|
|
469
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
470
|
+
if (result.success) {
|
|
471
|
+
const profilePath = path.join(tmpDir, "profiles", `${result.data.id}.json`);
|
|
472
|
+
(0, _bunTest.expect)(fs.existsSync(profilePath)).toBe(true);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
(0, _bunTest.test)("create-profile does NOT switch the active profile", async () => {
|
|
476
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
477
|
+
name: "x"
|
|
478
|
+
});
|
|
479
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
480
|
+
await sprinkle.loadProfile("default");
|
|
481
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
482
|
+
sprinkle.registerAction(action);
|
|
483
|
+
}
|
|
484
|
+
await sprinkle.runAction("create-profile", {
|
|
485
|
+
name: "Another Profile"
|
|
486
|
+
});
|
|
487
|
+
(0, _bunTest.expect)(sprinkle.profileId).toBe("default");
|
|
488
|
+
});
|
|
489
|
+
(0, _bunTest.test)("create-profile with optional description stores it", async () => {
|
|
490
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
491
|
+
name: "x"
|
|
492
|
+
});
|
|
493
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
494
|
+
await sprinkle.loadProfile("default");
|
|
495
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
496
|
+
sprinkle.registerAction(action);
|
|
497
|
+
}
|
|
498
|
+
const result = await sprinkle.runAction("create-profile", {
|
|
499
|
+
name: "Described Profile",
|
|
500
|
+
description: "A detailed description"
|
|
501
|
+
});
|
|
502
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
503
|
+
if (result.success) {
|
|
504
|
+
const profilePath = path.join(tmpDir, "profiles", `${result.data.id}.json`);
|
|
505
|
+
const content = JSON.parse(fs.readFileSync(profilePath, "utf-8"));
|
|
506
|
+
(0, _bunTest.expect)(content.meta.description).toBe("A detailed description");
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
(0, _bunTest.test)("returns DUPLICATE_PROFILE error when name already exists", async () => {
|
|
510
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
511
|
+
name: "x"
|
|
512
|
+
});
|
|
513
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
514
|
+
await sprinkle.loadProfile("default");
|
|
515
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
516
|
+
sprinkle.registerAction(action);
|
|
517
|
+
}
|
|
518
|
+
const result = await sprinkle.runAction("create-profile", {
|
|
519
|
+
name: "Default"
|
|
520
|
+
});
|
|
521
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
522
|
+
if (!result.success) {
|
|
523
|
+
(0, _bunTest.expect)(result.error.code).toBe("DUPLICATE_PROFILE");
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
(0, _bunTest.test)("duplicate name check is case-insensitive", async () => {
|
|
527
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
528
|
+
name: "x"
|
|
529
|
+
});
|
|
530
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
531
|
+
await sprinkle.loadProfile("default");
|
|
532
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
533
|
+
sprinkle.registerAction(action);
|
|
534
|
+
}
|
|
535
|
+
const result = await sprinkle.runAction("create-profile", {
|
|
536
|
+
name: "DEFAULT"
|
|
537
|
+
});
|
|
538
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
539
|
+
if (!result.success) {
|
|
540
|
+
(0, _bunTest.expect)(result.error.code).toBe("DUPLICATE_PROFILE");
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
(0, _bunTest.test)("create-profile with initial settings writes them to disk", async () => {
|
|
544
|
+
writeTestProfile(tmpDir, "default", "Default", {
|
|
545
|
+
name: "x"
|
|
546
|
+
});
|
|
547
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
548
|
+
await sprinkle.loadProfile("default");
|
|
549
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
550
|
+
sprinkle.registerAction(action);
|
|
551
|
+
}
|
|
552
|
+
const result = await sprinkle.runAction("create-profile", {
|
|
553
|
+
name: "Preset Profile",
|
|
554
|
+
settings: {
|
|
555
|
+
name: "preset-name"
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
559
|
+
if (result.success) {
|
|
560
|
+
const profilePath = path.join(tmpDir, "profiles", `${result.data.id}.json`);
|
|
561
|
+
const content = JSON.parse(fs.readFileSync(profilePath, "utf-8"));
|
|
562
|
+
(0, _bunTest.expect)(content.settings.name).toBe("preset-name");
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// ---------------------------------------------------------------------------
|
|
568
|
+
// delete-profile
|
|
569
|
+
// ---------------------------------------------------------------------------
|
|
570
|
+
|
|
571
|
+
(0, _bunTest.describe)("delete-profile action", () => {
|
|
572
|
+
let tmpDir;
|
|
573
|
+
(0, _bunTest.beforeEach)(() => {
|
|
574
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
575
|
+
});
|
|
576
|
+
(0, _bunTest.afterEach)(() => {
|
|
577
|
+
fs.rmSync(tmpDir, {
|
|
578
|
+
recursive: true,
|
|
579
|
+
force: true
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
(0, _bunTest.test)("deletes a profile and returns deleted:true with id", async () => {
|
|
583
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
584
|
+
name: "alice"
|
|
585
|
+
});
|
|
586
|
+
writeTestProfile(tmpDir, "bob", "Bob", {
|
|
587
|
+
name: "bob"
|
|
588
|
+
});
|
|
589
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
590
|
+
await sprinkle.loadProfile("alice");
|
|
591
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
592
|
+
sprinkle.registerAction(action);
|
|
593
|
+
}
|
|
594
|
+
const result = await sprinkle.runAction("delete-profile", {
|
|
595
|
+
id: "bob"
|
|
596
|
+
});
|
|
597
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
598
|
+
if (result.success) {
|
|
599
|
+
(0, _bunTest.expect)(result.data.deleted).toBe(true);
|
|
600
|
+
(0, _bunTest.expect)(result.data.id).toBe("bob");
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
(0, _bunTest.test)("profile file is removed from disk after deletion", async () => {
|
|
604
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
605
|
+
name: "alice"
|
|
606
|
+
});
|
|
607
|
+
writeTestProfile(tmpDir, "bob", "Bob", {
|
|
608
|
+
name: "bob"
|
|
609
|
+
});
|
|
610
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
611
|
+
await sprinkle.loadProfile("alice");
|
|
612
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
613
|
+
sprinkle.registerAction(action);
|
|
614
|
+
}
|
|
615
|
+
await sprinkle.runAction("delete-profile", {
|
|
616
|
+
id: "bob"
|
|
617
|
+
});
|
|
618
|
+
(0, _bunTest.expect)(fs.existsSync(path.join(tmpDir, "profiles", "bob.json"))).toBe(false);
|
|
619
|
+
});
|
|
620
|
+
(0, _bunTest.test)("returns PROFILE_NOT_FOUND when deleting a non-existent profile", async () => {
|
|
621
|
+
writeTestProfile(tmpDir, "alice", "Alice", {
|
|
622
|
+
name: "alice"
|
|
623
|
+
});
|
|
624
|
+
writeTestProfile(tmpDir, "bob", "Bob", {
|
|
625
|
+
name: "bob"
|
|
626
|
+
});
|
|
627
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
628
|
+
await sprinkle.loadProfile("alice");
|
|
629
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
630
|
+
sprinkle.registerAction(action);
|
|
631
|
+
}
|
|
632
|
+
const result = await sprinkle.runAction("delete-profile", {
|
|
633
|
+
id: "nobody"
|
|
634
|
+
});
|
|
635
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
636
|
+
if (!result.success) {
|
|
637
|
+
(0, _bunTest.expect)(result.error.code).toBe("PROFILE_NOT_FOUND");
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
(0, _bunTest.test)("returns CANNOT_DELETE_ONLY_PROFILE when only one profile exists", async () => {
|
|
641
|
+
writeTestProfile(tmpDir, "only", "Only", {
|
|
642
|
+
name: "x"
|
|
643
|
+
});
|
|
644
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
645
|
+
await sprinkle.loadProfile("only");
|
|
646
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
647
|
+
sprinkle.registerAction(action);
|
|
648
|
+
}
|
|
649
|
+
const result = await sprinkle.runAction("delete-profile", {
|
|
650
|
+
id: "only"
|
|
651
|
+
});
|
|
652
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
653
|
+
if (!result.success) {
|
|
654
|
+
(0, _bunTest.expect)(result.error.code).toBe("CANNOT_DELETE_ONLY_PROFILE");
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
(0, _bunTest.test)("returns CANNOT_DELETE_ACTIVE_PROFILE when deleting the active profile", async () => {
|
|
658
|
+
writeTestProfile(tmpDir, "active", "Active", {
|
|
659
|
+
name: "x"
|
|
660
|
+
});
|
|
661
|
+
writeTestProfile(tmpDir, "other", "Other", {
|
|
662
|
+
name: "y"
|
|
663
|
+
});
|
|
664
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
665
|
+
await sprinkle.loadProfile("active");
|
|
666
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
667
|
+
sprinkle.registerAction(action);
|
|
668
|
+
}
|
|
669
|
+
const result = await sprinkle.runAction("delete-profile", {
|
|
670
|
+
id: "active"
|
|
671
|
+
});
|
|
672
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
673
|
+
if (!result.success) {
|
|
674
|
+
(0, _bunTest.expect)(result.error.code).toBe("CANNOT_DELETE_ACTIVE_PROFILE");
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// ---------------------------------------------------------------------------
|
|
680
|
+
// get-settings
|
|
681
|
+
// ---------------------------------------------------------------------------
|
|
682
|
+
|
|
683
|
+
(0, _bunTest.describe)("get-settings action", () => {
|
|
684
|
+
let tmpDir;
|
|
685
|
+
(0, _bunTest.beforeEach)(() => {
|
|
686
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
687
|
+
});
|
|
688
|
+
(0, _bunTest.afterEach)(() => {
|
|
689
|
+
fs.rmSync(tmpDir, {
|
|
690
|
+
recursive: true,
|
|
691
|
+
force: true
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
(0, _bunTest.test)("returns settings, profileId, and profileName", async () => {
|
|
695
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
696
|
+
name: "Alice"
|
|
697
|
+
});
|
|
698
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
699
|
+
sprinkle.registerAction(action);
|
|
700
|
+
}
|
|
701
|
+
const result = await sprinkle.runAction("get-settings", {});
|
|
702
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
703
|
+
if (result.success) {
|
|
704
|
+
(0, _bunTest.expect)(result.data.profileId).toBe("default");
|
|
705
|
+
(0, _bunTest.expect)(result.data.profileName).toBe("Default");
|
|
706
|
+
(0, _bunTest.expect)(result.data.settings).toBeDefined();
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
(0, _bunTest.test)("returns masked settings by default", async () => {
|
|
710
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
711
|
+
name: "Alice"
|
|
712
|
+
});
|
|
713
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
714
|
+
sprinkle.registerAction(action);
|
|
715
|
+
}
|
|
716
|
+
const result = await sprinkle.runAction("get-settings", {});
|
|
717
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
718
|
+
if (result.success) {
|
|
719
|
+
// For a schema without sensitive fields, settings pass through unchanged
|
|
720
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("Alice");
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
(0, _bunTest.test)("returns raw settings when includeSensitive is true", async () => {
|
|
724
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
725
|
+
name: "raw-user"
|
|
726
|
+
});
|
|
727
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
728
|
+
sprinkle.registerAction(action);
|
|
729
|
+
}
|
|
730
|
+
const result = await sprinkle.runAction("get-settings", {
|
|
731
|
+
includeSensitive: true
|
|
732
|
+
});
|
|
733
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
734
|
+
if (result.success) {
|
|
735
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("raw-user");
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
(0, _bunTest.test)("returns same settings whether includeSensitive is false or not provided (no sensitive fields)", async () => {
|
|
739
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
740
|
+
name: "same-user"
|
|
741
|
+
});
|
|
742
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
743
|
+
sprinkle.registerAction(action);
|
|
744
|
+
}
|
|
745
|
+
const [masked, raw] = await Promise.all([sprinkle.runAction("get-settings", {
|
|
746
|
+
includeSensitive: false
|
|
747
|
+
}), sprinkle.runAction("get-settings", {
|
|
748
|
+
includeSensitive: true
|
|
749
|
+
})]);
|
|
750
|
+
(0, _bunTest.expect)(masked.success).toBe(true);
|
|
751
|
+
(0, _bunTest.expect)(raw.success).toBe(true);
|
|
752
|
+
if (masked.success && raw.success) {
|
|
753
|
+
(0, _bunTest.expect)(masked.data.settings).toEqual(raw.data.settings);
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
(0, _bunTest.test)("settings match what was loaded from profile", async () => {
|
|
757
|
+
const sprinkle = await makeSprinkle(tmpDir, "prof", {
|
|
758
|
+
name: "expected-value"
|
|
759
|
+
});
|
|
760
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
761
|
+
sprinkle.registerAction(action);
|
|
762
|
+
}
|
|
763
|
+
const result = await sprinkle.runAction("get-settings", {
|
|
764
|
+
includeSensitive: true
|
|
765
|
+
});
|
|
766
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
767
|
+
if (result.success) {
|
|
768
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("expected-value");
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
// ---------------------------------------------------------------------------
|
|
774
|
+
// update-settings
|
|
775
|
+
// ---------------------------------------------------------------------------
|
|
776
|
+
|
|
777
|
+
(0, _bunTest.describe)("update-settings action", () => {
|
|
778
|
+
let tmpDir;
|
|
779
|
+
(0, _bunTest.beforeEach)(() => {
|
|
780
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
781
|
+
});
|
|
782
|
+
(0, _bunTest.afterEach)(() => {
|
|
783
|
+
fs.rmSync(tmpDir, {
|
|
784
|
+
recursive: true,
|
|
785
|
+
force: true
|
|
786
|
+
});
|
|
787
|
+
});
|
|
788
|
+
(0, _bunTest.test)("updates settings and returns masked settings with profileId", async () => {
|
|
789
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
790
|
+
name: "old-name"
|
|
791
|
+
});
|
|
792
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
793
|
+
sprinkle.registerAction(action);
|
|
794
|
+
}
|
|
795
|
+
const result = await sprinkle.runAction("update-settings", {
|
|
796
|
+
settings: {
|
|
797
|
+
name: "new-name"
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
801
|
+
if (result.success) {
|
|
802
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("new-name");
|
|
803
|
+
(0, _bunTest.expect)(result.data.profileId).toBe("default");
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
(0, _bunTest.test)("update persists settings in memory", async () => {
|
|
807
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
808
|
+
name: "before"
|
|
809
|
+
});
|
|
810
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
811
|
+
sprinkle.registerAction(action);
|
|
812
|
+
}
|
|
813
|
+
await sprinkle.runAction("update-settings", {
|
|
814
|
+
settings: {
|
|
815
|
+
name: "after"
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
(0, _bunTest.expect)(sprinkle.settings.name).toBe("after");
|
|
819
|
+
});
|
|
820
|
+
(0, _bunTest.test)("update persists settings to disk", async () => {
|
|
821
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
822
|
+
name: "before"
|
|
823
|
+
});
|
|
824
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
825
|
+
sprinkle.registerAction(action);
|
|
826
|
+
}
|
|
827
|
+
await sprinkle.runAction("update-settings", {
|
|
828
|
+
settings: {
|
|
829
|
+
name: "persisted"
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
// Read the saved file to verify persistence
|
|
834
|
+
const profilePath = path.join(tmpDir, "profiles", "default.json");
|
|
835
|
+
const content = JSON.parse(fs.readFileSync(profilePath, "utf-8"));
|
|
836
|
+
(0, _bunTest.expect)(content.settings.name).toBe("persisted");
|
|
837
|
+
});
|
|
838
|
+
(0, _bunTest.test)("returns VALIDATION_ERROR for settings that violate schema", async () => {
|
|
839
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
840
|
+
name: "valid"
|
|
841
|
+
});
|
|
842
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
843
|
+
sprinkle.registerAction(action);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// Removing required 'name' field should fail schema validation
|
|
847
|
+
const result = await sprinkle.runAction("update-settings", {
|
|
848
|
+
settings: {
|
|
849
|
+
name: 12345
|
|
850
|
+
} // name must be a string
|
|
851
|
+
});
|
|
852
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
853
|
+
if (!result.success) {
|
|
854
|
+
(0, _bunTest.expect)(result.error.code).toBe("VALIDATION_ERROR");
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
(0, _bunTest.test)("settings are not saved when validation fails", async () => {
|
|
858
|
+
const sprinkle = await makeSprinkle(tmpDir, "default", {
|
|
859
|
+
name: "original"
|
|
860
|
+
});
|
|
861
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
862
|
+
sprinkle.registerAction(action);
|
|
863
|
+
}
|
|
864
|
+
await sprinkle.runAction("update-settings", {
|
|
865
|
+
settings: {
|
|
866
|
+
name: 99
|
|
867
|
+
} // invalid: not a string
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
// Settings in memory should remain unchanged
|
|
871
|
+
(0, _bunTest.expect)(sprinkle.settings.name).toBe("original");
|
|
872
|
+
});
|
|
873
|
+
(0, _bunTest.test)("shallow merges settings - existing keys not in update are preserved", async () => {
|
|
874
|
+
// Use a schema with two optional keys to test merge behaviour
|
|
875
|
+
const TwoKeySchema = _typebox.Type.Object({
|
|
876
|
+
name: _typebox.Type.String(),
|
|
877
|
+
label: _typebox.Type.Optional(_typebox.Type.String())
|
|
878
|
+
});
|
|
879
|
+
writeTestProfile(tmpDir, "twokey", "TwoKey", {
|
|
880
|
+
name: "base",
|
|
881
|
+
label: "keep-me"
|
|
882
|
+
});
|
|
883
|
+
const sprinkle = new _index.Sprinkle(TwoKeySchema, tmpDir);
|
|
884
|
+
await sprinkle.loadProfile("twokey");
|
|
885
|
+
for (const action of (0, _index.getBuiltinActions)()) {
|
|
886
|
+
sprinkle.registerAction(action);
|
|
887
|
+
}
|
|
888
|
+
const result = await sprinkle.runAction("update-settings", {
|
|
889
|
+
settings: {
|
|
890
|
+
name: "updated"
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
894
|
+
if (result.success) {
|
|
895
|
+
(0, _bunTest.expect)(result.data.settings.name).toBe("updated");
|
|
896
|
+
(0, _bunTest.expect)(result.data.settings.label).toBe("keep-me");
|
|
897
|
+
}
|
|
898
|
+
});
|
|
899
|
+
});
|
|
900
|
+
|
|
901
|
+
// ---------------------------------------------------------------------------
|
|
902
|
+
// Sprinkle.getProfileById direct method tests
|
|
903
|
+
// ---------------------------------------------------------------------------
|
|
904
|
+
|
|
905
|
+
(0, _bunTest.describe)("Sprinkle.getProfileById", () => {
|
|
906
|
+
let tmpDir;
|
|
907
|
+
(0, _bunTest.beforeEach)(() => {
|
|
908
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
909
|
+
});
|
|
910
|
+
(0, _bunTest.afterEach)(() => {
|
|
911
|
+
fs.rmSync(tmpDir, {
|
|
912
|
+
recursive: true,
|
|
913
|
+
force: true
|
|
914
|
+
});
|
|
915
|
+
});
|
|
916
|
+
(0, _bunTest.test)("returns profile entry when id exists", () => {
|
|
917
|
+
writeTestProfile(tmpDir, "myid", "My Name", {
|
|
918
|
+
name: "x"
|
|
919
|
+
});
|
|
920
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
921
|
+
const entry = sprinkle.getProfileById("myid");
|
|
922
|
+
(0, _bunTest.expect)(entry).toBeDefined();
|
|
923
|
+
(0, _bunTest.expect)(entry.id).toBe("myid");
|
|
924
|
+
(0, _bunTest.expect)(entry.meta.name).toBe("My Name");
|
|
925
|
+
});
|
|
926
|
+
(0, _bunTest.test)("returns undefined when id does not exist", () => {
|
|
927
|
+
writeTestProfile(tmpDir, "real", "Real", {
|
|
928
|
+
name: "x"
|
|
929
|
+
});
|
|
930
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
931
|
+
(0, _bunTest.expect)(sprinkle.getProfileById("ghost")).toBeUndefined();
|
|
932
|
+
});
|
|
933
|
+
(0, _bunTest.test)("returns undefined when no profiles exist", () => {
|
|
934
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
935
|
+
(0, _bunTest.expect)(sprinkle.getProfileById("anything")).toBeUndefined();
|
|
936
|
+
});
|
|
937
|
+
});
|
|
938
|
+
|
|
939
|
+
// ---------------------------------------------------------------------------
|
|
940
|
+
// Sprinkle.createProfileNonInteractive direct method tests
|
|
941
|
+
// ---------------------------------------------------------------------------
|
|
942
|
+
|
|
943
|
+
(0, _bunTest.describe)("Sprinkle.createProfileNonInteractive", () => {
|
|
944
|
+
let tmpDir;
|
|
945
|
+
(0, _bunTest.beforeEach)(() => {
|
|
946
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
947
|
+
});
|
|
948
|
+
(0, _bunTest.afterEach)(() => {
|
|
949
|
+
fs.rmSync(tmpDir, {
|
|
950
|
+
recursive: true,
|
|
951
|
+
force: true
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
(0, _bunTest.test)("creates a profile file and returns IProfileEntry", async () => {
|
|
955
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
956
|
+
const entry = await sprinkle.createProfileNonInteractive("Test Profile");
|
|
957
|
+
(0, _bunTest.expect)(entry.id).toBeDefined();
|
|
958
|
+
(0, _bunTest.expect)(entry.meta.name).toBe("Test Profile");
|
|
959
|
+
const profilePath = path.join(tmpDir, "profiles", `${entry.id}.json`);
|
|
960
|
+
(0, _bunTest.expect)(fs.existsSync(profilePath)).toBe(true);
|
|
961
|
+
});
|
|
962
|
+
(0, _bunTest.test)("sanitizes name to form a valid id", async () => {
|
|
963
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
964
|
+
const entry = await sprinkle.createProfileNonInteractive("My New Profile!");
|
|
965
|
+
// sanitized: "my-new-profile"
|
|
966
|
+
(0, _bunTest.expect)(entry.id).toBe("my-new-profile");
|
|
967
|
+
});
|
|
968
|
+
(0, _bunTest.test)("uses findAvailableId to avoid collisions", async () => {
|
|
969
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
970
|
+
// "My Profile" sanitizes to "my-profile". Pre-create that file so
|
|
971
|
+
// findAvailableId must fall back to "my-profile-2".
|
|
972
|
+
writeTestProfile(tmpDir, "my-profile", "My Profile First", {
|
|
973
|
+
name: "x"
|
|
974
|
+
});
|
|
975
|
+
const entry = await sprinkle.createProfileNonInteractive("My Profile");
|
|
976
|
+
// "my-profile" is taken, so the entry id should become "my-profile-2"
|
|
977
|
+
(0, _bunTest.expect)(entry.id).toBe("my-profile-2");
|
|
978
|
+
});
|
|
979
|
+
(0, _bunTest.test)("throws DUPLICATE_PROFILE for same name (case-insensitive)", async () => {
|
|
980
|
+
writeTestProfile(tmpDir, "existing", "Existing Profile", {
|
|
981
|
+
name: "x"
|
|
982
|
+
});
|
|
983
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
984
|
+
await (0, _bunTest.expect)(sprinkle.createProfileNonInteractive("existing profile")).rejects.toMatchObject({
|
|
985
|
+
code: "DUPLICATE_PROFILE"
|
|
986
|
+
});
|
|
987
|
+
});
|
|
988
|
+
(0, _bunTest.test)("stores optional description in meta", async () => {
|
|
989
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
990
|
+
const entry = await sprinkle.createProfileNonInteractive("Described", "My description");
|
|
991
|
+
(0, _bunTest.expect)(entry.meta.description).toBe("My description");
|
|
992
|
+
const profilePath = path.join(tmpDir, "profiles", `${entry.id}.json`);
|
|
993
|
+
const content = JSON.parse(fs.readFileSync(profilePath, "utf-8"));
|
|
994
|
+
(0, _bunTest.expect)(content.meta.description).toBe("My description");
|
|
995
|
+
});
|
|
996
|
+
(0, _bunTest.test)("stores initial settings when provided", async () => {
|
|
997
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
998
|
+
const entry = await sprinkle.createProfileNonInteractive("With Settings", undefined, {
|
|
999
|
+
name: "preset"
|
|
1000
|
+
});
|
|
1001
|
+
const profilePath = path.join(tmpDir, "profiles", `${entry.id}.json`);
|
|
1002
|
+
const content = JSON.parse(fs.readFileSync(profilePath, "utf-8"));
|
|
1003
|
+
(0, _bunTest.expect)(content.settings.name).toBe("preset");
|
|
1004
|
+
});
|
|
1005
|
+
(0, _bunTest.test)("does not change the active profile", async () => {
|
|
1006
|
+
writeTestProfile(tmpDir, "active", "Active", {
|
|
1007
|
+
name: "x"
|
|
1008
|
+
});
|
|
1009
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
1010
|
+
await sprinkle.loadProfile("active");
|
|
1011
|
+
await sprinkle.createProfileNonInteractive("New One");
|
|
1012
|
+
(0, _bunTest.expect)(sprinkle.profileId).toBe("active");
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
// ---------------------------------------------------------------------------
|
|
1017
|
+
// Sprinkle.deleteProfileById direct method tests
|
|
1018
|
+
// ---------------------------------------------------------------------------
|
|
1019
|
+
|
|
1020
|
+
(0, _bunTest.describe)("Sprinkle.deleteProfileById", () => {
|
|
1021
|
+
let tmpDir;
|
|
1022
|
+
(0, _bunTest.beforeEach)(() => {
|
|
1023
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sprinkles-builtin-test-"));
|
|
1024
|
+
});
|
|
1025
|
+
(0, _bunTest.afterEach)(() => {
|
|
1026
|
+
fs.rmSync(tmpDir, {
|
|
1027
|
+
recursive: true,
|
|
1028
|
+
force: true
|
|
1029
|
+
});
|
|
1030
|
+
});
|
|
1031
|
+
(0, _bunTest.test)("removes the profile file from disk", () => {
|
|
1032
|
+
writeTestProfile(tmpDir, "keep", "Keep", {
|
|
1033
|
+
name: "x"
|
|
1034
|
+
});
|
|
1035
|
+
writeTestProfile(tmpDir, "remove", "Remove", {
|
|
1036
|
+
name: "y"
|
|
1037
|
+
});
|
|
1038
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
1039
|
+
sprinkle.profileId = "keep";
|
|
1040
|
+
sprinkle.profileMeta = {
|
|
1041
|
+
name: "Keep",
|
|
1042
|
+
createdAt: "",
|
|
1043
|
+
updatedAt: ""
|
|
1044
|
+
};
|
|
1045
|
+
sprinkle.deleteProfileById("remove");
|
|
1046
|
+
(0, _bunTest.expect)(fs.existsSync(path.join(tmpDir, "profiles", "remove.json"))).toBe(false);
|
|
1047
|
+
(0, _bunTest.expect)(fs.existsSync(path.join(tmpDir, "profiles", "keep.json"))).toBe(true);
|
|
1048
|
+
});
|
|
1049
|
+
(0, _bunTest.test)("throws PROFILE_NOT_FOUND for unknown id", () => {
|
|
1050
|
+
writeTestProfile(tmpDir, "alpha", "Alpha", {
|
|
1051
|
+
name: "x"
|
|
1052
|
+
});
|
|
1053
|
+
writeTestProfile(tmpDir, "beta", "Beta", {
|
|
1054
|
+
name: "y"
|
|
1055
|
+
});
|
|
1056
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
1057
|
+
sprinkle.profileId = "alpha";
|
|
1058
|
+
sprinkle.profileMeta = {
|
|
1059
|
+
name: "Alpha",
|
|
1060
|
+
createdAt: "",
|
|
1061
|
+
updatedAt: ""
|
|
1062
|
+
};
|
|
1063
|
+
(0, _bunTest.expect)(() => sprinkle.deleteProfileById("ghost")).toThrow();
|
|
1064
|
+
try {
|
|
1065
|
+
sprinkle.deleteProfileById("ghost");
|
|
1066
|
+
} catch (e) {
|
|
1067
|
+
(0, _bunTest.expect)(e.code).toBe("PROFILE_NOT_FOUND");
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
(0, _bunTest.test)("throws CANNOT_DELETE_ONLY_PROFILE when only one profile exists", () => {
|
|
1071
|
+
writeTestProfile(tmpDir, "solo", "Solo", {
|
|
1072
|
+
name: "x"
|
|
1073
|
+
});
|
|
1074
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
1075
|
+
sprinkle.profileId = "solo";
|
|
1076
|
+
sprinkle.profileMeta = {
|
|
1077
|
+
name: "Solo",
|
|
1078
|
+
createdAt: "",
|
|
1079
|
+
updatedAt: ""
|
|
1080
|
+
};
|
|
1081
|
+
(0, _bunTest.expect)(() => sprinkle.deleteProfileById("solo")).toThrow();
|
|
1082
|
+
try {
|
|
1083
|
+
sprinkle.deleteProfileById("solo");
|
|
1084
|
+
} catch (e) {
|
|
1085
|
+
(0, _bunTest.expect)(e.code).toBe("CANNOT_DELETE_ONLY_PROFILE");
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
(0, _bunTest.test)("throws CANNOT_DELETE_ACTIVE_PROFILE when deleting the active profile", () => {
|
|
1089
|
+
writeTestProfile(tmpDir, "active", "Active", {
|
|
1090
|
+
name: "x"
|
|
1091
|
+
});
|
|
1092
|
+
writeTestProfile(tmpDir, "other", "Other", {
|
|
1093
|
+
name: "y"
|
|
1094
|
+
});
|
|
1095
|
+
const sprinkle = new _index.Sprinkle(SimpleSchema, tmpDir);
|
|
1096
|
+
sprinkle.profileId = "active";
|
|
1097
|
+
sprinkle.profileMeta = {
|
|
1098
|
+
name: "Active",
|
|
1099
|
+
createdAt: "",
|
|
1100
|
+
updatedAt: ""
|
|
1101
|
+
};
|
|
1102
|
+
(0, _bunTest.expect)(() => sprinkle.deleteProfileById("active")).toThrow();
|
|
1103
|
+
try {
|
|
1104
|
+
sprinkle.deleteProfileById("active");
|
|
1105
|
+
} catch (e) {
|
|
1106
|
+
(0, _bunTest.expect)(e.code).toBe("CANNOT_DELETE_ACTIVE_PROFILE");
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
});
|
|
1110
|
+
//# sourceMappingURL=builtin-actions.test.js.map
|