doover-js 0.1.2 → 0.2.0-alpha.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.
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ConfigManager = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const auth_profile_1 = require("../auth/auth-profile");
41
+ const errors_1 = require("../auth/errors");
42
+ /**
43
+ * File-backed profile store compatible with pydoover's config format.
44
+ *
45
+ * Reads `~/.doover/config` (or a custom path) synchronously on construction,
46
+ * matching Python's eager-read model.
47
+ *
48
+ * Behaviour:
49
+ * - Doover2 `[profile=...]` blocks are parsed into `AuthProfile` entries.
50
+ * - Legacy Doover1 `[...]` blocks and unrecognised raw blocks are preserved
51
+ * verbatim in their original order and written back unchanged.
52
+ * - `write()` creates the `~/.doover` directory if missing.
53
+ */
54
+ class ConfigManager {
55
+ constructor(configPath) {
56
+ this.currentProfile = null;
57
+ this.current = null;
58
+ /** Parsed Doover2 profiles keyed by profile name. */
59
+ this.profiles = new Map();
60
+ /**
61
+ * Ordered list of *blocks* in the file as they were originally read. Each
62
+ * entry is either a `{ type: "managed"; name: string }` reference into
63
+ * `this.profiles`, or a `{ type: "raw"; text: string }` blob that is
64
+ * preserved verbatim.
65
+ */
66
+ this.blocks = [];
67
+ this.configPath =
68
+ configPath ?? path.join(os.homedir(), ".doover", "config");
69
+ this.read();
70
+ }
71
+ // ------------------------------------------------------------------
72
+ // AuthProfileStore interface
73
+ // ------------------------------------------------------------------
74
+ get(profileName) {
75
+ return this.profiles.get(profileName);
76
+ }
77
+ create(entry) {
78
+ const existing = this.profiles.has(entry.profile);
79
+ this.profiles.set(entry.profile, entry);
80
+ if (!existing) {
81
+ this.blocks.push({ type: "managed", name: entry.profile });
82
+ }
83
+ }
84
+ delete(profileName) {
85
+ this.profiles.delete(profileName);
86
+ this.blocks = this.blocks.filter((b) => !(b.type === "managed" && b.name === profileName));
87
+ if (this.currentProfile === profileName) {
88
+ this.currentProfile = null;
89
+ this.current = null;
90
+ }
91
+ }
92
+ write() {
93
+ const dir = path.dirname(this.configPath);
94
+ try {
95
+ fs.mkdirSync(dir, { recursive: true });
96
+ }
97
+ catch (err) {
98
+ throw new errors_1.DooverAuthError(`Failed to create config directory '${dir}': ${err instanceof Error ? err.message : String(err)}`);
99
+ }
100
+ const sections = [];
101
+ for (const block of this.blocks) {
102
+ if (block.type === "raw") {
103
+ sections.push(block.text);
104
+ }
105
+ else {
106
+ const profile = this.profiles.get(block.name);
107
+ if (profile) {
108
+ sections.push(profile.dumpBlock());
109
+ }
110
+ }
111
+ }
112
+ try {
113
+ fs.writeFileSync(this.configPath, sections.join("\n\n") + "\n", "utf-8");
114
+ }
115
+ catch (err) {
116
+ throw new errors_1.DooverAuthError(`Failed to write config file '${this.configPath}': ${err instanceof Error ? err.message : String(err)}`);
117
+ }
118
+ }
119
+ // ------------------------------------------------------------------
120
+ // Internal parsing
121
+ // ------------------------------------------------------------------
122
+ read() {
123
+ let content;
124
+ try {
125
+ content = fs.readFileSync(this.configPath, "utf-8");
126
+ }
127
+ catch {
128
+ // File does not exist — start empty.
129
+ return;
130
+ }
131
+ this.profiles.clear();
132
+ this.blocks = [];
133
+ const lines = content.split(/\r?\n/);
134
+ let i = 0;
135
+ while (i < lines.length) {
136
+ const line = lines[i];
137
+ const profileMatch = line.match(/^\[profile=(.+)\]$/);
138
+ if (profileMatch) {
139
+ // Doover2 managed block
140
+ const profileName = profileMatch[1];
141
+ const bodyLines = [];
142
+ i++;
143
+ while (i < lines.length && !lines[i].startsWith("[")) {
144
+ bodyLines.push(lines[i]);
145
+ i++;
146
+ }
147
+ const profile = auth_profile_1.AuthProfile.parse(profileName, bodyLines);
148
+ this.profiles.set(profileName, profile);
149
+ this.blocks.push({ type: "managed", name: profileName });
150
+ }
151
+ else if (line.match(/^\[.+\]$/) && !line.match(/^\[profile=/)) {
152
+ // Legacy Doover1 block — preserve verbatim.
153
+ const rawLines = [line];
154
+ i++;
155
+ while (i < lines.length && !lines[i].startsWith("[")) {
156
+ rawLines.push(lines[i]);
157
+ i++;
158
+ }
159
+ this.blocks.push({ type: "raw", text: rawLines.join("\n").trimEnd() });
160
+ }
161
+ else {
162
+ // Stray line outside any block — preserve as raw.
163
+ if (line.trim()) {
164
+ this.blocks.push({ type: "raw", text: line });
165
+ }
166
+ i++;
167
+ }
168
+ }
169
+ // Set default current profile to the first managed profile.
170
+ if (this.profiles.size > 0) {
171
+ const firstName = this.profiles.keys().next().value;
172
+ this.currentProfile = firstName;
173
+ this.current = this.profiles.get(firstName);
174
+ }
175
+ }
176
+ }
177
+ exports.ConfigManager = ConfigManager;
@@ -0,0 +1 @@
1
+ export { ConfigManager } from "./config-manager";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigManager = void 0;
4
+ var config_manager_1 = require("./config-manager");
5
+ Object.defineProperty(exports, "ConfigManager", { enumerable: true, get: function () { return config_manager_1.ConfigManager; } });
@@ -0,0 +1 @@
1
+ export {};