@withstudiocms/internal_helpers 0.1.0-beta.2 → 0.1.0-beta.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/dist/astro-integration/integrationLogger.js +1 -1
- package/dist/cli-providers/core/formatter.d.ts +23 -0
- package/dist/cli-providers/core/formatter.js +47 -0
- package/dist/cli-providers/core/get-package-manger.d.ts +13 -0
- package/dist/cli-providers/core/get-package-manger.js +37 -0
- package/dist/cli-providers/core/process-node-version-provider.d.ts +7 -0
- package/dist/cli-providers/core/process-node-version-provider.js +6 -0
- package/dist/cli-providers/core/process-package-manager-user-agent-provider.d.ts +7 -0
- package/dist/cli-providers/core/process-package-manager-user-agent-provider.js +7 -0
- package/dist/cli-providers/core/system-info-provider.d.ts +9 -0
- package/dist/cli-providers/core/system-info-provider.js +24 -0
- package/dist/cli-providers/core/tinyexec.d.ts +9 -0
- package/dist/cli-providers/core/tinyexec.js +38 -0
- package/dist/cli-providers/definitions.d.ts +58 -0
- package/dist/cli-providers/definitions.js +0 -0
- package/dist/cli-providers/index.d.ts +6 -0
- package/dist/cli-providers/index.js +6 -0
- package/dist/cli-providers/infra/bun-package-manager.d.ts +8 -0
- package/dist/cli-providers/infra/bun-package-manager.js +9 -0
- package/dist/cli-providers/infra/noop-package-manager.d.ts +8 -0
- package/dist/cli-providers/infra/noop-package-manager.js +9 -0
- package/dist/cli-providers/infra/npm-package-manager.d.ts +12 -0
- package/dist/cli-providers/infra/npm-package-manager.js +36 -0
- package/dist/cli-providers/infra/pnpm-package-manager.d.ts +12 -0
- package/dist/cli-providers/infra/pnpm-package-manager.js +68 -0
- package/dist/cli-providers/infra/yarn-package-manager.d.ts +12 -0
- package/dist/cli-providers/infra/yarn-package-manager.js +36 -0
- package/dist/debug-info-provider.d.ts +50 -0
- package/dist/debug-info-provider.js +79 -0
- package/dist/headConfigSchema.d.ts +8 -8
- package/dist/pathResolver.d.ts +30 -0
- package/dist/pathResolver.js +31 -0
- package/package.json +24 -3
|
@@ -23,7 +23,7 @@ async function logMessages(messages, options, logger) {
|
|
|
23
23
|
{
|
|
24
24
|
logger: logger.fork(label),
|
|
25
25
|
logLevel,
|
|
26
|
-
verbose: logLevel === "info" ? options.verbose : true
|
|
26
|
+
verbose: logLevel === "info" || logLevel === "debug" ? options.verbose : true
|
|
27
27
|
},
|
|
28
28
|
message
|
|
29
29
|
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
2
|
+
import type { TextFormatter } from '../definitions';
|
|
3
|
+
type StyleTextFormatColor = Parameters<typeof styleText>[0];
|
|
4
|
+
/**
|
|
5
|
+
* Options for formatting and styling debug information.
|
|
6
|
+
*/
|
|
7
|
+
export type FormatOptions = {
|
|
8
|
+
keyStyle: StyleTextFormatColor;
|
|
9
|
+
valueStyle: StyleTextFormatColor;
|
|
10
|
+
};
|
|
11
|
+
export type DebugStylerOptions = {
|
|
12
|
+
indent?: number;
|
|
13
|
+
style?: FormatOptions;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* A utility class for formatting and styling debug information.
|
|
17
|
+
*/
|
|
18
|
+
export declare class Formatter implements TextFormatter {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(obj: Record<string, string>, opts?: DebugStylerOptions);
|
|
21
|
+
format(styled?: boolean): string;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { styleText } from "node:util";
|
|
2
|
+
class Formatter {
|
|
3
|
+
#indent;
|
|
4
|
+
#obj;
|
|
5
|
+
#style;
|
|
6
|
+
constructor(obj, opts) {
|
|
7
|
+
this.#indent = opts?.indent ?? 2;
|
|
8
|
+
this.#obj = obj;
|
|
9
|
+
this.#style = opts?.style ?? {
|
|
10
|
+
keyStyle: "cyan",
|
|
11
|
+
valueStyle: "white"
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
get #getKeyPair() {
|
|
15
|
+
return Object.entries(this.#obj).map(([key, value]) => ({ key, value }));
|
|
16
|
+
}
|
|
17
|
+
#textProcessor(text, type, styled) {
|
|
18
|
+
const style = type === "key" ? this.#style.keyStyle : this.#style.valueStyle;
|
|
19
|
+
return styled ? styleText(style, text) : text;
|
|
20
|
+
}
|
|
21
|
+
#getTextProcessor(styled) {
|
|
22
|
+
return (text, type) => this.#textProcessor(text, type, styled);
|
|
23
|
+
}
|
|
24
|
+
format(styled) {
|
|
25
|
+
const pairs = this.#getKeyPair;
|
|
26
|
+
if (pairs.length === 0) return "";
|
|
27
|
+
const maxKeyLength = Math.max(...pairs.map((p) => p.key.length));
|
|
28
|
+
const lines = [];
|
|
29
|
+
const processText = this.#getTextProcessor(styled);
|
|
30
|
+
for (const { key, value } of pairs) {
|
|
31
|
+
const padding = " ".repeat(maxKeyLength - key.length + this.#indent);
|
|
32
|
+
const valueLines = value.split("\n");
|
|
33
|
+
const styledKey = processText(key, "key");
|
|
34
|
+
const styledValue = processText(valueLines[0], "value");
|
|
35
|
+
lines.push(`${styledKey}${padding}${styledValue}`);
|
|
36
|
+
for (let i = 1; i < valueLines.length; i++) {
|
|
37
|
+
const indent = " ".repeat(maxKeyLength + this.#indent);
|
|
38
|
+
const styledLine = processText(valueLines[i], "value");
|
|
39
|
+
lines.push(`${indent}${styledLine}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return lines.join("\n");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
Formatter
|
|
47
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CommandExecutor, PackageManager, PackageManagerUserAgentProvider } from '../definitions.js';
|
|
2
|
+
interface Options {
|
|
3
|
+
packageManagerUserAgentProvider: PackageManagerUserAgentProvider;
|
|
4
|
+
commandExecutor: CommandExecutor;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Determines the package manager based on the user agent string.
|
|
8
|
+
*
|
|
9
|
+
* @param options - The options object containing the user agent provider.
|
|
10
|
+
* @returns A promise that resolves to the appropriate PackageManager instance.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getPackageManager({ packageManagerUserAgentProvider, commandExecutor, }: Options): Promise<PackageManager>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
async function getPackageManager({
|
|
2
|
+
packageManagerUserAgentProvider,
|
|
3
|
+
commandExecutor
|
|
4
|
+
}) {
|
|
5
|
+
if (!packageManagerUserAgentProvider.userAgent) {
|
|
6
|
+
const { NoopPackageManager } = await import("../infra/noop-package-manager.js");
|
|
7
|
+
return new NoopPackageManager();
|
|
8
|
+
}
|
|
9
|
+
const specifier = packageManagerUserAgentProvider.userAgent.split(" ")[0];
|
|
10
|
+
const _name = specifier.substring(0, specifier.lastIndexOf("/"));
|
|
11
|
+
const name = _name === "npminstall" ? "cnpm" : _name;
|
|
12
|
+
switch (name) {
|
|
13
|
+
case "pnpm": {
|
|
14
|
+
const { PnpmPackageManager } = await import("../infra/pnpm-package-manager.js");
|
|
15
|
+
return new PnpmPackageManager({ commandExecutor });
|
|
16
|
+
}
|
|
17
|
+
case "npm": {
|
|
18
|
+
const { NpmPackageManager } = await import("../infra/npm-package-manager.js");
|
|
19
|
+
return new NpmPackageManager({ commandExecutor });
|
|
20
|
+
}
|
|
21
|
+
case "yarn": {
|
|
22
|
+
const { YarnPackageManager } = await import("../infra/yarn-package-manager.js");
|
|
23
|
+
return new YarnPackageManager({ commandExecutor });
|
|
24
|
+
}
|
|
25
|
+
case "bun": {
|
|
26
|
+
const { BunPackageManager } = await import("../infra/bun-package-manager.js");
|
|
27
|
+
return new BunPackageManager();
|
|
28
|
+
}
|
|
29
|
+
default: {
|
|
30
|
+
const { NoopPackageManager } = await import("../infra/noop-package-manager.js");
|
|
31
|
+
return new NoopPackageManager();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
getPackageManager
|
|
37
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PackageManagerUserAgentProvider } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Provides the package manager user agent from the current process environment.
|
|
4
|
+
*/
|
|
5
|
+
export declare class ProcessPackageManagerUserAgentProvider implements PackageManagerUserAgentProvider {
|
|
6
|
+
readonly userAgent: string | null;
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SystemInfoProvider } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Provides system information based on the current process.
|
|
4
|
+
*/
|
|
5
|
+
export declare class ProcessSystemInfoProvider implements SystemInfoProvider {
|
|
6
|
+
#private;
|
|
7
|
+
readonly name: NodeJS.Platform;
|
|
8
|
+
readonly displayName: string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class ProcessSystemInfoProvider {
|
|
2
|
+
#platformToOs = {
|
|
3
|
+
win32: "Windows",
|
|
4
|
+
darwin: "macOS",
|
|
5
|
+
linux: "Linux",
|
|
6
|
+
aix: "AIX",
|
|
7
|
+
freebsd: "FreeBSD",
|
|
8
|
+
openbsd: "OpenBSD",
|
|
9
|
+
sunos: "SunOS"
|
|
10
|
+
};
|
|
11
|
+
#archToArchName = {
|
|
12
|
+
x64: "x64",
|
|
13
|
+
arm64: "ARM64",
|
|
14
|
+
ia32: "x86",
|
|
15
|
+
arm: "ARM",
|
|
16
|
+
mips: "MIPS",
|
|
17
|
+
ppc: "PowerPC"
|
|
18
|
+
};
|
|
19
|
+
name = process.platform;
|
|
20
|
+
displayName = `${this.#platformToOs[this.name] ?? this.name} (${this.#archToArchName[process.arch] ?? process.arch})`;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
ProcessSystemInfoProvider
|
|
24
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CommandExecutor, CommandExecutorOptions } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Provides a command executor that uses the Tinyexec library to run shell commands.
|
|
4
|
+
*/
|
|
5
|
+
export declare class TinyexecCommandExecutor implements CommandExecutor {
|
|
6
|
+
execute(command: string, args?: Array<string>, options?: CommandExecutorOptions): Promise<{
|
|
7
|
+
stdout: string;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NonZeroExitError, x } from "tinyexec";
|
|
2
|
+
class TinyExecError extends Error {
|
|
3
|
+
stderr;
|
|
4
|
+
stdout;
|
|
5
|
+
}
|
|
6
|
+
class TinyexecCommandExecutor {
|
|
7
|
+
async execute(command, args, options) {
|
|
8
|
+
const proc = x(command, args, {
|
|
9
|
+
throwOnError: true,
|
|
10
|
+
nodeOptions: {
|
|
11
|
+
cwd: options?.cwd,
|
|
12
|
+
env: options?.env,
|
|
13
|
+
shell: options?.shell,
|
|
14
|
+
stdio: options?.stdio
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
if (options?.input) {
|
|
18
|
+
proc.process?.stdin?.end(options.input);
|
|
19
|
+
}
|
|
20
|
+
return await proc.then(
|
|
21
|
+
(o) => o,
|
|
22
|
+
(e) => {
|
|
23
|
+
if (e instanceof NonZeroExitError) {
|
|
24
|
+
const fullCommand = args?.length ? `${command} ${args.map((a) => a.includes(" ") ? `"${a}"` : a).join(" ")}` : command;
|
|
25
|
+
const message = `The command \`${fullCommand}\` exited with code ${e.exitCode}`;
|
|
26
|
+
const newError = new TinyExecError(message, e.cause ? { cause: e.cause } : void 0);
|
|
27
|
+
newError.stderr = e.output?.stderr;
|
|
28
|
+
newError.stdout = e.output?.stdout;
|
|
29
|
+
throw newError;
|
|
30
|
+
}
|
|
31
|
+
throw e;
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
TinyexecCommandExecutor
|
|
38
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { StdioOptions } from 'node:child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Defines interfaces for package managers, Node.js version, and system information providers.
|
|
4
|
+
*/
|
|
5
|
+
export interface PackageManager {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
getPackageVersion: (name: string) => Promise<string | undefined>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Provides the user agent string of the package manager.
|
|
11
|
+
*/
|
|
12
|
+
export interface PackageManagerUserAgentProvider {
|
|
13
|
+
readonly userAgent: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Provides the Node.js version.
|
|
17
|
+
*/
|
|
18
|
+
export interface NodeVersionProvider {
|
|
19
|
+
readonly version: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Provides system information.
|
|
23
|
+
*/
|
|
24
|
+
export interface SystemInfoProvider {
|
|
25
|
+
readonly name: NodeJS.Platform;
|
|
26
|
+
readonly displayName: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Represents debug information about the environment.
|
|
30
|
+
*/
|
|
31
|
+
export interface CommandExecutorOptions {
|
|
32
|
+
cwd?: string;
|
|
33
|
+
env?: Record<string, string | undefined>;
|
|
34
|
+
shell?: boolean;
|
|
35
|
+
input?: string;
|
|
36
|
+
stdio?: StdioOptions;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Represents a command executor that can run shell commands.
|
|
40
|
+
*/
|
|
41
|
+
export interface CommandExecutor {
|
|
42
|
+
execute: (command: string, args?: Array<string>, options?: CommandExecutorOptions) => Promise<{
|
|
43
|
+
stdout: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Represents the structure of a bare NPM-like version output.
|
|
48
|
+
*/
|
|
49
|
+
export interface BareNpmLikeVersionOutput {
|
|
50
|
+
version: string;
|
|
51
|
+
dependencies: Record<string, BareNpmLikeVersionOutput>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Represents a text formatter for styling output.
|
|
55
|
+
*/
|
|
56
|
+
export interface TextFormatter {
|
|
57
|
+
format: (styled?: boolean) => string;
|
|
58
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './core/formatter.js';
|
|
2
|
+
export * from './core/get-package-manger.js';
|
|
3
|
+
export * from './core/process-node-version-provider.js';
|
|
4
|
+
export * from './core/process-package-manager-user-agent-provider.js';
|
|
5
|
+
export * from './core/system-info-provider.js';
|
|
6
|
+
export * from './core/tinyexec.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from "./core/formatter.js";
|
|
2
|
+
export * from "./core/get-package-manger.js";
|
|
3
|
+
export * from "./core/process-node-version-provider.js";
|
|
4
|
+
export * from "./core/process-package-manager-user-agent-provider.js";
|
|
5
|
+
export * from "./core/system-info-provider.js";
|
|
6
|
+
export * from "./core/tinyexec.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PackageManager } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the Bun package manager.
|
|
4
|
+
*/
|
|
5
|
+
export declare class BunPackageManager implements PackageManager {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
getPackageVersion(_name: string): Promise<string | undefined>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PackageManager } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a no-operation package manager for unknown cases.
|
|
4
|
+
*/
|
|
5
|
+
export declare class NoopPackageManager implements PackageManager {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
getPackageVersion(_name: string): Promise<string | undefined>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CommandExecutor, PackageManager } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the NPM package manager.
|
|
4
|
+
*/
|
|
5
|
+
export declare class NpmPackageManager implements PackageManager {
|
|
6
|
+
#private;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
constructor({ commandExecutor }: {
|
|
9
|
+
commandExecutor: CommandExecutor;
|
|
10
|
+
});
|
|
11
|
+
getPackageVersion(name: string): Promise<string | undefined>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
class NpmPackageManager {
|
|
2
|
+
name = "npm";
|
|
3
|
+
#commandExecutor;
|
|
4
|
+
constructor({ commandExecutor }) {
|
|
5
|
+
this.#commandExecutor = commandExecutor;
|
|
6
|
+
}
|
|
7
|
+
async getPackageVersion(name) {
|
|
8
|
+
try {
|
|
9
|
+
const { stdout } = await this.#commandExecutor.execute(
|
|
10
|
+
"npm",
|
|
11
|
+
["ls", name, "--json", "--depth=1"],
|
|
12
|
+
{
|
|
13
|
+
shell: true
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
const parsedNpmOutput = JSON.parse(stdout);
|
|
17
|
+
if (!parsedNpmOutput.dependencies) {
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
if (parsedNpmOutput.dependencies[name]) {
|
|
21
|
+
return `v${parsedNpmOutput.dependencies[name].version}`;
|
|
22
|
+
}
|
|
23
|
+
const studiocms = parsedNpmOutput.dependencies.studiocms;
|
|
24
|
+
if (studiocms?.dependencies?.[name]?.version) {
|
|
25
|
+
return `v${studiocms.dependencies[name].version}`;
|
|
26
|
+
}
|
|
27
|
+
const astro = parsedNpmOutput.dependencies.astro;
|
|
28
|
+
return astro?.dependencies?.[name]?.version ? `v${astro.dependencies[name].version}` : void 0;
|
|
29
|
+
} catch {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
NpmPackageManager
|
|
36
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CommandExecutor, PackageManager } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the PNPM package manager.
|
|
4
|
+
*/
|
|
5
|
+
export declare class PnpmPackageManager implements PackageManager {
|
|
6
|
+
#private;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
constructor({ commandExecutor }: {
|
|
9
|
+
commandExecutor: CommandExecutor;
|
|
10
|
+
});
|
|
11
|
+
getPackageVersion(name: string): Promise<string | undefined>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
function formatPnpmVersionOutput(versionOutput) {
|
|
2
|
+
return versionOutput.startsWith("link:") ? "Local" : `v${versionOutput}`;
|
|
3
|
+
}
|
|
4
|
+
class PnpmPackageManager {
|
|
5
|
+
name = "pnpm";
|
|
6
|
+
#commandExecutor;
|
|
7
|
+
constructor({ commandExecutor }) {
|
|
8
|
+
this.#commandExecutor = commandExecutor;
|
|
9
|
+
}
|
|
10
|
+
#processPnpmWhyOutput(name, pnpmWhy) {
|
|
11
|
+
const parsedOutput = JSON.parse(pnpmWhy);
|
|
12
|
+
if (parsedOutput.length === 0) {
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
15
|
+
const deps = parsedOutput[0].dependencies;
|
|
16
|
+
if (!deps) {
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
const userProvidedDependency = deps[name];
|
|
20
|
+
if (userProvidedDependency) {
|
|
21
|
+
return formatPnpmVersionOutput(userProvidedDependency.version);
|
|
22
|
+
}
|
|
23
|
+
const studiocmsDependency = deps.studiocms?.dependencies?.[name];
|
|
24
|
+
if (studiocmsDependency) {
|
|
25
|
+
return formatPnpmVersionOutput(studiocmsDependency.version);
|
|
26
|
+
}
|
|
27
|
+
const astroDependency = deps.astro?.dependencies?.[name];
|
|
28
|
+
return astroDependency ? formatPnpmVersionOutput(astroDependency.version) : void 0;
|
|
29
|
+
}
|
|
30
|
+
#processPnpmLsOutput(name, pnpmLs) {
|
|
31
|
+
const parsedOutput = JSON.parse(pnpmLs);
|
|
32
|
+
if (parsedOutput.length === 0) {
|
|
33
|
+
return void 0;
|
|
34
|
+
}
|
|
35
|
+
const deps = parsedOutput[0].dependencies;
|
|
36
|
+
if (!deps) {
|
|
37
|
+
return void 0;
|
|
38
|
+
}
|
|
39
|
+
const userProvidedDependency = deps[name];
|
|
40
|
+
if (userProvidedDependency) {
|
|
41
|
+
return formatPnpmVersionOutput(userProvidedDependency.version);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async getPackageVersion(name) {
|
|
45
|
+
try {
|
|
46
|
+
const { stdout: pnpmLs } = await this.#commandExecutor.execute("pnpm", ["ls", "--json"], {
|
|
47
|
+
shell: true
|
|
48
|
+
});
|
|
49
|
+
const lsVersion = this.#processPnpmLsOutput(name, pnpmLs);
|
|
50
|
+
if (lsVersion) {
|
|
51
|
+
return lsVersion;
|
|
52
|
+
}
|
|
53
|
+
const { stdout: pnpmWhy } = await this.#commandExecutor.execute(
|
|
54
|
+
"pnpm",
|
|
55
|
+
["why", name, "--json"],
|
|
56
|
+
{
|
|
57
|
+
shell: true
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
return this.#processPnpmWhyOutput(name, pnpmWhy);
|
|
61
|
+
} catch {
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
PnpmPackageManager
|
|
68
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CommandExecutor, PackageManager } from '../definitions.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the Yarn package manager.
|
|
4
|
+
*/
|
|
5
|
+
export declare class YarnPackageManager implements PackageManager {
|
|
6
|
+
#private;
|
|
7
|
+
readonly name: string;
|
|
8
|
+
constructor({ commandExecutor }: {
|
|
9
|
+
commandExecutor: CommandExecutor;
|
|
10
|
+
});
|
|
11
|
+
getPackageVersion(name: string): Promise<string | undefined>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function getYarnOutputDepVersion(dependency, outputLine) {
|
|
2
|
+
const parsed = JSON.parse(outputLine);
|
|
3
|
+
for (const [key, value] of Object.entries(parsed.children)) {
|
|
4
|
+
if (key.startsWith(`${dependency}@`)) {
|
|
5
|
+
return `v${value.locator.split(":").pop()}`;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
class YarnPackageManager {
|
|
10
|
+
name = "yarn";
|
|
11
|
+
#commandExecutor;
|
|
12
|
+
constructor({ commandExecutor }) {
|
|
13
|
+
this.#commandExecutor = commandExecutor;
|
|
14
|
+
}
|
|
15
|
+
async getPackageVersion(name) {
|
|
16
|
+
try {
|
|
17
|
+
const { stdout } = await this.#commandExecutor.execute("yarn", ["why", name, "--json"], {
|
|
18
|
+
shell: true
|
|
19
|
+
});
|
|
20
|
+
const hasUserDefinition = stdout.includes("workspace:.");
|
|
21
|
+
for (const line of stdout.split("\n")) {
|
|
22
|
+
if (hasUserDefinition && line.includes("workspace:."))
|
|
23
|
+
return getYarnOutputDepVersion(name, line);
|
|
24
|
+
if (hasUserDefinition && line.includes("studiocms@"))
|
|
25
|
+
return getYarnOutputDepVersion(name, line);
|
|
26
|
+
if (!hasUserDefinition && line.includes("astro@"))
|
|
27
|
+
return getYarnOutputDepVersion(name, line);
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
YarnPackageManager
|
|
36
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { FormatOptions } from './cli-providers/core/formatter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents debug information about the Astro and StudioCMS environment.
|
|
4
|
+
*/
|
|
5
|
+
export type DebugInfo = {
|
|
6
|
+
Astro: string;
|
|
7
|
+
'Astro Adapter': string;
|
|
8
|
+
'Database Dialect': string;
|
|
9
|
+
'Node.js': string;
|
|
10
|
+
'Package Manager': string;
|
|
11
|
+
System: string;
|
|
12
|
+
StudioCMS: string;
|
|
13
|
+
'StudioCMS UI': string;
|
|
14
|
+
'StudioCMS Plugins': string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Represents a list of installed plugins.
|
|
18
|
+
*/
|
|
19
|
+
type PluginList = {
|
|
20
|
+
identifier: string;
|
|
21
|
+
name: string;
|
|
22
|
+
}[];
|
|
23
|
+
/**
|
|
24
|
+
* Represents the context required to gather debug information.
|
|
25
|
+
*/
|
|
26
|
+
export interface DebugInfoContext {
|
|
27
|
+
adapterName: string;
|
|
28
|
+
databaseDialect: string;
|
|
29
|
+
installedPlugins: PluginList;
|
|
30
|
+
}
|
|
31
|
+
export declare class DebugInfoProvider {
|
|
32
|
+
#private;
|
|
33
|
+
constructor(ctx: DebugInfoContext);
|
|
34
|
+
/**
|
|
35
|
+
* Gathers debug information as an object.
|
|
36
|
+
*
|
|
37
|
+
* @returns A promise that resolves to the debug information object.
|
|
38
|
+
*/
|
|
39
|
+
getDebugInfoObj(): Promise<DebugInfo>;
|
|
40
|
+
/**
|
|
41
|
+
* Gathers debug information as a formatted string.
|
|
42
|
+
*
|
|
43
|
+
* @returns A promise that resolves to the debug information string.
|
|
44
|
+
*/
|
|
45
|
+
getDebugInfoString(indent?: number, { styled, styles: style }?: {
|
|
46
|
+
styled: boolean;
|
|
47
|
+
styles?: FormatOptions;
|
|
48
|
+
}): Promise<string>;
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const dbDialectLabels = {
|
|
2
|
+
libsql: "LibSQL",
|
|
3
|
+
mysql: "MySQL",
|
|
4
|
+
postgres: "PostgreSQL",
|
|
5
|
+
sqlite: "SQLite"
|
|
6
|
+
};
|
|
7
|
+
class DebugInfoProvider {
|
|
8
|
+
#ctx;
|
|
9
|
+
constructor(ctx) {
|
|
10
|
+
this.#ctx = ctx;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Gathers debug information as an object.
|
|
14
|
+
*
|
|
15
|
+
* @returns A promise that resolves to the debug information object.
|
|
16
|
+
*/
|
|
17
|
+
async getDebugInfoObj() {
|
|
18
|
+
const { adapterName, databaseDialect, installedPlugins } = this.#ctx;
|
|
19
|
+
const {
|
|
20
|
+
getPackageManager,
|
|
21
|
+
ProcessNodeVersionProvider,
|
|
22
|
+
ProcessPackageManagerUserAgentProvider,
|
|
23
|
+
ProcessSystemInfoProvider,
|
|
24
|
+
TinyexecCommandExecutor
|
|
25
|
+
} = await import("./cli-providers/index.js");
|
|
26
|
+
const nodeVersionProvider = new ProcessNodeVersionProvider();
|
|
27
|
+
const packageManagerUserAgentProvider = new ProcessPackageManagerUserAgentProvider();
|
|
28
|
+
const systemInfoProvider = new ProcessSystemInfoProvider();
|
|
29
|
+
const commandExecutor = new TinyexecCommandExecutor();
|
|
30
|
+
const packageManagerProvider = await getPackageManager({
|
|
31
|
+
packageManagerUserAgentProvider,
|
|
32
|
+
commandExecutor
|
|
33
|
+
});
|
|
34
|
+
async function getVersionWithIdentifier(identifier) {
|
|
35
|
+
const version = await packageManagerProvider.getPackageVersion(identifier);
|
|
36
|
+
if (!version) {
|
|
37
|
+
return identifier;
|
|
38
|
+
}
|
|
39
|
+
return `${identifier} (${version})`;
|
|
40
|
+
}
|
|
41
|
+
const fallbackValue = "Unavailable";
|
|
42
|
+
const AstroVersion = await packageManagerProvider.getPackageVersion("astro") || fallbackValue;
|
|
43
|
+
const AstroAdapter = await getVersionWithIdentifier(adapterName);
|
|
44
|
+
const DatabaseDialect = dbDialectLabels[databaseDialect] ?? databaseDialect;
|
|
45
|
+
const StudioCMSVersion = await packageManagerProvider.getPackageVersion("studiocms") || fallbackValue;
|
|
46
|
+
const StudioCMSUiVersion = await packageManagerProvider.getPackageVersion("@studiocms/ui") || fallbackValue;
|
|
47
|
+
return {
|
|
48
|
+
Astro: AstroVersion,
|
|
49
|
+
"Astro Adapter": AstroAdapter,
|
|
50
|
+
"Database Dialect": DatabaseDialect,
|
|
51
|
+
"Node.js": nodeVersionProvider.version,
|
|
52
|
+
"Package Manager": packageManagerProvider.name,
|
|
53
|
+
System: systemInfoProvider.displayName,
|
|
54
|
+
StudioCMS: StudioCMSVersion,
|
|
55
|
+
"StudioCMS UI": StudioCMSUiVersion,
|
|
56
|
+
"StudioCMS Plugins": await Promise.all(
|
|
57
|
+
installedPlugins.map(
|
|
58
|
+
async ({ identifier, name }) => `${name} - ${await getVersionWithIdentifier(identifier)}`
|
|
59
|
+
)
|
|
60
|
+
).then((versions) => versions.join("\n"))
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gathers debug information as a formatted string.
|
|
65
|
+
*
|
|
66
|
+
* @returns A promise that resolves to the debug information string.
|
|
67
|
+
*/
|
|
68
|
+
async getDebugInfoString(indent, { styled, styles: style } = {
|
|
69
|
+
styled: false
|
|
70
|
+
}) {
|
|
71
|
+
const { Formatter } = await import("./cli-providers/core/formatter.js");
|
|
72
|
+
const debugInfo = await this.getDebugInfoObj();
|
|
73
|
+
const styler = new Formatter(debugInfo, { indent, style });
|
|
74
|
+
return styler.format(styled);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
DebugInfoProvider
|
|
79
|
+
};
|
|
@@ -7,11 +7,11 @@ export declare const HeadConfigSchema: () => z.ZodDefault<z.ZodArray<z.ZodObject
|
|
|
7
7
|
/** Content to place inside the tag (optional). */
|
|
8
8
|
content: z.ZodDefault<z.ZodString>;
|
|
9
9
|
}, "strip", z.ZodTypeAny, {
|
|
10
|
-
tag: "
|
|
10
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
11
11
|
attrs: Record<string, string | boolean | undefined>;
|
|
12
12
|
content: string;
|
|
13
13
|
}, {
|
|
14
|
-
tag: "
|
|
14
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
15
15
|
attrs?: Record<string, string | boolean | undefined> | undefined;
|
|
16
16
|
content?: string | undefined;
|
|
17
17
|
}>, "many">>;
|
|
@@ -25,17 +25,17 @@ export declare const HeadSchema: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
|
25
25
|
/** Content to place inside the tag (optional). */
|
|
26
26
|
content: z.ZodDefault<z.ZodString>;
|
|
27
27
|
}, "strip", z.ZodTypeAny, {
|
|
28
|
-
tag: "
|
|
28
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
29
29
|
attrs: Record<string, string | boolean | undefined>;
|
|
30
30
|
content: string;
|
|
31
31
|
}, {
|
|
32
|
-
tag: "
|
|
32
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
33
33
|
attrs?: Record<string, string | boolean | undefined> | undefined;
|
|
34
34
|
content?: string | undefined;
|
|
35
35
|
}>, "many">>;
|
|
36
36
|
/** Create a fully parsed, merged, and sorted head entry array from multiple sources. */
|
|
37
37
|
export declare function createHead(defaults: HeadUserConfig, ...heads: HeadConfig[]): {
|
|
38
|
-
tag: "
|
|
38
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
39
39
|
attrs: Record<string, string | boolean | undefined>;
|
|
40
40
|
content: string;
|
|
41
41
|
}[];
|
|
@@ -57,15 +57,15 @@ export declare function hasOneOf(head: HeadConfig, entry: HeadConfig[number], ke
|
|
|
57
57
|
export declare function getAttr(keys: string[], entry: HeadConfig[number]): [key: string, value: string | boolean] | undefined;
|
|
58
58
|
/** Merge two heads, overwriting entries in the first head that exist in the second. */
|
|
59
59
|
export declare function mergeHead(oldHead: HeadConfig, newHead: HeadConfig): {
|
|
60
|
-
tag: "
|
|
60
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
61
61
|
attrs: Record<string, string | boolean | undefined>;
|
|
62
62
|
content: string;
|
|
63
63
|
}[];
|
|
64
64
|
/** Sort head tags to place important tags first and relegate “SEO” meta tags. */
|
|
65
65
|
export declare function sortHead(head: HeadConfig): {
|
|
66
|
-
tag: "
|
|
66
|
+
tag: "style" | "title" | "base" | "link" | "meta" | "script" | "noscript" | "template";
|
|
67
67
|
attrs: Record<string, string | boolean | undefined>;
|
|
68
68
|
content: string;
|
|
69
69
|
}[];
|
|
70
70
|
/** Get the relative importance of a specific head tag. */
|
|
71
|
-
export declare function getImportance(entry: HeadConfig[number]): 100 | 90 | 70 | 80
|
|
71
|
+
export declare function getImportance(entry: HeadConfig[number]): 0 | 100 | 90 | 70 | 80;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
interface PathResolver {
|
|
2
|
+
resolve: (...segments: string[]) => string;
|
|
3
|
+
resolveURL: (...segments: string[]) => URL;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Create a path resolver anchored to the provided base.
|
|
7
|
+
*
|
|
8
|
+
* The function accepts either a file URL (for example `import.meta.url`, i.e. a string
|
|
9
|
+
* that starts with `file://`) or a regular filesystem path (absolute or relative,
|
|
10
|
+
* e.g. `process.cwd()` or a custom string). If a file URL is provided it will be
|
|
11
|
+
* converted to the directory containing that file; otherwise the provided string is
|
|
12
|
+
* used directly as the base directory.
|
|
13
|
+
*
|
|
14
|
+
* @param baseOption - Base location used to resolve relative paths. Either:
|
|
15
|
+
* - a file URL string (starts with "file://", e.g. `import.meta.url`), or
|
|
16
|
+
* - a filesystem path string (absolute or relative).
|
|
17
|
+
* @returns An object with two helpers:
|
|
18
|
+
* - `resolve(...segments: string[]): string` — resolves the given path segments
|
|
19
|
+
* against the computed base directory and returns an absolute filesystem path.
|
|
20
|
+
* - `resolveURL(...segments: string[]): URL` — resolves the given path segments
|
|
21
|
+
* against the computed base directory and returns a `file://` URL.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Using import.meta.url as the base:
|
|
25
|
+
* const resolver = createPathResolver(import.meta.url);
|
|
26
|
+
* const absolutePath = resolver.resolve('..', 'assets', 'image.png');
|
|
27
|
+
* const fileUrl = resolver.resolveURL('..', 'assets', 'image.png');
|
|
28
|
+
*/
|
|
29
|
+
declare function createPathResolver(baseOption: string): PathResolver;
|
|
30
|
+
export default createPathResolver;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
|
+
function createPathResolver(baseOption) {
|
|
4
|
+
let baseDir;
|
|
5
|
+
if (baseOption.startsWith("file://")) {
|
|
6
|
+
const filePath = fileURLToPath(baseOption);
|
|
7
|
+
baseDir = path.dirname(filePath);
|
|
8
|
+
} else {
|
|
9
|
+
baseDir = path.resolve(baseOption);
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
/**
|
|
13
|
+
* Resolve path segments against the base directory.
|
|
14
|
+
*
|
|
15
|
+
* @param segments - Path segments to resolve.
|
|
16
|
+
* @returns The resolved absolute filesystem path.
|
|
17
|
+
*/
|
|
18
|
+
resolve: (...segments) => path.resolve(baseDir, ...segments),
|
|
19
|
+
/**
|
|
20
|
+
* Resolve path segments against the base directory and return a file URL.
|
|
21
|
+
*
|
|
22
|
+
* @param segments - Path segments to resolve.
|
|
23
|
+
* @returns The resolved file URL.
|
|
24
|
+
*/
|
|
25
|
+
resolveURL: (...segments) => pathToFileURL(path.resolve(baseDir, ...segments))
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
var pathResolver_default = createPathResolver;
|
|
29
|
+
export {
|
|
30
|
+
pathResolver_default as default
|
|
31
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withstudiocms/internal_helpers",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.4",
|
|
4
4
|
"description": "Internal helper utilities for StudioCMS",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "withstudiocms",
|
|
@@ -56,14 +56,35 @@
|
|
|
56
56
|
"./headConfigSchema": {
|
|
57
57
|
"types": "./dist/headConfigSchema.d.ts",
|
|
58
58
|
"default": "./dist/headConfigSchema.js"
|
|
59
|
+
},
|
|
60
|
+
"./pathResolver": {
|
|
61
|
+
"types": "./dist/pathResolver.d.ts",
|
|
62
|
+
"default": "./dist/pathResolver.js"
|
|
63
|
+
},
|
|
64
|
+
"./debug-info-provider": {
|
|
65
|
+
"types": "./dist/debug-info-provider.d.ts",
|
|
66
|
+
"default": "./dist/debug-info-provider.js"
|
|
67
|
+
},
|
|
68
|
+
"./cli-providers": {
|
|
69
|
+
"types": "./dist/cli-providers/index.d.ts",
|
|
70
|
+
"default": "./dist/cli-providers/index.js"
|
|
71
|
+
},
|
|
72
|
+
"./cli-providers/definitions": {
|
|
73
|
+
"types": "./dist/cli-providers/definitions.d.ts",
|
|
74
|
+
"default": "./dist/cli-providers/definitions.js"
|
|
75
|
+
},
|
|
76
|
+
"./cli-providers/core/*": {
|
|
77
|
+
"types": "./dist/cli-providers/core/*.d.ts",
|
|
78
|
+
"default": "./dist/cli-providers/core/*.js"
|
|
59
79
|
}
|
|
60
80
|
},
|
|
61
81
|
"type": "module",
|
|
62
82
|
"dependencies": {
|
|
63
|
-
"astro-integration-kit": "^0.19.
|
|
83
|
+
"astro-integration-kit": "^0.19.1",
|
|
64
84
|
"mdast-util-from-markdown": "^2.0.2",
|
|
65
85
|
"mdast-util-to-string": "^4.0.0",
|
|
66
|
-
"unist-util-visit": "^5.0.0"
|
|
86
|
+
"unist-util-visit": "^5.0.0",
|
|
87
|
+
"tinyexec": "^1.0.2"
|
|
67
88
|
},
|
|
68
89
|
"devDependencies": {
|
|
69
90
|
"@types/mdast": "^4.0.4",
|