skyltmax_config 1.0.0 → 2.0.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.
@@ -1,132 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { existsSync, realpathSync } from "node:fs"
4
- import { readFile } from "node:fs/promises"
5
- import { createRequire } from "node:module"
6
- import { dirname, resolve } from "node:path"
7
- import { fileURLToPath } from "node:url"
8
-
9
- const __filename = fileURLToPath(import.meta.url)
10
- const __dirname = dirname(__filename)
11
- const defaultManifestPath = resolve(__dirname, "..", "..", "package.json")
12
- const defaultConsumerRoot = process.env.INIT_CWD ?? process.env.npm_config_local_prefix ?? process.cwd()
13
-
14
- async function readManifest(path) {
15
- const raw = await readFile(path, "utf8")
16
- return JSON.parse(raw)
17
- }
18
-
19
- function createConsumerRequire(root) {
20
- const candidate = resolve(root, "package.json")
21
- if (existsSync(candidate)) {
22
- return createRequire(candidate)
23
- }
24
-
25
- return createRequire(import.meta.url)
26
- }
27
-
28
- export async function auditPeerDependencies({
29
- manifestPath = defaultManifestPath,
30
- consumerRoot = defaultConsumerRoot,
31
- } = {}) {
32
- const manifest = await readManifest(manifestPath)
33
- const peers = Object.entries(manifest.peerDependencies ?? {})
34
-
35
- if (!peers.length) {
36
- return {
37
- peers,
38
- missing: [],
39
- mismatched: [],
40
- }
41
- }
42
-
43
- const requireFromConsumer = createConsumerRequire(consumerRoot)
44
- const missing = []
45
- const mismatched = []
46
-
47
- for (const [name, expectedVersion] of peers) {
48
- let resolvedPackageJson
49
- try {
50
- resolvedPackageJson = requireFromConsumer.resolve(`${name}/package.json`)
51
- } catch (error) {
52
- missing.push({ name, expectedVersion, reason: error.message })
53
- continue
54
- }
55
-
56
- try {
57
- const pkg = JSON.parse(await readFile(resolvedPackageJson, "utf8"))
58
- const actualVersion = pkg.version
59
- if (actualVersion !== expectedVersion) {
60
- mismatched.push({ name, expectedVersion, actualVersion })
61
- }
62
- } catch (error) {
63
- mismatched.push({ name, expectedVersion, actualVersion: "unknown", reason: error.message })
64
- }
65
- }
66
-
67
- return {
68
- peers,
69
- missing,
70
- mismatched,
71
- }
72
- }
73
-
74
- export function formatAuditMessage({ missing, mismatched }) {
75
- if (!missing.length && !mismatched.length) {
76
- return null
77
- }
78
-
79
- const lines = ["[skyltmax-config] Peer dependency check detected issues:"]
80
-
81
- if (missing.length) {
82
- lines.push(" Missing peers:")
83
- for (const item of missing) {
84
- lines.push(` - ${item.name}@${item.expectedVersion}`)
85
- }
86
- }
87
-
88
- if (mismatched.length) {
89
- lines.push(" Version mismatches:")
90
- for (const item of mismatched) {
91
- const details = item.actualVersion ? ` (found ${item.actualVersion})` : ""
92
- lines.push(` - ${item.name}@${item.expectedVersion}${details}`)
93
- }
94
- }
95
-
96
- lines.push(' Run "npx skyltmax-config-peers" to install the correct versions.')
97
-
98
- return lines.join("\n")
99
- }
100
-
101
- export async function runPostinstallAudit() {
102
- try {
103
- const result = await auditPeerDependencies()
104
- const message = formatAuditMessage(result)
105
-
106
- if (message) {
107
- console.warn(message)
108
- }
109
- } catch (error) {
110
- console.warn(`[skyltmax-config] Peer dependency check skipped: ${error.message}`)
111
- }
112
- }
113
-
114
- const isDirectExecution = (() => {
115
- const [argvPath] = process.argv.slice(1, 2)
116
-
117
- if (!argvPath) return false
118
-
119
- try {
120
- return realpathSync(argvPath) === realpathSync(__filename)
121
- } catch (error) {
122
- if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
123
- return false
124
- }
125
-
126
- throw error
127
- }
128
- })()
129
-
130
- if (isDirectExecution) {
131
- runPostinstallAudit()
132
- }
@@ -1,206 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawn } from "node:child_process"
3
- import { existsSync, realpathSync } from "node:fs"
4
- import { readFile } from "node:fs/promises"
5
- import { dirname, resolve } from "node:path"
6
- import { fileURLToPath } from "node:url"
7
-
8
- const HELP = `Usage: skyltmax-config-peers [options]
9
-
10
- Options:
11
- --manager <name> npm | pnpm | bun (auto-detected by default)
12
- --dry-run Print the install command without running it
13
- --help Show this help message
14
- `
15
-
16
- const __filename = fileURLToPath(import.meta.url)
17
- const __dirname = dirname(__filename)
18
- const defaultManifestPath = resolve(__dirname, "..", "..", "package.json")
19
-
20
- export async function loadPeerDependencies(manifestPath = defaultManifestPath) {
21
- const manifest = JSON.parse(await readFile(manifestPath, "utf8"))
22
- const peers = manifest.peerDependencies ?? {}
23
- return Object.entries(peers).map(([name, version]) => `${name}@${version}`)
24
- }
25
-
26
- export function detectManager({ managerArg, userAgent = "", cwd = process.cwd() } = {}) {
27
- if (managerArg) return managerArg
28
-
29
- if (userAgent.startsWith("pnpm/")) return "pnpm"
30
- if (userAgent.startsWith("bun/")) return "bun"
31
- if (userAgent.startsWith("npm/")) return "npm"
32
-
33
- if (existsSync(resolve(cwd, "pnpm-lock.yaml"))) return "pnpm"
34
- if (existsSync(resolve(cwd, "bun.lockb"))) return "bun"
35
- if (existsSync(resolve(cwd, "package-lock.json"))) return "npm"
36
-
37
- return "npm"
38
- }
39
-
40
- export function findPnpmWorkspaceRoot(startDir) {
41
- let current = resolve(startDir)
42
-
43
- while (true) {
44
- if (existsSync(resolve(current, "pnpm-workspace.yaml")) || existsSync(resolve(current, "pnpm-workspace.yml"))) {
45
- return current
46
- }
47
-
48
- const parent = dirname(current)
49
-
50
- if (parent === current) {
51
- return undefined
52
- }
53
-
54
- current = parent
55
- }
56
- }
57
-
58
- export function buildInstallCommand(manager, packages, { cwd = process.cwd() } = {}) {
59
- if (!packages.length) {
60
- throw new Error("No peer dependencies to install.")
61
- }
62
-
63
- if (manager === "pnpm") {
64
- const workspaceRoot = findPnpmWorkspaceRoot(cwd)
65
- const args = ["add", "-D", "--save-exact", ...packages]
66
-
67
- if (workspaceRoot) {
68
- args.splice(2, 0, "-w")
69
- }
70
-
71
- return {
72
- command: "pnpm",
73
- args,
74
- cwd: workspaceRoot ?? cwd,
75
- }
76
- }
77
-
78
- if (manager === "npm") {
79
- return {
80
- command: "npm",
81
- args: ["install", "--save-dev", "--save-exact", ...packages],
82
- cwd,
83
- }
84
- }
85
-
86
- if (manager === "bun") {
87
- return {
88
- command: "bun",
89
- args: ["add", "--dev", "--exact", ...packages],
90
- cwd,
91
- }
92
- }
93
-
94
- const supported = "npm, pnpm, bun"
95
- throw new Error(`Unsupported package manager: ${manager}. Supported managers: ${supported}`)
96
- }
97
-
98
- export function formatCommand({ command, args }) {
99
- return `${command} ${args.join(" ")}`
100
- }
101
-
102
- export async function prepareInstall({
103
- managerArg,
104
- cwd = process.cwd(),
105
- env = process.env,
106
- manifestPath = defaultManifestPath,
107
- } = {}) {
108
- const packages = await loadPeerDependencies(manifestPath)
109
-
110
- if (packages.length === 0) {
111
- return { packages: [] }
112
- }
113
-
114
- const manager = detectManager({ managerArg, userAgent: env.npm_config_user_agent ?? "", cwd })
115
- const command = buildInstallCommand(manager, packages, { cwd })
116
-
117
- return {
118
- manager,
119
- packages,
120
- command: command.command,
121
- args: command.args,
122
- cwd: command.cwd ?? cwd,
123
- printable: formatCommand(command),
124
- }
125
- }
126
-
127
- export async function runCli({ args = process.argv.slice(2), env = process.env, cwd = process.cwd() } = {}) {
128
- if (args.includes("--help")) {
129
- process.stdout.write(HELP)
130
- return 0
131
- }
132
-
133
- const argValue = flag => {
134
- const index = args.indexOf(flag)
135
- if (index === -1) return undefined
136
- return args[index + 1]
137
- }
138
-
139
- const managerArg = argValue("--manager")
140
- const dryRun = args.includes("--dry-run")
141
-
142
- try {
143
- const result = await prepareInstall({ managerArg, cwd, env })
144
-
145
- if (!result.packages || result.packages.length === 0) {
146
- process.stdout.write("No peer dependencies found on @skyltmax/config.\n")
147
- return 0
148
- }
149
-
150
- if (dryRun) {
151
- process.stdout.write(`${result.printable}\n`)
152
- return 0
153
- }
154
-
155
- process.stdout.write(`Running: ${result.printable}\n`)
156
-
157
- const child = spawn(result.command, result.args, {
158
- stdio: "inherit",
159
- cwd: result.cwd,
160
- })
161
-
162
- return await new Promise((resolve, reject) => {
163
- child.on("close", code => {
164
- if (code === 0) {
165
- resolve(0)
166
- } else {
167
- reject(new Error(`${result.command} exited with code ${code}`))
168
- }
169
- })
170
-
171
- child.on("error", error => {
172
- reject(error)
173
- })
174
- })
175
- } catch (error) {
176
- process.stderr.write(`${error.message}\n`)
177
- return 1
178
- }
179
- }
180
-
181
- const isDirectExecution = (() => {
182
- const [argvPath] = process.argv.slice(1, 2)
183
-
184
- if (!argvPath) return false
185
-
186
- try {
187
- return realpathSync(argvPath) === realpathSync(__filename)
188
- } catch (error) {
189
- if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
190
- return false
191
- }
192
-
193
- throw error
194
- }
195
- })()
196
-
197
- if (isDirectExecution) {
198
- runCli()
199
- .then(code => {
200
- process.exit(code)
201
- })
202
- .catch(error => {
203
- process.stderr.write(`${error.message}\n`)
204
- process.exit(1)
205
- })
206
- }
@@ -1,76 +0,0 @@
1
- import { mkdtemp, writeFile, mkdir } from "node:fs/promises"
2
- import { tmpdir } from "node:os"
3
- import { join } from "node:path"
4
- import { fileURLToPath } from "node:url"
5
- import { describe, expect, test } from "vitest"
6
-
7
- import { auditPeerDependencies, formatAuditMessage } from "../scripts/peer-deps/audit.js"
8
-
9
- const fixturePath = relative => fileURLToPath(new URL(`./fixtures/${relative}`, import.meta.url))
10
-
11
- async function createPackage(root, name, version) {
12
- const parts = name.split("/")
13
- const packageDir = join(root, "node_modules", ...parts)
14
- await mkdir(packageDir, { recursive: true })
15
- await writeFile(join(packageDir, "package.json"), JSON.stringify({ name, version }), "utf8")
16
- }
17
-
18
- async function createProjectRoot() {
19
- const root = await mkdtemp(join(tmpdir(), "skyltmax-check-peers-"))
20
- await writeFile(join(root, "package.json"), JSON.stringify({ name: "example", version: "1.0.0" }), "utf8")
21
- return root
22
- }
23
-
24
- describe("check-peers audit", () => {
25
- test("returns empty when all peers match", async () => {
26
- const root = await createProjectRoot()
27
- await createPackage(root, "eslint", "9.39.1")
28
- await createPackage(root, "prettier", "3.6.2")
29
-
30
- const result = await auditPeerDependencies({
31
- manifestPath: fixturePath("manifest-with-peers.json"),
32
- consumerRoot: root,
33
- })
34
-
35
- expect(result.missing).toEqual([])
36
- expect(result.mismatched).toEqual([])
37
- expect(formatAuditMessage(result)).toBeNull()
38
- })
39
-
40
- test("detects missing peers", async () => {
41
- const root = await createProjectRoot()
42
- await createPackage(root, "eslint", "9.39.1")
43
-
44
- const result = await auditPeerDependencies({
45
- manifestPath: fixturePath("manifest-with-peers.json"),
46
- consumerRoot: root,
47
- })
48
-
49
- expect(result.missing.map(item => item.name)).toEqual(["prettier"])
50
- const message = formatAuditMessage(result)
51
- expect(message).toContain("Missing peers")
52
- expect(message).toContain("prettier@3.6.2")
53
- })
54
-
55
- test("detects version mismatches", async () => {
56
- const root = await createProjectRoot()
57
- await createPackage(root, "eslint", "9.0.0")
58
- await createPackage(root, "prettier", "3.6.2")
59
-
60
- const result = await auditPeerDependencies({
61
- manifestPath: fixturePath("manifest-with-peers.json"),
62
- consumerRoot: root,
63
- })
64
-
65
- expect(result.mismatched).toEqual([
66
- {
67
- name: "eslint",
68
- expectedVersion: "9.39.1",
69
- actualVersion: "9.0.0",
70
- },
71
- ])
72
- const message = formatAuditMessage(result)
73
- expect(message).toContain("Version mismatches")
74
- expect(message).toContain("eslint@9.39.1 (found 9.0.0)")
75
- })
76
- })
@@ -1,3 +0,0 @@
1
- {
2
- "name": "example"
3
- }
@@ -1,6 +0,0 @@
1
- {
2
- "peerDependencies": {
3
- "eslint": "9.39.1",
4
- "prettier": "3.6.2"
5
- }
6
- }
@@ -1,115 +0,0 @@
1
- import { mkdir, mkdtemp, writeFile } from "node:fs/promises"
2
- import { tmpdir } from "node:os"
3
- import { join } from "node:path"
4
- import { fileURLToPath } from "node:url"
5
- import { describe, expect, test } from "vitest"
6
-
7
- import {
8
- buildInstallCommand,
9
- detectManager,
10
- formatCommand,
11
- loadPeerDependencies,
12
- prepareInstall,
13
- } from "../scripts/peer-deps/install.js"
14
-
15
- const fixturePath = relative => fileURLToPath(new URL(`./fixtures/${relative}`, import.meta.url))
16
-
17
- describe("install-peers helper", () => {
18
- test("loadPeerDependencies returns pinned peers", async () => {
19
- const peers = await loadPeerDependencies(fixturePath("manifest-with-peers.json"))
20
- expect(peers).toEqual(["eslint@9.39.1", "prettier@3.6.2"])
21
- })
22
-
23
- test("loadPeerDependencies handles missing peers", async () => {
24
- const peers = await loadPeerDependencies(fixturePath("manifest-no-peers.json"))
25
- expect(peers).toEqual([])
26
- })
27
-
28
- test("detectManager respects explicit flag", () => {
29
- const manager = detectManager({ managerArg: "pnpm" })
30
- expect(manager).toBe("pnpm")
31
- })
32
-
33
- test("detectManager infers from user agent", () => {
34
- const manager = detectManager({ userAgent: "pnpm/9.0.0 npm/?" })
35
- expect(manager).toBe("pnpm")
36
- })
37
-
38
- test("detectManager infers from lockfile", async () => {
39
- const dir = await mkdtemp(join(tmpdir(), "skyltmax-config-"))
40
- await writeFile(join(dir, "bun.lockb"), "")
41
- const manager = detectManager({ cwd: dir })
42
- expect(manager).toBe("bun")
43
- })
44
-
45
- test("buildInstallCommand supports npm", () => {
46
- const result = buildInstallCommand("npm", ["eslint@9.39.1"])
47
- expect(result.command).toBe("npm")
48
- expect(result.args).toEqual(["install", "--save-dev", "--save-exact", "eslint@9.39.1"])
49
- expect(formatCommand(result)).toBe("npm install --save-dev --save-exact eslint@9.39.1")
50
- })
51
-
52
- test("buildInstallCommand adds -w flag in pnpm workspaces", async () => {
53
- const workspaceDir = await mkdtemp(join(tmpdir(), "skyltmax-config-workspace-"))
54
- await writeFile(join(workspaceDir, "pnpm-workspace.yaml"), "packages:\n - packages/*\n")
55
- const packageDir = join(workspaceDir, "packages", "app")
56
- await mkdir(packageDir, { recursive: true })
57
-
58
- const result = buildInstallCommand("pnpm", ["eslint@9.39.1"], { cwd: packageDir })
59
-
60
- expect(result.command).toBe("pnpm")
61
- expect(result.args).toEqual(["add", "-D", "-w", "--save-exact", "eslint@9.39.1"])
62
- expect(result.cwd).toBe(workspaceDir)
63
- })
64
-
65
- test("buildInstallCommand throws on unsupported manager", () => {
66
- expect(() => buildInstallCommand("yarn", ["eslint@9.39.1"])).toThrow(/Unsupported package manager/)
67
- })
68
-
69
- test("prepareInstall returns printable command", async () => {
70
- const result = await prepareInstall({
71
- managerArg: "npm",
72
- env: {},
73
- cwd: process.cwd(),
74
- manifestPath: fixturePath("manifest-with-peers.json"),
75
- })
76
-
77
- expect(result.manager).toBe("npm")
78
- expect(result.packages).toEqual(["eslint@9.39.1", "prettier@3.6.2"])
79
- expect(result.printable).toBe("npm install --save-dev --save-exact eslint@9.39.1 prettier@3.6.2")
80
- })
81
-
82
- test("prepareInstall targets pnpm workspace root", async () => {
83
- const workspaceDir = await mkdtemp(join(tmpdir(), "skyltmax-config-workspace-"))
84
- await writeFile(join(workspaceDir, "pnpm-workspace.yaml"), "packages:\n - packages/*\n")
85
- const manifestPath = join(workspaceDir, "package.json")
86
- await writeFile(manifestPath, JSON.stringify({ peerDependencies: { eslint: "9.39.1" } }, null, 2))
87
-
88
- const packageDir = join(workspaceDir, "packages", "app")
89
- await mkdir(packageDir, { recursive: true })
90
-
91
- const result = await prepareInstall({
92
- managerArg: "pnpm",
93
- env: {},
94
- cwd: packageDir,
95
- manifestPath,
96
- })
97
-
98
- expect(result.manager).toBe("pnpm")
99
- expect(result.packages).toEqual(["eslint@9.39.1"])
100
- expect(result.args).toEqual(["add", "-D", "-w", "--save-exact", "eslint@9.39.1"])
101
- expect(result.cwd).toBe(workspaceDir)
102
- expect(result.printable).toBe("pnpm add -D -w --save-exact eslint@9.39.1")
103
- })
104
-
105
- test("prepareInstall returns empty when no peers", async () => {
106
- const result = await prepareInstall({
107
- managerArg: "npm",
108
- env: {},
109
- cwd: process.cwd(),
110
- manifestPath: fixturePath("manifest-no-peers.json"),
111
- })
112
-
113
- expect(result.packages).toEqual([])
114
- })
115
- })