import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, describe, it } from "@effect/vitest";
import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@t3tools/contracts";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Schema from "effect/Schema";
import * as DesktopConfig from "../app/DesktopConfig.ts";
import * as DesktopEnvironment from "../app/DesktopEnvironment.ts";
import * as ElectronSafeStorage from "../electron/ElectronSafeStorage.ts";
import * as DesktopSavedEnvironments from "./DesktopSavedEnvironments.ts";
const textDecoder = new TextDecoder();
const textEncoder = new TextEncoder();
const savedRegistryRecord: PersistedSavedEnvironmentRecord = {
environmentId: EnvironmentId.make("environment-1"),
label: "Remote environment",
httpBaseUrl: "https://remote.example.com/",
wsBaseUrl: "wss://remote.example.com/",
createdAt: "2026-04-09T00:00:00.000Z",
lastConnectedAt: "2026-04-09T01:00:00.000Z",
desktopSsh: {
alias: "devbox",
hostname: "devbox.example.com",
username: "julius",
port: 22,
},
};
const SavedEnvironmentRegistryDocumentProbe = Schema.Struct({
version: Schema.Number,
records: Schema.Array(Schema.Unknown),
});
const decodeSavedEnvironmentRegistryDocumentProbe = Schema.decodeEffect(
Schema.fromJsonString(SavedEnvironmentRegistryDocumentProbe),
);
function makeSafeStorageLayer(input: {
readonly available: boolean;
readonly availabilityError?: unknown;
readonly encryptError?: unknown;
readonly decryptError?: unknown;
}) {
return Layer.succeed(ElectronSafeStorage.ElectronSafeStorage, {
isEncryptionAvailable:
input.availabilityError === undefined
? Effect.succeed(input.available)
: Effect.fail(
new ElectronSafeStorage.ElectronSafeStorageAvailabilityError({
cause: input.availabilityError,
}),
),
encryptString: (value) =>
input.encryptError === undefined
? Effect.succeed(textEncoder.encode(`enc:${value}`))
: Effect.fail(
new ElectronSafeStorage.ElectronSafeStorageEncryptError({
cause: input.encryptError,
}),
),
decryptString: (value) => {
if (input.decryptError !== undefined) {
return Effect.fail(
new ElectronSafeStorage.ElectronSafeStorageDecryptError({
cause: input.decryptError,
}),
);
}
const decoded = textDecoder.decode(value);
if (!decoded.startsWith("enc:")) {
return Effect.fail(
new ElectronSafeStorage.ElectronSafeStorageDecryptError({
cause: new Error("invalid secret"),
}),
);
}
return Effect.succeed(decoded.slice("enc:".length));
},
} satisfies ElectronSafeStorage.ElectronSafeStorageShape);
}
function makeLayer(
baseDir: string,
options?: {
readonly availableSecretStorage?: boolean;
readonly availabilityError?: unknown;
readonly encryptError?: unknown;
readonly decryptError?: unknown;
},
) {
const environmentLayer = DesktopEnvironment.layer({
dirname: "/repo/apps/desktop/src",
homeDirectory: baseDir,
platform: "darwin",
processArch: "x64",
appVersion: "1.2.3",
appPath: "/repo",
isPackaged: true,
resourcesPath: "/missing/resources",
runningUnderArm64Translation: false,
}).pipe(
Layer.provide(
Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ T3CODE_HOME: baseDir })),
),
);
return DesktopSavedEnvironments.layer.pipe(
Layer.provideMerge(environmentLayer),
Layer.provideMerge(
makeSafeStorageLayer({
available: options?.availableSecretStorage ?? true,
availabilityError: options?.availabilityError,
encryptError: options?.encryptError,
decryptError: options?.decryptError,
}),
),
Layer.provideMerge(NodeServices.layer),
);
}
const withSavedEnvironments = (
effect: Effect.Effect,
options?: {
readonly availableSecretStorage?: boolean;
readonly availabilityError?: unknown;
readonly encryptError?: unknown;
readonly decryptError?: unknown;
},
) =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-saved-environments-test-",
});
return yield* effect.pipe(Effect.provide(makeLayer(baseDir, options)));
}).pipe(Effect.provide(NodeServices.layer), Effect.scoped);
describe("DesktopSavedEnvironments", () => {
it.effect("persists and reloads saved environment metadata", () =>
withSavedEnvironments(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const fileSystem = yield* FileSystem.FileSystem;
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
assert.deepEqual(yield* savedEnvironments.getRegistry, [savedRegistryRecord]);
const persisted = yield* decodeSavedEnvironmentRegistryDocumentProbe(
yield* fileSystem.readFileString(environment.savedEnvironmentRegistryPath),
);
assert.equal(persisted.version, 1);
assert.lengthOf(persisted.records, 1);
}),
),
);
it.effect("loads lenient saved environment registry documents", () =>
withSavedEnvironments(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const fileSystem = yield* FileSystem.FileSystem;
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* fileSystem.makeDirectory(environment.stateDir, { recursive: true });
yield* fileSystem.writeFileString(
environment.savedEnvironmentRegistryPath,
`{
// Same optional envelope shape as browser saved environments.
"version": 1,
"records": [
{
"environmentId": "${savedRegistryRecord.environmentId}",
"label": "Remote environment",
"httpBaseUrl": "https://remote.example.com/",
"wsBaseUrl": "wss://remote.example.com/",
"createdAt": "2026-04-09T00:00:00.000Z",
"lastConnectedAt": "2026-04-09T01:00:00.000Z",
"desktopSsh": {
"alias": "devbox",
"hostname": "devbox.example.com",
"username": "julius",
"port": 22,
},
},
],
}\n`,
);
assert.deepEqual(yield* savedEnvironments.getRegistry, [savedRegistryRecord]);
}),
),
);
it.effect("persists encrypted saved environment secrets when encryption is available", () =>
withSavedEnvironments(
Effect.gen(function* () {
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
assert.isTrue(
yield* savedEnvironments.setSecret({
environmentId: savedRegistryRecord.environmentId,
secret: "bearer-token",
}),
);
assert.deepEqual(
yield* savedEnvironments.getSecret(savedRegistryRecord.environmentId),
Option.some("bearer-token"),
);
}),
),
);
it.effect("returns false when writing secrets while encryption is unavailable", () =>
withSavedEnvironments(
Effect.gen(function* () {
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
assert.isFalse(
yield* savedEnvironments.setSecret({
environmentId: savedRegistryRecord.environmentId,
secret: "next-token",
}),
);
}),
{ availableSecretStorage: false },
),
);
it.effect("surfaces typed safe storage availability failures", () => {
const cause = new Error("safe storage unavailable");
return withSavedEnvironments(
Effect.gen(function* () {
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
const error = yield* savedEnvironments
.setSecret({
environmentId: savedRegistryRecord.environmentId,
secret: "next-token",
})
.pipe(Effect.flip);
assert.instanceOf(error, ElectronSafeStorage.ElectronSafeStorageAvailabilityError);
assert.equal(error.cause, cause);
}),
{ availabilityError: cause },
);
});
it.effect("removes saved environment secrets", () =>
withSavedEnvironments(
Effect.gen(function* () {
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
yield* savedEnvironments.setSecret({
environmentId: savedRegistryRecord.environmentId,
secret: "bearer-token",
});
yield* savedEnvironments.removeSecret(savedRegistryRecord.environmentId);
assert.isTrue(
Option.isNone(yield* savedEnvironments.getSecret(savedRegistryRecord.environmentId)),
);
}),
),
);
it.effect("treats empty saved environment documents as empty", () =>
withSavedEnvironments(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const fileSystem = yield* FileSystem.FileSystem;
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* fileSystem.makeDirectory(environment.stateDir, { recursive: true });
yield* fileSystem.writeFileString(environment.savedEnvironmentRegistryPath, "{}\n");
assert.deepEqual(yield* savedEnvironments.getRegistry, []);
assert.isTrue(
Option.isNone(yield* savedEnvironments.getSecret(savedRegistryRecord.environmentId)),
);
}),
),
);
it.effect("treats malformed saved environment documents as empty", () =>
withSavedEnvironments(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const fileSystem = yield* FileSystem.FileSystem;
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* fileSystem.makeDirectory(environment.stateDir, { recursive: true });
yield* fileSystem.writeFileString(environment.savedEnvironmentRegistryPath, "{not-json");
assert.deepEqual(yield* savedEnvironments.getRegistry, []);
assert.isTrue(
Option.isNone(yield* savedEnvironments.getSecret(savedRegistryRecord.environmentId)),
);
}),
),
);
it.effect("returns false when writing a secret without metadata", () =>
withSavedEnvironments(
Effect.gen(function* () {
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
assert.isFalse(
yield* savedEnvironments.setSecret({
environmentId: savedRegistryRecord.environmentId,
secret: "bearer-token",
}),
);
}),
),
);
it.effect("preserves encrypted secrets when metadata is rewritten", () =>
withSavedEnvironments(
Effect.gen(function* () {
const savedEnvironments = yield* DesktopSavedEnvironments.DesktopSavedEnvironments;
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
yield* savedEnvironments.setSecret({
environmentId: savedRegistryRecord.environmentId,
secret: "bearer-token",
});
yield* savedEnvironments.setRegistry([savedRegistryRecord]);
assert.deepEqual(yield* savedEnvironments.getRegistry, [savedRegistryRecord]);
assert.deepEqual(
yield* savedEnvironments.getSecret(savedRegistryRecord.environmentId),
Option.some("bearer-token"),
);
}),
),
);
});