@powerhousedao/shared 6.0.0-dev.216 → 6.0.0-dev.218
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/clis/index.d.mts +40 -13
- package/dist/clis/index.d.mts.map +1 -1
- package/dist/clis/index.mjs +25 -1
- package/dist/clis/index.mjs.map +1 -1
- package/dist/registry/index.d.ts +21 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +40 -5
- package/dist/registry/index.js.map +1 -1
- package/package.json +1 -1
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { B as RegistryPackageStatus, F as PackageInfo, I as RegistryPackage, L as RegistryPackageList, R as RegistryPackageMap, kt as DEFAULT_REGISTRY_URL, z as RegistryPackageSource } from "../types-1E8sqdB9.js";
|
|
2
2
|
|
|
3
3
|
//#region registry/registry.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extract the host portion of a registry URL — what npm uses as the key in
|
|
6
|
+
* `~/.npmrc` for per-registry tokens (e.g. `//registry.dev.vetra.io/`).
|
|
7
|
+
*/
|
|
8
|
+
declare function registryAuthKey(registryUrl: string): string;
|
|
4
9
|
interface ResolveRegistryUrlOptions {
|
|
5
10
|
/** Explicit registry URL (e.g. from --registry flag). Highest priority. */
|
|
6
11
|
registry?: string;
|
|
@@ -25,6 +30,9 @@ interface NpmPublishOptions {
|
|
|
25
30
|
cwd: string;
|
|
26
31
|
/** Additional arguments forwarded to npm publish. */
|
|
27
32
|
args?: string[];
|
|
33
|
+
/** Bearer token for the registry. When set, passed via a registry-scoped
|
|
34
|
+
* `_authToken` config flag rather than read from the user's `.npmrc`. */
|
|
35
|
+
authToken?: string;
|
|
28
36
|
}
|
|
29
37
|
interface NpmPublishResult {
|
|
30
38
|
/** stdout from npm publish. */
|
|
@@ -33,8 +41,18 @@ interface NpmPublishResult {
|
|
|
33
41
|
/**
|
|
34
42
|
* Run `npm publish` against the given registry.
|
|
35
43
|
* Uses spawn with args array to avoid shell injection.
|
|
44
|
+
*
|
|
45
|
+
* When `authToken` is provided, the token is passed via a registry-scoped
|
|
46
|
+
* `--//host/:_authToken=<token>` flag (npm's standard form for per-registry
|
|
47
|
+
* tokens) so we never have to write to `~/.npmrc`.
|
|
36
48
|
*/
|
|
37
49
|
declare function npmPublish(options: NpmPublishOptions): Promise<NpmPublishResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Write `_authToken=<token>` for the given registry host into `~/.npmrc`,
|
|
52
|
+
* preserving any other lines. Replaces the existing entry for the same key
|
|
53
|
+
* if present. Returns the absolute path to the npmrc that was written.
|
|
54
|
+
*/
|
|
55
|
+
declare function writeRegistryAuthToken(registryUrl: string, token: string): Promise<string>;
|
|
38
56
|
interface NpmUnpublishOptions {
|
|
39
57
|
/** Registry URL to unpublish from. */
|
|
40
58
|
registryUrl: string;
|
|
@@ -44,6 +62,8 @@ interface NpmUnpublishOptions {
|
|
|
44
62
|
spec: string;
|
|
45
63
|
/** Additional arguments forwarded to npm unpublish. */
|
|
46
64
|
args?: string[];
|
|
65
|
+
/** Bearer token for the registry (same semantics as `NpmPublishOptions.authToken`). */
|
|
66
|
+
authToken?: string;
|
|
47
67
|
}
|
|
48
68
|
interface NpmUnpublishResult {
|
|
49
69
|
/** stdout from npm unpublish. */
|
|
@@ -56,5 +76,5 @@ interface NpmUnpublishResult {
|
|
|
56
76
|
*/
|
|
57
77
|
declare function npmUnpublish(options: NpmUnpublishOptions): Promise<NpmUnpublishResult>;
|
|
58
78
|
//#endregion
|
|
59
|
-
export { DEFAULT_REGISTRY_URL, NpmPublishOptions, NpmPublishResult, NpmUnpublishOptions, NpmUnpublishResult, PackageInfo, RegistryPackage, RegistryPackageList, RegistryPackageMap, RegistryPackageSource, RegistryPackageStatus, ResolveRegistryUrlOptions, checkNpmAuth, npmPublish, npmUnpublish, resolveRegistryUrl };
|
|
79
|
+
export { DEFAULT_REGISTRY_URL, NpmPublishOptions, NpmPublishResult, NpmUnpublishOptions, NpmUnpublishResult, PackageInfo, RegistryPackage, RegistryPackageList, RegistryPackageMap, RegistryPackageSource, RegistryPackageStatus, ResolveRegistryUrlOptions, checkNpmAuth, npmPublish, npmUnpublish, registryAuthKey, resolveRegistryUrl, writeRegistryAuthToken };
|
|
60
80
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../registry/registry.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../registry/registry.ts"],"mappings":";;;;;;;iBAgBgB,eAAA,CAAgB,WAAA;AAAA,UAQf,yBAAA;;EAEf,QAAA;EAViD;EAYjD,WAAA;EAJwC;EAMxC,GAAA,GAAM,MAAA;AAAA;;;;iBAMQ,kBAAA,CAAmB,OAAA,EAAS,yBAAA;;;AAA5C;;iBAiBsB,YAAA,CAAa,WAAA,WAAsB,OAAA;AAAA,UAIxC,iBAAA;EArBoD;EAuBnE,WAAA;EANgC;EAQhC,GAAA;EARiC;EAUjC,IAAA;EANe;;EASf,SAAA;AAAA;AAAA,UAGe,gBAAA;EARf;EAUA,MAAA;AAAA;;;AAFF;;;;;AAaA;iBAAsB,UAAA,CACpB,OAAA,EAAS,iBAAA,GACR,OAAA,CAAQ,gBAAA;;;;;;iBAeW,sBAAA,CACpB,WAAA,UACA,KAAA,WACC,OAAA;AAAA,UAmBc,mBAAA;EAtCf;EAwCA,WAAA;EAvCS;EAyCT,GAAA;EAzCyB;EA2CzB,IAAA;EA5B0C;EA8B1C,IAAA;EA3BQ;EA6BR,SAAA;AAAA;AAAA,UAGe,kBAAA;EAhCP;EAkCR,MAAA;AAAA;;;;;;iBAQoB,YAAA,CACpB,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,kBAAA"}
|
package/dist/registry/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { promises, readFileSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import {
|
|
3
|
+
import { join } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
const DEFAULT_REGISTRY_URL = "https://registry.dev.vetra.io";
|
|
6
6
|
const POWERHOUSE_CONFIG_FILE = "powerhouse.config.json";
|
|
@@ -63,6 +63,15 @@ function spawnAsync(command, args, options = {}) {
|
|
|
63
63
|
//#endregion
|
|
64
64
|
//#region registry/registry.ts
|
|
65
65
|
/**
|
|
66
|
+
* Extract the host portion of a registry URL — what npm uses as the key in
|
|
67
|
+
* `~/.npmrc` for per-registry tokens (e.g. `//registry.dev.vetra.io/`).
|
|
68
|
+
*/
|
|
69
|
+
function registryAuthKey(registryUrl) {
|
|
70
|
+
const url = new URL(registryUrl);
|
|
71
|
+
const path = url.pathname.endsWith("/") ? url.pathname : `${url.pathname}/`;
|
|
72
|
+
return `//${url.host}${path}:_authToken`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
66
75
|
* Resolve the registry URL with priority: flag > env > config > default.
|
|
67
76
|
*/
|
|
68
77
|
function resolveRegistryUrl(options) {
|
|
@@ -84,33 +93,59 @@ async function checkNpmAuth(registryUrl) {
|
|
|
84
93
|
/**
|
|
85
94
|
* Run `npm publish` against the given registry.
|
|
86
95
|
* Uses spawn with args array to avoid shell injection.
|
|
96
|
+
*
|
|
97
|
+
* When `authToken` is provided, the token is passed via a registry-scoped
|
|
98
|
+
* `--//host/:_authToken=<token>` flag (npm's standard form for per-registry
|
|
99
|
+
* tokens) so we never have to write to `~/.npmrc`.
|
|
87
100
|
*/
|
|
88
101
|
async function npmPublish(options) {
|
|
89
|
-
const { registryUrl, cwd, args = [] } = options;
|
|
102
|
+
const { registryUrl, cwd, args = [], authToken } = options;
|
|
90
103
|
return { stdout: await spawnAsync("npm", [
|
|
91
104
|
"publish",
|
|
92
105
|
"--registry",
|
|
93
106
|
registryUrl,
|
|
107
|
+
...authToken ? [`--${registryAuthKey(registryUrl)}=${authToken}`] : [],
|
|
94
108
|
...args
|
|
95
109
|
], { cwd }) };
|
|
96
110
|
}
|
|
97
111
|
/**
|
|
112
|
+
* Write `_authToken=<token>` for the given registry host into `~/.npmrc`,
|
|
113
|
+
* preserving any other lines. Replaces the existing entry for the same key
|
|
114
|
+
* if present. Returns the absolute path to the npmrc that was written.
|
|
115
|
+
*/
|
|
116
|
+
async function writeRegistryAuthToken(registryUrl, token) {
|
|
117
|
+
const npmrcPath = join(homedir(), ".npmrc");
|
|
118
|
+
const key = registryAuthKey(registryUrl);
|
|
119
|
+
let existing = "";
|
|
120
|
+
try {
|
|
121
|
+
existing = await promises.readFile(npmrcPath, "utf8");
|
|
122
|
+
} catch (err) {
|
|
123
|
+
if (err.code !== "ENOENT") throw err;
|
|
124
|
+
}
|
|
125
|
+
const filtered = existing.split("\n").filter((line) => !line.startsWith(`${key}=`));
|
|
126
|
+
while (filtered.length && filtered[filtered.length - 1] === "") filtered.pop();
|
|
127
|
+
filtered.push(`${key}=${token}`);
|
|
128
|
+
await promises.writeFile(npmrcPath, `${filtered.join("\n")}\n`, "utf8");
|
|
129
|
+
return npmrcPath;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
98
132
|
* Run `npm unpublish` against the given registry.
|
|
99
133
|
* Always passes `--force` because npm otherwise refuses to unpublish packages
|
|
100
134
|
* older than 72h (a public-npmjs safeguard that doesn't apply to private registries).
|
|
101
135
|
*/
|
|
102
136
|
async function npmUnpublish(options) {
|
|
103
|
-
const { registryUrl, cwd, spec, args = [] } = options;
|
|
137
|
+
const { registryUrl, cwd, spec, args = [], authToken } = options;
|
|
104
138
|
return { stdout: await spawnAsync("npm", [
|
|
105
139
|
"unpublish",
|
|
106
140
|
spec,
|
|
107
141
|
"--registry",
|
|
108
142
|
registryUrl,
|
|
109
143
|
"--force",
|
|
144
|
+
...authToken ? [`--${registryAuthKey(registryUrl)}=${authToken}`] : [],
|
|
110
145
|
...args
|
|
111
146
|
], { cwd }) };
|
|
112
147
|
}
|
|
113
148
|
//#endregion
|
|
114
|
-
export { DEFAULT_REGISTRY_URL, checkNpmAuth, npmPublish, npmUnpublish, resolveRegistryUrl };
|
|
149
|
+
export { DEFAULT_REGISTRY_URL, checkNpmAuth, npmPublish, npmUnpublish, registryAuthKey, resolveRegistryUrl, writeRegistryAuthToken };
|
|
115
150
|
|
|
116
151
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../clis/constants.ts","../../clis/file-system/get-config.ts","../../clis/file-system/spawn-async.ts","../../registry/registry.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { PowerhouseConfig } from \"./types.js\";\n\nexport const SERVICE_ACTIONS = [\n \"start\",\n \"stop\",\n \"status\",\n \"setup\",\n \"restart\",\n] as const;\n\nexport const SECONDS_IN_DAY = 24 * 60 * 60;\nexport const DEFAULT_EXPIRY_DAYS = 7;\nexport const DEFAULT_EXPIRY_SECONDS = DEFAULT_EXPIRY_DAYS * SECONDS_IN_DAY;\n\nexport const DRIVES_PRESERVE_STRATEGIES = [\n \"preserve-all\",\n \"preserve-by-url-and-detach\",\n] as const;\n\nexport const LOG_LEVELS = [\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"verbose\",\n] as const;\n\nexport const DEFAULT_TIMEOUT = 300 as const;\n\nexport const DEFAULT_CONNECT_STUDIO_PORT = 3000 as const;\n\nexport const DEFAULT_VETRA_CONNECT_PORT = 3001 as const;\n\nexport const DEFAULT_CONNECT_PREVIEW_PORT = 4173 as const;\n\nexport const DEFAULT_CONNECT_OUTDIR = \".ph/connect-build/dist/\" as const;\n\nexport const DEFAULT_RENOWN_URL = \"https://www.renown.id\" as const;\n\nexport const DEFAULT_REGISTRY_URL = \"https://registry.dev.vetra.io\" as const;\n\nexport const DEFAULT_SWITCHBOARD_PORT = 4001 as const;\n\nexport const DEFAULT_VETRA_DRIVE_ID = \"vetra\" as const;\n\nexport const MINIMUM_NODE_VERSION = \"24.0.0\" as const;\nexport const PH_BIN = \"ph-cli-legacy\" as const;\nexport const POWERHOUSE_CONFIG_FILE = \"powerhouse.config.json\" as const;\nexport const PH_GLOBAL_DIR_NAME = \".ph\" as const;\n// Keep PH_GLOBAL_PROJECT_NAME for backwards compatibility\nexport const PH_GLOBAL_PROJECT_NAME = PH_GLOBAL_DIR_NAME;\n\nexport const HOME_DIR = homedir();\n\nexport const POWERHOUSE_GLOBAL_DIR = join(HOME_DIR, PH_GLOBAL_DIR_NAME);\n\nexport const VERSIONED_DEPENDENCIES = [\n \"document-model\",\n \"@powerhousedao/design-system\",\n \"@powerhousedao/reactor-api\",\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/connect\",\n \"@powerhousedao/shared\",\n \"@powerhousedao/analytics-engine-core\",\n];\n\nexport const VERSIONED_DEV_DEPENDENCIES = [\n \"@powerhousedao/ph-cli\",\n \"@powerhousedao/reactor\",\n];\n\nconst DEFAULT_DOCUMENT_MODELS_DIR = \"./document-models\";\nconst DEFAULT_EDITORS_DIR = \"./editors\";\nconst DEFAULT_PROCESSORS_DIR = \"./processors\";\nconst DEFAULT_SUBGRAPHS_DIR = \"./subgraphs\";\nconst DEFAULT_IMPORT_SCRIPTS_DIR = \"./scripts\";\nconst DEFAULT_SKIP_FORMAT = false;\nconst DEFAULT_LOG_LEVEL = \"info\";\n\nexport const DEFAULT_CONFIG: PowerhouseConfig = {\n documentModelsDir: DEFAULT_DOCUMENT_MODELS_DIR,\n editorsDir: DEFAULT_EDITORS_DIR,\n processorsDir: DEFAULT_PROCESSORS_DIR,\n subgraphsDir: DEFAULT_SUBGRAPHS_DIR,\n importScriptsDir: DEFAULT_IMPORT_SCRIPTS_DIR,\n skipFormat: DEFAULT_SKIP_FORMAT,\n logLevel: DEFAULT_LOG_LEVEL,\n auth: {\n enabled: false,\n admins: [],\n },\n};\n","import { readFileSync } from \"node:fs\";\nimport { DEFAULT_CONFIG } from \"../constants.js\";\nimport type { PowerhouseConfig } from \"../types.js\";\n\nexport function getConfig(path = \"./powerhouse.config.json\") {\n let config: PowerhouseConfig = { ...DEFAULT_CONFIG };\n try {\n const configStr = readFileSync(path, \"utf-8\");\n const userConfig = JSON.parse(configStr) as PowerhouseConfig;\n config = { ...config, ...userConfig };\n } catch {\n // console.warn(\"No powerhouse.config.json found, using defaults\");\n }\n\n return config;\n}\n","import { spawn } from \"node:child_process\";\n\nexport function spawnAsync(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n } = {},\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const cmd =\n process.platform === \"win32\" && command === \"npm\" ? \"npm.cmd\" : command;\n\n const child = spawn(cmd, args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (d: Buffer) => {\n stdout += d.toString();\n });\n\n child.stderr.on(\"data\", (d: Buffer) => {\n stderr += d.toString();\n });\n\n child.on(\"error\", reject);\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(stdout.trim());\n } else {\n reject(\n new Error(stderr.trim() || `${command} exited with code ${code}`),\n );\n }\n });\n });\n}\n","import { join } from \"node:path\";\nimport {\n DEFAULT_REGISTRY_URL,\n POWERHOUSE_CONFIG_FILE,\n} from \"../clis/constants.js\";\nimport { getConfig } from \"../clis/file-system/get-config.js\";\nimport { spawnAsync } from \"../clis/file-system/spawn-async.js\";\n\nexport { DEFAULT_REGISTRY_URL } from \"../clis/constants.js\";\n\nexport interface ResolveRegistryUrlOptions {\n /** Explicit registry URL (e.g. from --registry flag). Highest priority. */\n registry?: string;\n /** Project path to read powerhouse.config.json from. */\n projectPath: string;\n /** Environment variables. Defaults to process.env. */\n env?: Record<string, string | undefined>;\n}\n\n/**\n * Resolve the registry URL with priority: flag > env > config > default.\n */\nexport function resolveRegistryUrl(options: ResolveRegistryUrlOptions): string {\n const { registry, projectPath, env = process.env } = options;\n const configPath = join(projectPath, POWERHOUSE_CONFIG_FILE);\n const config = getConfig(configPath);\n\n return (\n registry ??\n env.PH_REGISTRY_URL ??\n config.packageRegistryUrl ??\n DEFAULT_REGISTRY_URL\n );\n}\n\n/**\n * Check if the user is authenticated with the given npm registry.\n * Returns the username on success, throws on failure.\n */\nexport async function checkNpmAuth(registryUrl: string): Promise<string> {\n return spawnAsync(\"npm\", [\"whoami\", \"--registry\", registryUrl]);\n}\n\nexport interface NpmPublishOptions {\n /** Registry URL to publish to. */\n registryUrl: string;\n /** Working directory (project root). */\n cwd: string;\n /** Additional arguments forwarded to npm publish. */\n args?: string[];\n}\n\nexport interface NpmPublishResult {\n /** stdout from npm publish. */\n stdout: string;\n}\n\n/**\n * Run `npm publish` against the given registry.\n * Uses spawn with args array to avoid shell injection.\n */\nexport async function npmPublish(\n options: NpmPublishOptions,\n): Promise<NpmPublishResult> {\n const { registryUrl, cwd, args = [] } = options;\n const npmArgs = [\"publish\", \"--registry\", registryUrl, ...args];\n const stdout = await spawnAsync(\"npm\", npmArgs, { cwd });\n return { stdout };\n}\n\nexport interface NpmUnpublishOptions {\n /** Registry URL to unpublish from. */\n registryUrl: string;\n /** Working directory (project root). */\n cwd: string;\n /** Package spec: `<name>` (whole package) or `<name>@<version>` (single version). */\n spec: string;\n /** Additional arguments forwarded to npm unpublish. */\n args?: string[];\n}\n\nexport interface NpmUnpublishResult {\n /** stdout from npm unpublish. */\n stdout: string;\n}\n\n/**\n * Run `npm unpublish` against the given registry.\n * Always passes `--force` because npm otherwise refuses to unpublish packages\n * older than 72h (a public-npmjs safeguard that doesn't apply to private registries).\n */\nexport async function npmUnpublish(\n options: NpmUnpublishOptions,\n): Promise<NpmUnpublishResult> {\n const { registryUrl, cwd, spec, args = [] } = options;\n const npmArgs = [\n \"unpublish\",\n spec,\n \"--registry\",\n registryUrl,\n \"--force\",\n ...args,\n ];\n const stdout = await spawnAsync(\"npm\", npmArgs, { cwd });\n return { stdout };\n}\n"],"mappings":";;;;AAyCA,MAAa,uBAAuB;AAQpC,MAAa,yBAAyB;AAOD,KAFb,SAAS,EAES,MAA6B;AAyBvE,MAAa,iBAAmC;CAC9C,mBATkC;CAUlC,YAT0B;CAU1B,eAT6B;CAU7B,cAT4B;CAU5B,kBATiC;CAUjC,YAT0B;CAU1B,UATwB;CAUxB,MAAM;EACJ,SAAS;EACT,QAAQ,EAAE;EACX;CACF;;;ACzFD,SAAgB,UAAU,OAAO,4BAA4B;CAC3D,IAAI,SAA2B,EAAE,GAAG,gBAAgB;AACpD,KAAI;EACF,MAAM,YAAY,aAAa,MAAM,QAAQ;EAC7C,MAAM,aAAa,KAAK,MAAM,UAAU;AACxC,WAAS;GAAE,GAAG;GAAQ,GAAG;GAAY;SAC/B;AAIR,QAAO;;;;ACZT,SAAgB,WACd,SACA,MACA,UAGI,EAAE,EACW;AACjB,QAAO,IAAI,SAAS,SAAS,WAAW;EAItC,MAAM,QAAQ,MAFZ,QAAQ,aAAa,WAAW,YAAY,QAAQ,YAAY,SAEzC,MAAM;GAC7B,KAAK,QAAQ;GACb,KAAK,QAAQ;GACb,OAAO;IAAC;IAAU;IAAQ;IAAO;GAClC,CAAC;EAEF,IAAI,SAAS;EACb,IAAI,SAAS;AAEb,QAAM,OAAO,GAAG,SAAS,MAAc;AACrC,aAAU,EAAE,UAAU;IACtB;AAEF,QAAM,OAAO,GAAG,SAAS,MAAc;AACrC,aAAU,EAAE,UAAU;IACtB;AAEF,QAAM,GAAG,SAAS,OAAO;AAEzB,QAAM,GAAG,UAAU,SAAS;AAC1B,OAAI,SAAS,EACX,SAAQ,OAAO,MAAM,CAAC;OAEtB,QACE,IAAI,MAAM,OAAO,MAAM,IAAI,GAAG,QAAQ,oBAAoB,OAAO,CAClE;IAEH;GACF;;;;;;;ACpBJ,SAAgB,mBAAmB,SAA4C;CAC7E,MAAM,EAAE,UAAU,aAAa,MAAM,QAAQ,QAAQ;CAErD,MAAM,SAAS,UADI,KAAK,aAAa,uBAAuB,CACxB;AAEpC,QACE,YACA,IAAI,mBACJ,OAAO,sBAAA;;;;;;AASX,eAAsB,aAAa,aAAsC;AACvE,QAAO,WAAW,OAAO;EAAC;EAAU;EAAc;EAAY,CAAC;;;;;;AAqBjE,eAAsB,WACpB,SAC2B;CAC3B,MAAM,EAAE,aAAa,KAAK,OAAO,EAAE,KAAK;AAGxC,QAAO,EAAE,QADM,MAAM,WAAW,OADhB;EAAC;EAAW;EAAc;EAAa,GAAG;EAAK,EACf,EAAE,KAAK,CAAC,EACvC;;;;;;;AAwBnB,eAAsB,aACpB,SAC6B;CAC7B,MAAM,EAAE,aAAa,KAAK,MAAM,OAAO,EAAE,KAAK;AAU9C,QAAO,EAAE,QADM,MAAM,WAAW,OARhB;EACd;EACA;EACA;EACA;EACA;EACA,GAAG;EACJ,EAC+C,EAAE,KAAK,CAAC,EACvC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["fs"],"sources":["../../clis/constants.ts","../../clis/file-system/get-config.ts","../../clis/file-system/spawn-async.ts","../../registry/registry.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { PowerhouseConfig } from \"./types.js\";\n\nexport const SERVICE_ACTIONS = [\n \"start\",\n \"stop\",\n \"status\",\n \"setup\",\n \"restart\",\n] as const;\n\nexport const SECONDS_IN_DAY = 24 * 60 * 60;\nexport const DEFAULT_EXPIRY_DAYS = 7;\nexport const DEFAULT_EXPIRY_SECONDS = DEFAULT_EXPIRY_DAYS * SECONDS_IN_DAY;\n\nexport const DRIVES_PRESERVE_STRATEGIES = [\n \"preserve-all\",\n \"preserve-by-url-and-detach\",\n] as const;\n\nexport const LOG_LEVELS = [\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"verbose\",\n] as const;\n\nexport const DEFAULT_TIMEOUT = 300 as const;\n\nexport const DEFAULT_CONNECT_STUDIO_PORT = 3000 as const;\n\nexport const DEFAULT_VETRA_CONNECT_PORT = 3001 as const;\n\nexport const DEFAULT_CONNECT_PREVIEW_PORT = 4173 as const;\n\nexport const DEFAULT_CONNECT_OUTDIR = \".ph/connect-build/dist/\" as const;\n\nexport const DEFAULT_RENOWN_URL = \"https://www.renown.id\" as const;\n\nexport const DEFAULT_REGISTRY_URL = \"https://registry.dev.vetra.io\" as const;\n\nexport const DEFAULT_SWITCHBOARD_PORT = 4001 as const;\n\nexport const DEFAULT_VETRA_DRIVE_ID = \"vetra\" as const;\n\nexport const MINIMUM_NODE_VERSION = \"24.0.0\" as const;\nexport const PH_BIN = \"ph-cli-legacy\" as const;\nexport const POWERHOUSE_CONFIG_FILE = \"powerhouse.config.json\" as const;\nexport const PH_GLOBAL_DIR_NAME = \".ph\" as const;\n// Keep PH_GLOBAL_PROJECT_NAME for backwards compatibility\nexport const PH_GLOBAL_PROJECT_NAME = PH_GLOBAL_DIR_NAME;\n\nexport const HOME_DIR = homedir();\n\nexport const POWERHOUSE_GLOBAL_DIR = join(HOME_DIR, PH_GLOBAL_DIR_NAME);\n\nexport const VERSIONED_DEPENDENCIES = [\n \"document-model\",\n \"@powerhousedao/design-system\",\n \"@powerhousedao/reactor-api\",\n \"@powerhousedao/reactor-browser\",\n \"@powerhousedao/connect\",\n \"@powerhousedao/shared\",\n \"@powerhousedao/analytics-engine-core\",\n];\n\nexport const VERSIONED_DEV_DEPENDENCIES = [\n \"@powerhousedao/ph-cli\",\n \"@powerhousedao/reactor\",\n];\n\nconst DEFAULT_DOCUMENT_MODELS_DIR = \"./document-models\";\nconst DEFAULT_EDITORS_DIR = \"./editors\";\nconst DEFAULT_PROCESSORS_DIR = \"./processors\";\nconst DEFAULT_SUBGRAPHS_DIR = \"./subgraphs\";\nconst DEFAULT_IMPORT_SCRIPTS_DIR = \"./scripts\";\nconst DEFAULT_SKIP_FORMAT = false;\nconst DEFAULT_LOG_LEVEL = \"info\";\n\nexport const DEFAULT_CONFIG: PowerhouseConfig = {\n documentModelsDir: DEFAULT_DOCUMENT_MODELS_DIR,\n editorsDir: DEFAULT_EDITORS_DIR,\n processorsDir: DEFAULT_PROCESSORS_DIR,\n subgraphsDir: DEFAULT_SUBGRAPHS_DIR,\n importScriptsDir: DEFAULT_IMPORT_SCRIPTS_DIR,\n skipFormat: DEFAULT_SKIP_FORMAT,\n logLevel: DEFAULT_LOG_LEVEL,\n auth: {\n enabled: false,\n admins: [],\n },\n};\n","import { readFileSync } from \"node:fs\";\nimport { DEFAULT_CONFIG } from \"../constants.js\";\nimport type { PowerhouseConfig } from \"../types.js\";\n\nexport function getConfig(path = \"./powerhouse.config.json\") {\n let config: PowerhouseConfig = { ...DEFAULT_CONFIG };\n try {\n const configStr = readFileSync(path, \"utf-8\");\n const userConfig = JSON.parse(configStr) as PowerhouseConfig;\n config = { ...config, ...userConfig };\n } catch {\n // console.warn(\"No powerhouse.config.json found, using defaults\");\n }\n\n return config;\n}\n","import { spawn } from \"node:child_process\";\n\nexport function spawnAsync(\n command: string,\n args: string[],\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n } = {},\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const cmd =\n process.platform === \"win32\" && command === \"npm\" ? \"npm.cmd\" : command;\n\n const child = spawn(cmd, args, {\n cwd: options.cwd,\n env: options.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout.on(\"data\", (d: Buffer) => {\n stdout += d.toString();\n });\n\n child.stderr.on(\"data\", (d: Buffer) => {\n stderr += d.toString();\n });\n\n child.on(\"error\", reject);\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(stdout.trim());\n } else {\n reject(\n new Error(stderr.trim() || `${command} exited with code ${code}`),\n );\n }\n });\n });\n}\n","import { promises as fs } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n DEFAULT_REGISTRY_URL,\n POWERHOUSE_CONFIG_FILE,\n} from \"../clis/constants.js\";\nimport { getConfig } from \"../clis/file-system/get-config.js\";\nimport { spawnAsync } from \"../clis/file-system/spawn-async.js\";\n\nexport { DEFAULT_REGISTRY_URL } from \"../clis/constants.js\";\n\n/**\n * Extract the host portion of a registry URL — what npm uses as the key in\n * `~/.npmrc` for per-registry tokens (e.g. `//registry.dev.vetra.io/`).\n */\nexport function registryAuthKey(registryUrl: string): string {\n const url = new URL(registryUrl);\n // Always trailing slash; npm's lookup is exact-match against the leading\n // path of the registry URL, with `//` prefix and trailing `/`.\n const path = url.pathname.endsWith(\"/\") ? url.pathname : `${url.pathname}/`;\n return `//${url.host}${path}:_authToken`;\n}\n\nexport interface ResolveRegistryUrlOptions {\n /** Explicit registry URL (e.g. from --registry flag). Highest priority. */\n registry?: string;\n /** Project path to read powerhouse.config.json from. */\n projectPath: string;\n /** Environment variables. Defaults to process.env. */\n env?: Record<string, string | undefined>;\n}\n\n/**\n * Resolve the registry URL with priority: flag > env > config > default.\n */\nexport function resolveRegistryUrl(options: ResolveRegistryUrlOptions): string {\n const { registry, projectPath, env = process.env } = options;\n const configPath = join(projectPath, POWERHOUSE_CONFIG_FILE);\n const config = getConfig(configPath);\n\n return (\n registry ??\n env.PH_REGISTRY_URL ??\n config.packageRegistryUrl ??\n DEFAULT_REGISTRY_URL\n );\n}\n\n/**\n * Check if the user is authenticated with the given npm registry.\n * Returns the username on success, throws on failure.\n */\nexport async function checkNpmAuth(registryUrl: string): Promise<string> {\n return spawnAsync(\"npm\", [\"whoami\", \"--registry\", registryUrl]);\n}\n\nexport interface NpmPublishOptions {\n /** Registry URL to publish to. */\n registryUrl: string;\n /** Working directory (project root). */\n cwd: string;\n /** Additional arguments forwarded to npm publish. */\n args?: string[];\n /** Bearer token for the registry. When set, passed via a registry-scoped\n * `_authToken` config flag rather than read from the user's `.npmrc`. */\n authToken?: string;\n}\n\nexport interface NpmPublishResult {\n /** stdout from npm publish. */\n stdout: string;\n}\n\n/**\n * Run `npm publish` against the given registry.\n * Uses spawn with args array to avoid shell injection.\n *\n * When `authToken` is provided, the token is passed via a registry-scoped\n * `--//host/:_authToken=<token>` flag (npm's standard form for per-registry\n * tokens) so we never have to write to `~/.npmrc`.\n */\nexport async function npmPublish(\n options: NpmPublishOptions,\n): Promise<NpmPublishResult> {\n const { registryUrl, cwd, args = [], authToken } = options;\n const tokenArg = authToken\n ? [`--${registryAuthKey(registryUrl)}=${authToken}`]\n : [];\n const npmArgs = [\"publish\", \"--registry\", registryUrl, ...tokenArg, ...args];\n const stdout = await spawnAsync(\"npm\", npmArgs, { cwd });\n return { stdout };\n}\n\n/**\n * Write `_authToken=<token>` for the given registry host into `~/.npmrc`,\n * preserving any other lines. Replaces the existing entry for the same key\n * if present. Returns the absolute path to the npmrc that was written.\n */\nexport async function writeRegistryAuthToken(\n registryUrl: string,\n token: string,\n): Promise<string> {\n const npmrcPath = join(homedir(), \".npmrc\");\n const key = registryAuthKey(registryUrl);\n let existing = \"\";\n try {\n existing = await fs.readFile(npmrcPath, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") throw err;\n }\n const lines = existing.split(\"\\n\");\n const filtered = lines.filter((line) => !line.startsWith(`${key}=`));\n // Also drop any trailing empties to avoid stacking blank lines on rewrite.\n while (filtered.length && filtered[filtered.length - 1] === \"\")\n filtered.pop();\n filtered.push(`${key}=${token}`);\n await fs.writeFile(npmrcPath, `${filtered.join(\"\\n\")}\\n`, \"utf8\");\n return npmrcPath;\n}\n\nexport interface NpmUnpublishOptions {\n /** Registry URL to unpublish from. */\n registryUrl: string;\n /** Working directory (project root). */\n cwd: string;\n /** Package spec: `<name>` (whole package) or `<name>@<version>` (single version). */\n spec: string;\n /** Additional arguments forwarded to npm unpublish. */\n args?: string[];\n /** Bearer token for the registry (same semantics as `NpmPublishOptions.authToken`). */\n authToken?: string;\n}\n\nexport interface NpmUnpublishResult {\n /** stdout from npm unpublish. */\n stdout: string;\n}\n\n/**\n * Run `npm unpublish` against the given registry.\n * Always passes `--force` because npm otherwise refuses to unpublish packages\n * older than 72h (a public-npmjs safeguard that doesn't apply to private registries).\n */\nexport async function npmUnpublish(\n options: NpmUnpublishOptions,\n): Promise<NpmUnpublishResult> {\n const { registryUrl, cwd, spec, args = [], authToken } = options;\n const tokenArg = authToken\n ? [`--${registryAuthKey(registryUrl)}=${authToken}`]\n : [];\n const npmArgs = [\n \"unpublish\",\n spec,\n \"--registry\",\n registryUrl,\n \"--force\",\n ...tokenArg,\n ...args,\n ];\n const stdout = await spawnAsync(\"npm\", npmArgs, { cwd });\n return { stdout };\n}\n"],"mappings":"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"}
|