@theholocron/cli 3.63.0 → 3.65.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/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Analytics, Auth, AuthDescription, AuthEvent, AuthEventType, AuthIdentity, AuthUser, CARDINALITY, CapabilityImpls, CapabilityKey, Cardinality, CardinalityFor, Ci, CiRun, CiRunFilter, CiRunStatus, ConnectionStringOptions, CreateAuthUserInput, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, Dns, DnsRecord, DnsRecordType, EnsureResult, Environment, EnvironmentReviewer, Environments, Errors, Issue, IssueSearchFilter, Issues, LabelDef, LifecycleResult, LifecycleSlot, Logs, NormalizedAuthUser, Notifications, PagesConfig, ParseWebhookInput, ProviderApiError, ProviderIdentity, PullRequest, REQUIRED_CAPABILITIES, RepoRef, RepoSettings, ResolvedCapability, Ruleset, SecretScope, Secrets, Source, StatusCategory, Storage, StorageBranch, TeamEntry, TeamPermission, Tooling, ToolingDoctorReport, TrackerDoctorReport, TrackerUser, Vault, WebhookDashboardInfo, WebhookVerificationError, Wiki, WikiDnsRecord, WikiProvisionOpts, WikiProxyConfig, Workers, isMulti } from "./plugin/capabilities.mjs";
2
2
  import { AuthError, RequestOptions, ResolveTokenConfig as ResolveTokenConfig$1, ResolveTokenInput, RestClient, RestClientConfig, createRestClient } from "@theholocron/http-client";
3
+ import { ConfigFileError } from "@theholocron/datapad";
3
4
  import { LogLevel } from "@theholocron/logger";
4
5
  //#region src/auth/auth-resolver.d.ts
5
6
  type ResolveTokenConfig = Omit<ResolveTokenConfig$1, "getKeyringToken">;
@@ -513,9 +514,6 @@ declare function compose(...args: (Capability | Capability[])[]): ComposedPreset
513
514
  declare function defineConfig(config: HolocronConfig): HolocronConfig;
514
515
  //#endregion
515
516
  //#region src/config/load-config.d.ts
