@denvig/sdk 0.7.0-alpha.4
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/LICENSE +8 -0
- package/README.md +17 -0
- package/dist/chunk-CMqjfN_6.cjs +1 -0
- package/dist/fs.cjs +1 -0
- package/dist/fs.d.ts +15 -0
- package/dist/fs.js +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +273 -0
- package/dist/index.js +1 -0
- package/dist/internal.cjs +1 -0
- package/dist/internal.d.ts +202 -0
- package/dist/internal.js +1 -0
- package/dist/path-DElA4WIM.js +1 -0
- package/dist/path-pt0IDc1N.cjs +1 -0
- package/dist/project-BA4nj7bB.js +1 -0
- package/dist/project-BqMRVXi0.cjs +1 -0
- package/dist/project-DmYu4L1C.d.ts +247 -0
- package/dist/reconcile-C90QGHEJ.d.ts +50 -0
- package/dist/reconcile-CvY7dT3H.js +1 -0
- package/dist/reconcile-DU2Wb6SO.cjs +1 -0
- package/dist/safeReadFile-BlLUgHuA.cjs +1 -0
- package/dist/safeReadFile-Z2PHqO9j.js +1 -0
- package/dist/semver-CxqsdmU_.cjs +1 -0
- package/dist/semver-dZSpezIR.js +1 -0
- package/dist/teardown-BuHyVdhH.d.ts +764 -0
- package/dist/teardown-DgjT-aE7.js +208 -0
- package/dist/teardown-DypXa0Wy.cjs +208 -0
- package/dist/testing.cjs +1 -0
- package/dist/testing.d.ts +32 -0
- package/dist/testing.js +1 -0
- package/dist/utils.cjs +1 -0
- package/dist/utils.d.ts +15 -0
- package/dist/utils.js +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/actions/types.d.ts
|
|
4
|
+
type Actions = Record<string, string[]>;
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/schemas/config.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Global configuration for the system.
|
|
9
|
+
*
|
|
10
|
+
* This is located in ~/.denvig/config.yml but can be overridden by ENV.DENVIG_GLOBAL_CONFIG_PATH
|
|
11
|
+
*/
|
|
12
|
+
declare const GlobalConfigSchema: z.ZodObject<{
|
|
13
|
+
projectPaths: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
14
|
+
quickActions: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
15
|
+
services: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
16
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
17
|
+
command: z.ZodString;
|
|
18
|
+
http: z.ZodOptional<z.ZodObject<{
|
|
19
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
20
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
21
|
+
cnames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
+
secure: z.ZodOptional<z.ZodBoolean>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
envFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
25
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
26
|
+
keepAlive: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
+
startOnBoot: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
}, z.core.$strip>>>;
|
|
29
|
+
experimental: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
gateway: z.ZodOptional<z.ZodObject<{
|
|
31
|
+
enabled: z.ZodBoolean;
|
|
32
|
+
handler: z.ZodDefault<z.ZodEnum<{
|
|
33
|
+
nginx: "nginx";
|
|
34
|
+
}>>;
|
|
35
|
+
configsPath: z.ZodDefault<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
type GlobalConfigSchema = z.infer<typeof GlobalConfigSchema>;
|
|
40
|
+
/**
|
|
41
|
+
* The per project configuration.
|
|
42
|
+
* This is usually loaded from ~/.denvig.yml or ~/.denvig/config.yml
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* name: My Project
|
|
46
|
+
* actions:
|
|
47
|
+
* build:
|
|
48
|
+
* command: pnpm build
|
|
49
|
+
* clean:
|
|
50
|
+
* command: rf -rf dist
|
|
51
|
+
*/
|
|
52
|
+
declare const ProjectConfigSchema: z.ZodObject<{
|
|
53
|
+
name: z.ZodOptional<z.ZodString>;
|
|
54
|
+
actions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
55
|
+
command: z.ZodString;
|
|
56
|
+
}, z.core.$strip>>>;
|
|
57
|
+
quickActions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
58
|
+
services: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
59
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
60
|
+
command: z.ZodString;
|
|
61
|
+
http: z.ZodOptional<z.ZodObject<{
|
|
62
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
64
|
+
cnames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
65
|
+
secure: z.ZodOptional<z.ZodBoolean>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
envFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
68
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
69
|
+
keepAlive: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
startOnBoot: z.ZodOptional<z.ZodBoolean>;
|
|
71
|
+
}, z.core.$strip>>>;
|
|
72
|
+
}, z.core.$strip>;
|
|
73
|
+
type ProjectConfigSchema = z.infer<typeof ProjectConfigSchema>;
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/lib/config.d.ts
|
|
76
|
+
type ConfigWithSourcePaths<C> = C & {
|
|
77
|
+
$sources: string[];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Load global config with the following precedence (highest to lowest):
|
|
81
|
+
* 1. Environment variables (DENVIG_PROJECT_PATHS, DENVIG_QUICK_ACTIONS)
|
|
82
|
+
* 2. ~/.denvig/config.yml
|
|
83
|
+
* 3. Default values
|
|
84
|
+
*/
|
|
85
|
+
declare const getGlobalConfig: () => Promise<ConfigWithSourcePaths<GlobalConfigSchema>>;
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/lib/services/launchctl.d.ts
|
|
88
|
+
/**
|
|
89
|
+
* Parsed output from launchctl print command.
|
|
90
|
+
*/
|
|
91
|
+
type LaunchctlPrintOutput = {
|
|
92
|
+
pid?: number;
|
|
93
|
+
status: string;
|
|
94
|
+
label: string;
|
|
95
|
+
state: string;
|
|
96
|
+
lastExitCode?: number;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Item from launchctl list command.
|
|
100
|
+
*/
|
|
101
|
+
type LaunchctlListItem = {
|
|
102
|
+
pid: number | '-';
|
|
103
|
+
status: number;
|
|
104
|
+
label: string;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Get the user domain for launchctl commands.
|
|
108
|
+
*
|
|
109
|
+
* @returns Domain string in format "gui/USER_ID"
|
|
110
|
+
*/
|
|
111
|
+
declare function getUserDomain(): string;
|
|
112
|
+
/**
|
|
113
|
+
* Bootstrap a service (load and start).
|
|
114
|
+
*
|
|
115
|
+
* @param plistPath - Path to the plist file
|
|
116
|
+
* @returns Result with success status and output
|
|
117
|
+
*/
|
|
118
|
+
declare function bootstrap(plistPath: string): Promise<{
|
|
119
|
+
success: boolean;
|
|
120
|
+
output: string;
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Bootout a service (unload and stop).
|
|
124
|
+
*
|
|
125
|
+
* @param label - Service label
|
|
126
|
+
* @returns Result with success status and output
|
|
127
|
+
*/
|
|
128
|
+
declare function bootout(label: string): Promise<{
|
|
129
|
+
success: boolean;
|
|
130
|
+
output: string;
|
|
131
|
+
}>;
|
|
132
|
+
/**
|
|
133
|
+
* Start a service (must be already bootstrapped).
|
|
134
|
+
*
|
|
135
|
+
* @param label - Service label
|
|
136
|
+
* @returns Result with success status and output
|
|
137
|
+
*/
|
|
138
|
+
declare function start(label: string): Promise<{
|
|
139
|
+
success: boolean;
|
|
140
|
+
output: string;
|
|
141
|
+
}>;
|
|
142
|
+
/**
|
|
143
|
+
* Stop a service (keeps it bootstrapped).
|
|
144
|
+
*
|
|
145
|
+
* @param label - Service label
|
|
146
|
+
* @returns Result with success status and output
|
|
147
|
+
*/
|
|
148
|
+
declare function stop(label: string): Promise<{
|
|
149
|
+
success: boolean;
|
|
150
|
+
output: string;
|
|
151
|
+
}>;
|
|
152
|
+
/**
|
|
153
|
+
* Enable a service so it can be started by launchd.
|
|
154
|
+
*
|
|
155
|
+
* @param label - Service label
|
|
156
|
+
* @returns Result with success status and output
|
|
157
|
+
*/
|
|
158
|
+
declare function enable(label: string): Promise<{
|
|
159
|
+
success: boolean;
|
|
160
|
+
output: string;
|
|
161
|
+
}>;
|
|
162
|
+
/**
|
|
163
|
+
* Disable a service so launchd will not start it on login.
|
|
164
|
+
*
|
|
165
|
+
* @param label - Service label
|
|
166
|
+
* @returns Result with success status and output
|
|
167
|
+
*/
|
|
168
|
+
declare function disable(label: string): Promise<{
|
|
169
|
+
success: boolean;
|
|
170
|
+
output: string;
|
|
171
|
+
}>;
|
|
172
|
+
/**
|
|
173
|
+
* Get service information.
|
|
174
|
+
*
|
|
175
|
+
* @param label - Service label
|
|
176
|
+
* @returns Parsed service info or null if not found
|
|
177
|
+
*/
|
|
178
|
+
declare function print(label: string): Promise<LaunchctlPrintOutput | null>;
|
|
179
|
+
/**
|
|
180
|
+
* List all services matching a pattern.
|
|
181
|
+
*
|
|
182
|
+
* @param pattern - Optional pattern to filter services
|
|
183
|
+
* @returns Array of service items
|
|
184
|
+
*/
|
|
185
|
+
declare function list(pattern?: string): Promise<LaunchctlListItem[]>;
|
|
186
|
+
declare const _default: {
|
|
187
|
+
bootstrap: typeof bootstrap;
|
|
188
|
+
bootout: typeof bootout;
|
|
189
|
+
enable: typeof enable;
|
|
190
|
+
disable: typeof disable;
|
|
191
|
+
start: typeof start;
|
|
192
|
+
stop: typeof stop;
|
|
193
|
+
print: typeof print;
|
|
194
|
+
list: typeof list;
|
|
195
|
+
getUserDomain: typeof getUserDomain;
|
|
196
|
+
};
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/lib/project/git.d.ts
|
|
199
|
+
/** Run `git pull` in the given directory. */
|
|
200
|
+
declare const gitPull: (cwd: string) => Promise<boolean>;
|
|
201
|
+
/** Check if a git working tree has uncommitted changes. */
|
|
202
|
+
declare const isWorkingTreeDirty: (cwd: string) => Promise<boolean>;
|
|
203
|
+
type ProjectWorktree = {
|
|
204
|
+
/** Absolute path of the detached worktree's checkout. */path: string; /** Branch checked out in the detached worktree. */
|
|
205
|
+
branch: string;
|
|
206
|
+
};
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/lib/project.d.ts
|
|
209
|
+
/**
|
|
210
|
+
* A project is the primary git checkout plus every detached worktree that
|
|
211
|
+
* descends from it. Its identity (`id`, `slug`, `refs`, `path`, `name`) is the
|
|
212
|
+
* primary checkout's.
|
|
213
|
+
*
|
|
214
|
+
* Everything path-sensitive (config, dependencies, actions, services) lives on
|
|
215
|
+
* a {@link Worktree}. Use `activeWorktree` for the checkout a command is acting
|
|
216
|
+
* on, `primaryWorktree` for the project root, or `worktree(branch)` to select a
|
|
217
|
+
* specific one.
|
|
218
|
+
*/
|
|
219
|
+
declare class DenvigProject {
|
|
220
|
+
/** The primary checkout (`main`). Defines the project's identity. */
|
|
221
|
+
readonly primaryWorktree: Worktree;
|
|
222
|
+
/** Every checkout: the primary plus all detached worktrees. */
|
|
223
|
+
readonly worktrees: Worktree[];
|
|
224
|
+
/** The checkout this project instance is acting on. */
|
|
225
|
+
activeWorktree: Worktree;
|
|
226
|
+
private constructor();
|
|
227
|
+
/**
|
|
228
|
+
* Retrieve a project from any path inside it (the primary checkout or a
|
|
229
|
+
* detached worktree). The project's identity is rooted at the primary, and
|
|
230
|
+
* the checkout matching `projectPath` becomes the active worktree.
|
|
231
|
+
*/
|
|
232
|
+
static retrieve(projectPath: string): Promise<DenvigProject>;
|
|
233
|
+
/** Select a worktree by branch. `main` resolves to the primary checkout. */
|
|
234
|
+
worktree(branch: string): Worktree | null;
|
|
235
|
+
/** Project identity, rooted at the primary checkout. */
|
|
236
|
+
get id(): string;
|
|
237
|
+
get slug(): string;
|
|
238
|
+
/**
|
|
239
|
+
* All identifiers for the project. See `projectRefs()` for the format
|
|
240
|
+
* of each ref (`id:`, `local:`, `github:`, `git:`).
|
|
241
|
+
*/
|
|
242
|
+
get refs(): string[];
|
|
243
|
+
get name(): string;
|
|
244
|
+
/** Absolute path of the primary checkout. */
|
|
245
|
+
get path(): string;
|
|
246
|
+
}
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/lib/projectInfo.d.ts
|
|
249
|
+
type ServiceStatus$1 = 'running' | 'stopped' | 'none';
|
|
250
|
+
type ProjectInfo = {
|
|
251
|
+
id: string;
|
|
252
|
+
slug: string;
|
|
253
|
+
name: string;
|
|
254
|
+
path: string;
|
|
255
|
+
refs: string[];
|
|
256
|
+
worktrees: ProjectWorktree[];
|
|
257
|
+
config: ProjectConfigSchema | null;
|
|
258
|
+
serviceStatus: ServiceStatus$1;
|
|
259
|
+
};
|
|
260
|
+
type GetProjectInfoOptions = {
|
|
261
|
+
/** Pre-fetched launchctl list to avoid repeated shell calls */launchctlList?: LaunchctlListItem[]; /** Include service status in the response (requires launchctl calls) */
|
|
262
|
+
includeServiceStatus?: boolean;
|
|
263
|
+
};
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/types/responses.d.ts
|
|
266
|
+
/**
|
|
267
|
+
* Service information for display.
|
|
268
|
+
*/
|
|
269
|
+
type ServiceInfo = {
|
|
270
|
+
name: string;
|
|
271
|
+
cwd: string;
|
|
272
|
+
command: string;
|
|
273
|
+
http?: {
|
|
274
|
+
port?: number;
|
|
275
|
+
domain?: string;
|
|
276
|
+
secure?: boolean;
|
|
277
|
+
};
|
|
278
|
+
startOnBoot?: boolean;
|
|
279
|
+
};
|
|
280
|
+
/**
|
|
281
|
+
* Result of a service operation.
|
|
282
|
+
*/
|
|
283
|
+
type ServiceResult = {
|
|
284
|
+
name: string;
|
|
285
|
+
success: boolean;
|
|
286
|
+
message: string;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Status of a running service.
|
|
290
|
+
*/
|
|
291
|
+
type ServiceStatus = {
|
|
292
|
+
name: string;
|
|
293
|
+
running: boolean;
|
|
294
|
+
pid?: number;
|
|
295
|
+
uptime?: string;
|
|
296
|
+
command: string;
|
|
297
|
+
cwd: string;
|
|
298
|
+
logs?: string[];
|
|
299
|
+
logPath: string;
|
|
300
|
+
lastExitCode?: number;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Project data included in service responses.
|
|
304
|
+
*/
|
|
305
|
+
type ServiceProjectData = {
|
|
306
|
+
id: string;
|
|
307
|
+
slug: string;
|
|
308
|
+
name: string;
|
|
309
|
+
path: string;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* Unified service response for all service commands.
|
|
313
|
+
* Used by list, status, start, stop, and restart commands.
|
|
314
|
+
*/
|
|
315
|
+
type ServiceResponse = {
|
|
316
|
+
name: string;
|
|
317
|
+
project: ServiceProjectData;
|
|
318
|
+
status: 'running' | 'error' | 'stopped';
|
|
319
|
+
pid: number | null;
|
|
320
|
+
/**
|
|
321
|
+
* Canonical URL for the service. The domain URL when this service owns
|
|
322
|
+
* the gateway route, otherwise a direct `http://localhost:<port>` URL.
|
|
323
|
+
*/
|
|
324
|
+
url: string | null;
|
|
325
|
+
/**
|
|
326
|
+
* Direct `http://localhost:<port>` URL when an effective port is known.
|
|
327
|
+
* Useful when the gateway route is held by another service (e.g. a
|
|
328
|
+
* sibling worktree) and `url` falls back to the localhost form already.
|
|
329
|
+
*/
|
|
330
|
+
localUrl: string | null; /** Effective port the service is configured to listen on. */
|
|
331
|
+
port: number | null; /** Port declared in the service config, if any. */
|
|
332
|
+
configPort: number | null;
|
|
333
|
+
command: string;
|
|
334
|
+
cwd: string;
|
|
335
|
+
logPath: string;
|
|
336
|
+
envFiles: string[];
|
|
337
|
+
lastExitCode: number | null;
|
|
338
|
+
logs?: string[];
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Version information for a dependency.
|
|
342
|
+
*/
|
|
343
|
+
type DependencyVersion = {
|
|
344
|
+
resolved: string;
|
|
345
|
+
specifier: string;
|
|
346
|
+
source: string;
|
|
347
|
+
wanted?: string;
|
|
348
|
+
latest?: string;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* A project dependency from deps:list command.
|
|
352
|
+
*/
|
|
353
|
+
type Dependency = {
|
|
354
|
+
id: string;
|
|
355
|
+
name: string;
|
|
356
|
+
versions: DependencyVersion[];
|
|
357
|
+
ecosystem: string;
|
|
358
|
+
};
|
|
359
|
+
/**
|
|
360
|
+
* An outdated dependency from deps:outdated command.
|
|
361
|
+
*/
|
|
362
|
+
type OutdatedDependency = Dependency & {
|
|
363
|
+
wanted: string;
|
|
364
|
+
latest: string;
|
|
365
|
+
specifier: string;
|
|
366
|
+
isDevDependency: boolean;
|
|
367
|
+
currentDate?: string;
|
|
368
|
+
wantedDate?: string;
|
|
369
|
+
latestDate?: string;
|
|
370
|
+
};
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region src/lib/plugin.d.ts
|
|
373
|
+
/**
|
|
374
|
+
* Options for outdatedDependencies method
|
|
375
|
+
*/
|
|
376
|
+
type OutdatedDependenciesOptions = {
|
|
377
|
+
/** Use cache for registry requests (default: true) */cache?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* How many levels of the dependency tree to include.
|
|
380
|
+
* 0 (default) = direct dependencies only.
|
|
381
|
+
* N > 0 = direct deps plus transitive dependencies up to depth N.
|
|
382
|
+
*/
|
|
383
|
+
depth?: number;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* Options for deduplicateDependencies method
|
|
387
|
+
*/
|
|
388
|
+
type DeduplicateDependenciesOptions = {
|
|
389
|
+
/** Only analyze without applying changes (default: false) */dryRun?: boolean;
|
|
390
|
+
};
|
|
391
|
+
/**
|
|
392
|
+
* Details of a package that can be deduplicated.
|
|
393
|
+
*/
|
|
394
|
+
type DeduplicateDetail = {
|
|
395
|
+
name: string;
|
|
396
|
+
versions: string[];
|
|
397
|
+
optimisedVersions: string[];
|
|
398
|
+
};
|
|
399
|
+
/**
|
|
400
|
+
* Result of a deduplication analysis/operation.
|
|
401
|
+
*/
|
|
402
|
+
type DeduplicateResult = {
|
|
403
|
+
ecosystem: string;
|
|
404
|
+
totalDependencies: number;
|
|
405
|
+
optimisedDependencies: number;
|
|
406
|
+
removals: Record<string, string[]>;
|
|
407
|
+
details: DeduplicateDetail[];
|
|
408
|
+
applied: boolean;
|
|
409
|
+
};
|
|
410
|
+
//#endregion
|
|
411
|
+
//#region src/lib/project/worktree.d.ts
|
|
412
|
+
/**
|
|
413
|
+
* A single git checkout belonging to a project — either the primary checkout
|
|
414
|
+
* or a detached worktree. Everything path-sensitive (config, dependencies,
|
|
415
|
+
* actions, refs) lives here, since these all differ between checkouts.
|
|
416
|
+
*
|
|
417
|
+
* A worktree's `refs`, `id` and `slug` are derived from its own path, so they
|
|
418
|
+
* match the values the legacy `DenvigProject` produced for that checkout. This
|
|
419
|
+
* keeps service state keys (which are derived from these) stable across the
|
|
420
|
+
* project-owns-worktrees refactor.
|
|
421
|
+
*/
|
|
422
|
+
declare class Worktree {
|
|
423
|
+
/** Absolute path of this checkout. */
|
|
424
|
+
readonly path: string;
|
|
425
|
+
/** Branch checked out here. The primary checkout always reports `main`. */
|
|
426
|
+
readonly branch: string;
|
|
427
|
+
/** True when this is the project's primary checkout. */
|
|
428
|
+
readonly isPrimary: boolean;
|
|
429
|
+
/** All identifiers for this checkout. See `projectRefs()` for the format. */
|
|
430
|
+
readonly refs: string[];
|
|
431
|
+
readonly slug: string;
|
|
432
|
+
readonly id: string;
|
|
433
|
+
config: ConfigWithSourcePaths<ProjectConfigSchema>;
|
|
434
|
+
private _rootFilesCache;
|
|
435
|
+
private constructor();
|
|
436
|
+
/** Retrieve a worktree by looking up its config and root files. */
|
|
437
|
+
static retrieve(path: string, branch: string, isPrimary: boolean): Promise<Worktree>;
|
|
438
|
+
get name(): string;
|
|
439
|
+
/** List of files in the root of this checkout. */
|
|
440
|
+
get rootFiles(): string[];
|
|
441
|
+
get packageManagers(): string[];
|
|
442
|
+
get primaryPackageManager(): string | null;
|
|
443
|
+
dependencies(): Promise<Dependency[]>;
|
|
444
|
+
outdatedDependencies(options?: OutdatedDependenciesOptions): Promise<OutdatedDependency[]>;
|
|
445
|
+
deduplicateDependencies(options?: DeduplicateDependenciesOptions): Promise<DeduplicateResult[]>;
|
|
446
|
+
/** All actions that can be run for this checkout. */
|
|
447
|
+
get actions(): Promise<Actions>;
|
|
448
|
+
/** All services defined in this checkout's configuration. */
|
|
449
|
+
get services(): Record<string, {
|
|
450
|
+
command: string;
|
|
451
|
+
cwd?: string | undefined;
|
|
452
|
+
http?: {
|
|
453
|
+
port?: number | undefined;
|
|
454
|
+
domain?: string | undefined;
|
|
455
|
+
cnames?: string[] | undefined;
|
|
456
|
+
secure?: boolean | undefined;
|
|
457
|
+
} | undefined;
|
|
458
|
+
envFiles?: string[] | undefined;
|
|
459
|
+
env?: Record<string, string> | undefined;
|
|
460
|
+
keepAlive?: boolean | undefined;
|
|
461
|
+
startOnBoot?: boolean | undefined;
|
|
462
|
+
}>;
|
|
463
|
+
/** Find all files recursively with a given name in this checkout. */
|
|
464
|
+
findFilesByName(fileName: string): Promise<string[]>;
|
|
465
|
+
}
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/lib/formatters/tree-node.d.ts
|
|
468
|
+
/**
|
|
469
|
+
* A node in a tree structure for rendering. The shape is produced by logic in
|
|
470
|
+
* the SDK (e.g. dependency chains) and consumed by the CLI's tree renderer.
|
|
471
|
+
*/
|
|
472
|
+
type TreeNode = {
|
|
473
|
+
name: string;
|
|
474
|
+
version: string;
|
|
475
|
+
children: TreeNode[]; /** Optional ANSI color applied to the entire `name version` body. */
|
|
476
|
+
color?: string; /** Optional preformatted suffix appended after the version. */
|
|
477
|
+
suffix?: string;
|
|
478
|
+
};
|
|
479
|
+
//#endregion
|
|
480
|
+
//#region src/lib/deps/tree.d.ts
|
|
481
|
+
/**
|
|
482
|
+
* A dependency entry with tree metadata for rendering.
|
|
483
|
+
*/
|
|
484
|
+
type TreeDependencyEntry = {
|
|
485
|
+
name: string;
|
|
486
|
+
version: string;
|
|
487
|
+
ecosystem: string;
|
|
488
|
+
isDevDependency: boolean;
|
|
489
|
+
depth: number;
|
|
490
|
+
isLast: boolean;
|
|
491
|
+
hasChildren: boolean;
|
|
492
|
+
parentPath: boolean[];
|
|
493
|
+
dependencyType?: string;
|
|
494
|
+
};
|
|
495
|
+
/**
|
|
496
|
+
* Check if a source is from devDependencies section.
|
|
497
|
+
*/
|
|
498
|
+
declare const isDevDependenciesSource: (source: string) => boolean;
|
|
499
|
+
/**
|
|
500
|
+
* Build a reverse dependency chain from a target dependency back to a direct dependency.
|
|
501
|
+
* Returns the chain as a tree structure starting from the root, or null if chain cannot be built.
|
|
502
|
+
*/
|
|
503
|
+
declare const buildReverseChain: (targetName: string, targetVersion: string, source: string, depsMap: Map<string, Dependency>) => TreeNode | null;
|
|
504
|
+
//#endregion
|
|
505
|
+
//#region src/lib/services/manager.d.ts
|
|
506
|
+
type ServiceConfig = NonNullable<ProjectConfigSchema['services']>[string];
|
|
507
|
+
/**
|
|
508
|
+
* Minimal project shape required by ServiceManager.
|
|
509
|
+
* DenvigProject structurally satisfies this type.
|
|
510
|
+
*/
|
|
511
|
+
type ServiceManagerProject = {
|
|
512
|
+
id: string;
|
|
513
|
+
slug: string;
|
|
514
|
+
name: string;
|
|
515
|
+
path: string;
|
|
516
|
+
config: {
|
|
517
|
+
services?: ProjectConfigSchema['services'];
|
|
518
|
+
};
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Manager for project services.
|
|
522
|
+
*/
|
|
523
|
+
declare class ServiceManager {
|
|
524
|
+
private project;
|
|
525
|
+
constructor(project: ServiceManagerProject);
|
|
526
|
+
/**
|
|
527
|
+
* List all services defined in the project configuration.
|
|
528
|
+
*/
|
|
529
|
+
listServices(): Promise<ServiceInfo[]>;
|
|
530
|
+
/**
|
|
531
|
+
* Build environment variables for a service.
|
|
532
|
+
* This loads env files and merges with explicit env config.
|
|
533
|
+
* All env files are optional - missing files are silently skipped.
|
|
534
|
+
*
|
|
535
|
+
* @param options.port - Effective port for the service. When provided,
|
|
536
|
+
* overrides any port defined in config and is exported as `PORT` in
|
|
537
|
+
* the service environment.
|
|
538
|
+
*/
|
|
539
|
+
buildServiceEnvironment(name: string, options?: {
|
|
540
|
+
port?: number;
|
|
541
|
+
}): Promise<{
|
|
542
|
+
success: true;
|
|
543
|
+
env: Record<string, string>;
|
|
544
|
+
} | {
|
|
545
|
+
success: false;
|
|
546
|
+
message: string;
|
|
547
|
+
}>;
|
|
548
|
+
/**
|
|
549
|
+
* Decide which port to run a service on.
|
|
550
|
+
*
|
|
551
|
+
* Resolution order:
|
|
552
|
+
* 1. If `forceRandom`, always allocate a fresh random port (preferring the
|
|
553
|
+
* previously-allocated one when free).
|
|
554
|
+
* 2. If state already records a port for this service, reuse it. State is
|
|
555
|
+
* authoritative once allocated so restarts stay on the same port and
|
|
556
|
+
* don't re-prompt about the config port being busy. Run
|
|
557
|
+
* `services teardown` to reset.
|
|
558
|
+
* 3. Otherwise try the config port — falling back to a random port and
|
|
559
|
+
* flagging `conflict: true` when it's already in use.
|
|
560
|
+
* 4. Otherwise (no config port, no state) allocate a random port.
|
|
561
|
+
*/
|
|
562
|
+
resolveServicePort(name: string, options?: {
|
|
563
|
+
forceRandom?: boolean;
|
|
564
|
+
}): Promise<{
|
|
565
|
+
success: true;
|
|
566
|
+
port: number | undefined;
|
|
567
|
+
source: 'config' | 'allocated' | 'state' | 'none';
|
|
568
|
+
conflict: boolean;
|
|
569
|
+
configPort?: number;
|
|
570
|
+
} | {
|
|
571
|
+
success: false;
|
|
572
|
+
message: string;
|
|
573
|
+
}>;
|
|
574
|
+
/**
|
|
575
|
+
* Start a specific service.
|
|
576
|
+
*
|
|
577
|
+
* @param options.port - Pre-resolved port to use for this service. When
|
|
578
|
+
* omitted, the manager resolves the port itself, auto-allocating a
|
|
579
|
+
* random port if the config port is busy.
|
|
580
|
+
* @param options.claimDomain - When the service's configured domain is
|
|
581
|
+
* already claimed by a different project, this flag controls whether
|
|
582
|
+
* this start should replace the route as an override (`true`) or
|
|
583
|
+
* leave the existing route alone (`false`). When undefined and the
|
|
584
|
+
* domain has no existing owner, the route is registered as the
|
|
585
|
+
* natural owner (`defaultService: true`).
|
|
586
|
+
* @param options.reviveIfNotRunning - When the service is already
|
|
587
|
+
* bootstrapped with an unchanged plist but isn't currently running,
|
|
588
|
+
* bootout and bootstrap again to kick it (`true`, the default — what an
|
|
589
|
+
* explicit `start` wants). The reconciler passes `false`: a bootstrapped
|
|
590
|
+
* service's liveness is launchd's job (`KeepAlive` respawns it, one-shot
|
|
591
|
+
* services are meant to stay exited), so re-bootstrapping an unchanged
|
|
592
|
+
* plist is needless churn that fights launchd.
|
|
593
|
+
*/
|
|
594
|
+
startService(name: string, options?: {
|
|
595
|
+
port?: number;
|
|
596
|
+
portResolved?: boolean;
|
|
597
|
+
claimDomain?: boolean;
|
|
598
|
+
reviveIfNotRunning?: boolean;
|
|
599
|
+
}): Promise<ServiceResult>;
|
|
600
|
+
/**
|
|
601
|
+
* Stop a specific service.
|
|
602
|
+
*/
|
|
603
|
+
stopService(name: string): Promise<ServiceResult>;
|
|
604
|
+
/**
|
|
605
|
+
* Restart a specific service.
|
|
606
|
+
*/
|
|
607
|
+
restartService(name: string, options?: {
|
|
608
|
+
port?: number;
|
|
609
|
+
portResolved?: boolean;
|
|
610
|
+
claimDomain?: boolean;
|
|
611
|
+
}): Promise<ServiceResult>;
|
|
612
|
+
/**
|
|
613
|
+
* Get the status of a specific service.
|
|
614
|
+
*/
|
|
615
|
+
getServiceStatus(name: string): Promise<ServiceStatus | null>;
|
|
616
|
+
/**
|
|
617
|
+
* Start all services.
|
|
618
|
+
*/
|
|
619
|
+
startAll(): Promise<ServiceResult[]>;
|
|
620
|
+
/**
|
|
621
|
+
* Stop all running services.
|
|
622
|
+
*/
|
|
623
|
+
stopAll(): Promise<ServiceResult[]>;
|
|
624
|
+
/**
|
|
625
|
+
* Restart all services (only those currently bootstrapped).
|
|
626
|
+
*/
|
|
627
|
+
restartAll(): Promise<ServiceResult[]>;
|
|
628
|
+
/**
|
|
629
|
+
* Teardown all services for this project.
|
|
630
|
+
* Stops all services, removes them from launchctl, and deletes plist files.
|
|
631
|
+
* @param options.removeLogs - Also remove log files (default: false)
|
|
632
|
+
*/
|
|
633
|
+
teardownAll(options?: {
|
|
634
|
+
removeLogs?: boolean;
|
|
635
|
+
}): Promise<ServiceResult[]>;
|
|
636
|
+
/**
|
|
637
|
+
* Check if a service is bootstrapped (loaded in launchctl).
|
|
638
|
+
*/
|
|
639
|
+
isServiceBootstrapped(name: string): Promise<boolean>;
|
|
640
|
+
/**
|
|
641
|
+
* Normalize a string for use in launchctl labels and filenames.
|
|
642
|
+
* Replaces special characters with safe alternatives.
|
|
643
|
+
*/
|
|
644
|
+
private normalizeForLabel;
|
|
645
|
+
/**
|
|
646
|
+
* Get the service label for launchctl.
|
|
647
|
+
* Format: denvig.[projectId].[serviceName]
|
|
648
|
+
*/
|
|
649
|
+
getServiceLabel(name: string): string;
|
|
650
|
+
/**
|
|
651
|
+
* Get the denvig directory path.
|
|
652
|
+
*/
|
|
653
|
+
getDenvigHomeDir(): string;
|
|
654
|
+
/**
|
|
655
|
+
* Get the plist file path.
|
|
656
|
+
*/
|
|
657
|
+
getPlistPath(name: string): string;
|
|
658
|
+
/**
|
|
659
|
+
* Get the service-specific directory.
|
|
660
|
+
* Format: ~/.denvig/services/[projectId].[serviceName]/
|
|
661
|
+
*/
|
|
662
|
+
getServiceDir(name: string): string;
|
|
663
|
+
/**
|
|
664
|
+
* Get the service-specific log directory.
|
|
665
|
+
* Format: ~/.denvig/services/[projectId].[serviceName]/logs/
|
|
666
|
+
*/
|
|
667
|
+
getServiceLogDir(name: string): string;
|
|
668
|
+
/**
|
|
669
|
+
* Get the path to the service wrapper script.
|
|
670
|
+
* Includes the project slug in the filename for github projects so Login Items
|
|
671
|
+
* shows a meaningful name (e.g. "denvig-marcqualie-myapp-api").
|
|
672
|
+
*/
|
|
673
|
+
getServiceScriptPath(name: string): string;
|
|
674
|
+
/**
|
|
675
|
+
* Get the stable log path used by the plist StandardOutPath.
|
|
676
|
+
* This is a symlink that always points to the current timestamped log file.
|
|
677
|
+
* Format: ~/.denvig/services/[serviceId]/logs/latest.log
|
|
678
|
+
*/
|
|
679
|
+
getStableLogPath(name: string): string;
|
|
680
|
+
/**
|
|
681
|
+
* Get the log file path (symlink to latest log for this host).
|
|
682
|
+
* Format: ~/.denvig/services/[serviceId]/logs/latest.[hostname].log
|
|
683
|
+
*/
|
|
684
|
+
getLogPath(name: string, _type?: 'stdout' | 'stderr'): string;
|
|
685
|
+
/**
|
|
686
|
+
* Create a new timestamped log file and update the latest symlink.
|
|
687
|
+
* Returns the absolute path to the new log file.
|
|
688
|
+
*/
|
|
689
|
+
createLogFile(name: string): Promise<string>;
|
|
690
|
+
/**
|
|
691
|
+
* Ensure denvig directories exist.
|
|
692
|
+
*/
|
|
693
|
+
ensureDenvigDirectories(): Promise<void>;
|
|
694
|
+
/**
|
|
695
|
+
* Get recent log lines from a service.
|
|
696
|
+
*/
|
|
697
|
+
getRecentLogs(name: string, lines: number): Promise<string[]>;
|
|
698
|
+
/**
|
|
699
|
+
* Resolve the absolute working directory for a service.
|
|
700
|
+
*/
|
|
701
|
+
private resolveServiceCwd;
|
|
702
|
+
/**
|
|
703
|
+
* Get the configuration for a specific service.
|
|
704
|
+
*/
|
|
705
|
+
getServiceConfig(name: string): ServiceConfig | undefined;
|
|
706
|
+
/**
|
|
707
|
+
* Rebuild all gateway nginx configs across all projects.
|
|
708
|
+
* Removes stale configs and regenerates from current service definitions.
|
|
709
|
+
*/
|
|
710
|
+
reconfigureGateway(): Promise<void>;
|
|
711
|
+
/**
|
|
712
|
+
* Get the canonical URL where a service can be accessed. Returns the
|
|
713
|
+
* domain URL only when this service currently owns the gateway route for
|
|
714
|
+
* its configured domain; otherwise (or when no domain is configured)
|
|
715
|
+
* falls back to a direct `http://localhost:<port>` URL.
|
|
716
|
+
*/
|
|
717
|
+
getServiceUrl(name: string): Promise<string | null>;
|
|
718
|
+
/**
|
|
719
|
+
* Get the direct localhost URL for a service (`http://localhost:<port>`),
|
|
720
|
+
* or null if there's no effective port yet.
|
|
721
|
+
*/
|
|
722
|
+
getServiceLocalUrl(name: string): Promise<string | null>;
|
|
723
|
+
/**
|
|
724
|
+
* Get the effective runtime port for a service, considering state-tracked
|
|
725
|
+
* allocations first and falling back to the config port.
|
|
726
|
+
*/
|
|
727
|
+
getEffectivePort(name: string): Promise<number | undefined>;
|
|
728
|
+
/**
|
|
729
|
+
* Check if a plist file exists for a service.
|
|
730
|
+
*/
|
|
731
|
+
plistExists(name: string): Promise<boolean>;
|
|
732
|
+
/**
|
|
733
|
+
* Get a unified service response for a service.
|
|
734
|
+
* Returns null if the service is not found in configuration.
|
|
735
|
+
* @param name - Service name
|
|
736
|
+
* @param options.includeLogs - Whether to include recent logs (default: false)
|
|
737
|
+
* @param options.logLines - Number of log lines to include (default: 20)
|
|
738
|
+
* @param options.launchctlList - Pre-fetched launchctl list for batch operations (avoids N shell calls)
|
|
739
|
+
*/
|
|
740
|
+
getServiceResponse(name: string, options?: {
|
|
741
|
+
includeLogs?: boolean;
|
|
742
|
+
logLines?: number;
|
|
743
|
+
launchctlList?: LaunchctlListItem[];
|
|
744
|
+
}): Promise<ServiceResponse | null>;
|
|
745
|
+
}
|
|
746
|
+
//#endregion
|
|
747
|
+
//#region src/lib/teardown.d.ts
|
|
748
|
+
type TeardownResult = {
|
|
749
|
+
success: boolean;
|
|
750
|
+
services: ServiceResult[];
|
|
751
|
+
logsRemoved: boolean;
|
|
752
|
+
};
|
|
753
|
+
type ProjectTeardownResult = TeardownResult & {
|
|
754
|
+
project: string;
|
|
755
|
+
};
|
|
756
|
+
type TeardownOptions = {
|
|
757
|
+
removeLogs?: boolean;
|
|
758
|
+
};
|
|
759
|
+
/**
|
|
760
|
+
* Teardown all denvig services globally (across all projects).
|
|
761
|
+
*/
|
|
762
|
+
declare function teardownGlobal(options?: TeardownOptions): Promise<TeardownResult>;
|
|
763
|
+
//#endregion
|
|
764
|
+
export { _default as C, ProjectConfigSchema as D, GlobalConfigSchema as E, LaunchctlListItem as S, getGlobalConfig as T, ProjectInfo as _, TreeDependencyEntry as a, gitPull as b, TreeNode as c, DeduplicateResult as d, OutdatedDependenciesOptions as f, GetProjectInfoOptions as g, ServiceResponse as h, ServiceManagerProject as i, Worktree as l, OutdatedDependency as m, teardownGlobal as n, buildReverseChain as o, Dependency as p, ServiceManager as r, isDevDependenciesSource as s, ProjectTeardownResult as t, DeduplicateDependenciesOptions as u, ServiceStatus$1 as v, ConfigWithSourcePaths as w, isWorkingTreeDirty as x, DenvigProject as y };
|