516
- declare class ConfigFileError extends Error {
517
- name: string;
518
- }
519
517
  interface LoadedConfig {
520
518
  resolved: ResolvedHolocronConfig;
521
519
  /** Absolute path to the file the config was read from. */
@@ -523,8 +521,8 @@ interface LoadedConfig {
523
521
  }
524
522
  /**
525
523
  * Read + parse + resolve `holocron.config.*` from the given directory.
526
- * Search order: json → js → ts. Throws `ConfigFileError` if nothing
527
- * found, or `ConfigError` if the config is malformed / invalid.
524
+ * Throws {@link ConfigFileError} when nothing is found or a file cannot
525
+ * be loaded, or `ConfigError` when the config is invalid.
528
526
  */
529
527
  declare function loadConfig(cwd: string): Promise<LoadedConfig>;
530
528
  //#endregion
package/dist/index.mjs CHANGED
@@ -3,10 +3,10 @@ import { AuthError, createResolveToken as createResolveToken$1, createRestClient
3
3
  import { createEnvLookup } from "@theholocron/env-utils";
4
4
  import { Entry, findCredentials } from "@napi-rs/keyring";
5
5
  import { execFile } from "node:child_process";
6
- import { readFile, stat } from "node:fs/promises";
6
+ import { readFile } from "node:fs/promises";
7
7
  import { basename, dirname, join } from "node:path";
8
- import { pathToFileURL } from "node:url";
9
8
  import { promisify } from "node:util";
9
+ import { ConfigFileError, ConfigFileError as ConfigFileError$1, loadConfigFile } from "@theholocron/datapad";
10
10
  createEnvLookup();
11
11
  /**
12
12
  * Create an injectable env for commands that accept a fake env in tests.
@@ -312,74 +312,32 @@ function defineConfig(config) {
312
312
  //#endregion
313
313
  //#region src/config/load-config.ts
314
314
  /**
315
- * `holocron.config.{json,js,ts}` file loader.
315
+ * `holocron.config.{ts,js,mjs,cjs,json}` loader.
316
316
  *
317
- * Search order: json → js → ts. JSON is parsed directly; JS is loaded
318
- * via native dynamic import; TS is loaded via `tsImport` from tsx (a
319
- * runtime dep) so operators can write typed configs with `defineConfig`
320
- * without needing a separate build step.
317
+ * File discovery + module loading (typed configs via `tsx`, no build
318
+ * step) is delegated to `@theholocron/datapad`. This module keeps the
319
+ * holocron-specific parts: filling `name` / `repo.name` defaults and
320
+ * running the config through `resolveConfig`.
321
321
  *
322
- * All three forms are validated through the same `resolveConfig` path.
323
- * Implements the lookup-order contract from issue #75 / #81.
322
+ * Probe order is TS-first (`.ts` → `.js` → `.mjs` → `.cjs` → `.json`) —
323
+ * see ADR-0010 / issue #75 / #81.
324
324
  */
325
325
  const execFileAsync = promisify(execFile);
326
- const CANDIDATE_FILENAMES = [
327
- "holocron.config.json",
328
- "holocron.config.js",
329
- "holocron.config.ts"
330
- ];
331
- var ConfigFileError = class extends Error {
332
- name = "ConfigFileError";
333
- };
334
326
  /**
335
327
  * Read + parse + resolve `holocron.config.*` from the given directory.
336
- * Search order: json → js → ts. Throws `ConfigFileError` if nothing
337
- * found, or `ConfigError` if the config is malformed / invalid.
328
+ * Throws {@link ConfigFileError} when nothing is found or a file cannot
329
+ * be loaded, or `ConfigError` when the config is invalid.
338
330
  */
339
331
  async function loadConfig(cwd) {
340
- for (const filename of CANDIDATE_FILENAMES) {
341
- const fullPath = join(cwd, filename);
342
- if (await fileExists(fullPath)) {
343
- if (filename.endsWith(".json")) return {
344
- resolved: await loadJson(fullPath),
345
- filepath: fullPath
346
- };
347
- if (filename.endsWith(".ts")) return {
348
- resolved: await loadTs(fullPath),
349
- filepath: fullPath
350
- };
351
- return {
352
- resolved: await loadJs(fullPath),
353
- filepath: fullPath
354
- };
355
- }
356
- }
357
- throw new ConfigFileError(`no holocron.config.{json,js,ts} found in ${cwd}. Create one — see the README for the schema.`);
358
- }
359
- async function loadJson(filepath) {
360
- const raw = await readFile(filepath, "utf8");
361
- let parsed;
362
- try {
363
- parsed = JSON.parse(raw);
364
- } catch (err) {
365
- throw new ConfigError(`${filepath} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
366
- }
367
- return resolveConfig(await deriveDefaults(dirname(filepath), parsed));
368
- }
369
- async function loadJs(filepath) {
370
- const mod = await import(pathToFileURL(filepath).href);
371
- return resolveConfig(await deriveDefaults(dirname(filepath), extractRaw(filepath, mod)));
372
- }
373
- async function loadTs(filepath) {
374
- const { tsImport } = await import("tsx/esm/api");
375
- const mod = await tsImport(pathToFileURL(filepath).href, import.meta.url);
376
- return resolveConfig(await deriveDefaults(dirname(filepath), extractRaw(filepath, mod)));
377
- }
378
- function extractRaw(filepath, mod) {
379
- const outer = mod.default;
380
- const raw = outer?.__esModule === true ? outer.default : outer;
381
- if (raw === void 0 || raw === null) throw new ConfigFileError(`${filepath} must have a default export (use \`export default defineConfig({…})\`)`);
382
- return raw;
332
+ const found = await loadConfigFile({
333
+ cwd,
334
+ name: "holocron"
335
+ });
336
+ if (!found) throw new ConfigFileError$1(`no holocron.config.{ts,js,mjs,cjs,json} found in ${cwd}. Create one — see the README for the schema.`);
337
+ return {
338
+ resolved: resolveConfig(await deriveDefaults(dirname(found.filepath), found.config)),
339
+ filepath: found.filepath
340
+ };
383
341
  }
384
342
  async function deriveDefaults(configDir, raw) {
385
343
  const result = { ...raw };
@@ -420,12 +378,5 @@ function parseGitRemoteUrl(url) {
420
378
  const sshMatch = url.match(/github\.com:([^/]+\/[^/]+?)(?:\.git)?$/);
421
379
  if (sshMatch) return sshMatch[1];
422
380
  }
423
- async function fileExists(path) {
424
- try {
425
- return (await stat(path)).isFile();
426
- } catch {
427
- return false;
428
- }
429
- }
430
381
  //#endregion
431
382
  export { AuthError, CARDINALITY, ConfigError, ConfigFileError, ProviderApiError, REQUIRED_CAPABILITIES, WebhookVerificationError, compose, createFeatureResolver, createResolveToken, createRestClient, defineConfig, deleteToken, getToken, isMulti, listStoredProviders, loadConfig, resolveConfig, resolveEntry, resolvePluginPackage, setToken };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/cli",
3
- "version": "3.63.0",
3
+ "version": "3.65.0",
4
4
  "description": "The Holocron CLI — a pluggable, capability-based orchestrator for spinning up and operating software projects.",
5
5
  "keywords": [
6
6
  "cli",
@@ -47,13 +47,13 @@
47
47
  "@theholocron/env-utils": "^1.6.0",
48
48
  "@theholocron/github-client": "^1.14.2",
49
49
  "@theholocron/http-client": "^1.14.2",
50
- "@theholocron/registry-doc": "^1.10.0",
50
+ "@theholocron/registry-doc": "^1.11.0",
51
51
  "chalk": "^6.0.0",
52
52
  "ora": "^9.4.1",
53
53
  "posthog-node": "^5.51.6",
54
- "tsx": "4.23.12",
55
54
  "yargs": "^18.1.0",
56
- "@theholocron/logger": "3.63.0"
55
+ "@theholocron/logger": "3.65.0",
56
+ "@theholocron/datapad": "3.65.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@theholocron/eslint-config": "^7.32.1",
@@ -67,9 +67,10 @@
67
67
  "eslint-plugin-n": "^18.3.0",
68
68
  "globals": "^17.11.0",
69
69
  "tsdown": "^0.22.14",
70
+ "tsx": "4.23.12",
70
71
  "typescript": "^5.9.3",
71
72
  "vitest": "^4.1.11",
72
- "@theholocron/rollup-plugin-transform-template": "3.63.0"
73
+ "@theholocron/rollup-plugin-transform-template": "3.65.0"
73
74
  },
74
75
  "engines": {
75
76
  "node": ">=22.0.0"