skyltmax_config 0.0.8 → 0.0.10
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.
- checksums.yaml +4 -4
- data/.prettierignore +1 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +1 -1
- data/README.md +14 -0
- data/eslint.config.js +12 -1
- data/fixture/.prettierignore +1 -0
- data/fixture/eslint.config.js +4 -0
- data/fixture/package.json +19 -0
- data/fixture/pnpm-lock.yaml +3195 -0
- data/fixture/src/index.ts +1 -0
- data/fixture/src/ui/button.tsx +24 -0
- data/fixture/tsconfig.json +13 -0
- data/lib/skyltmax_config/version.rb +1 -1
- data/package.json +10 -3
- data/pnpm-lock.yaml +1877 -1420
- data/prettier.js +3 -14
- data/scripts/peer-deps/audit.js +132 -0
- data/scripts/peer-deps/install.js +176 -0
- data/tests/check-peers.test.js +76 -0
- data/tests/fixtures/manifest-no-peers.json +3 -0
- data/tests/fixtures/manifest-with-peers.json +6 -0
- data/tests/install-peers.test.js +79 -0
- data/tsconfig.json +1 -0
- metadata +15 -1
data/prettier.js
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
// Try to load the Tailwind plugin if available
|
|
2
|
-
let tailwindPlugin
|
|
3
|
-
try {
|
|
4
|
-
tailwindPlugin = await import("prettier-plugin-tailwindcss")
|
|
5
|
-
} catch {
|
|
6
|
-
// Plugin not installed, that's okay
|
|
7
|
-
}
|
|
8
|
-
|
|
9
1
|
/** @type {import("prettier").Options} */
|
|
10
2
|
export const config = {
|
|
11
3
|
arrowParens: "avoid",
|
|
@@ -47,12 +39,9 @@ export const config = {
|
|
|
47
39
|
},
|
|
48
40
|
},
|
|
49
41
|
],
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
tailwindAttributes: ["class", "className", ".*[cC]lassName"],
|
|
54
|
-
tailwindFunctions: ["clsx", "cn", "twcn"],
|
|
55
|
-
}),
|
|
42
|
+
plugins: ["prettier-plugin-tailwindcss"],
|
|
43
|
+
tailwindAttributes: ["class", "className", ".*[cC]lassName"],
|
|
44
|
+
tailwindFunctions: ["clsx", "cn", "twcn"],
|
|
56
45
|
}
|
|
57
46
|
|
|
58
47
|
// this is for backward compatibility
|
|
@@ -0,0 +1,132 @@
|
|
|
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 = ["[signmax-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 signmax-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(`[signmax-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
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
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: signmax-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 buildInstallCommand(manager, packages) {
|
|
41
|
+
if (!packages.length) {
|
|
42
|
+
throw new Error("No peer dependencies to install.")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const commandByManager = {
|
|
46
|
+
npm: {
|
|
47
|
+
command: "npm",
|
|
48
|
+
args: ["install", "--save-dev", "--save-exact", ...packages],
|
|
49
|
+
},
|
|
50
|
+
pnpm: {
|
|
51
|
+
command: "pnpm",
|
|
52
|
+
args: ["add", "-D", "--save-exact", ...packages],
|
|
53
|
+
},
|
|
54
|
+
bun: {
|
|
55
|
+
command: "bun",
|
|
56
|
+
args: ["add", "--dev", "--exact", ...packages],
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const selected = commandByManager[manager]
|
|
61
|
+
|
|
62
|
+
if (!selected) {
|
|
63
|
+
const supported = Object.keys(commandByManager).join(", ")
|
|
64
|
+
throw new Error(`Unsupported package manager: ${manager}. Supported managers: ${supported}`)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return selected
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function formatCommand({ command, args }) {
|
|
71
|
+
return `${command} ${args.join(" ")}`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export async function prepareInstall({
|
|
75
|
+
managerArg,
|
|
76
|
+
cwd = process.cwd(),
|
|
77
|
+
env = process.env,
|
|
78
|
+
manifestPath = defaultManifestPath,
|
|
79
|
+
} = {}) {
|
|
80
|
+
const packages = await loadPeerDependencies(manifestPath)
|
|
81
|
+
|
|
82
|
+
if (packages.length === 0) {
|
|
83
|
+
return { packages: [] }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const manager = detectManager({ managerArg, userAgent: env.npm_config_user_agent ?? "", cwd })
|
|
87
|
+
const command = buildInstallCommand(manager, packages)
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
manager,
|
|
91
|
+
packages,
|
|
92
|
+
command: command.command,
|
|
93
|
+
args: command.args,
|
|
94
|
+
printable: formatCommand(command),
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export async function runCli({ args = process.argv.slice(2), env = process.env, cwd = process.cwd() } = {}) {
|
|
99
|
+
if (args.includes("--help")) {
|
|
100
|
+
process.stdout.write(HELP)
|
|
101
|
+
return 0
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const argValue = flag => {
|
|
105
|
+
const index = args.indexOf(flag)
|
|
106
|
+
if (index === -1) return undefined
|
|
107
|
+
return args[index + 1]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const managerArg = argValue("--manager")
|
|
111
|
+
const dryRun = args.includes("--dry-run")
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const result = await prepareInstall({ managerArg, cwd, env })
|
|
115
|
+
|
|
116
|
+
if (!result.packages || result.packages.length === 0) {
|
|
117
|
+
process.stdout.write("No peer dependencies found on @signmax/config.\n")
|
|
118
|
+
return 0
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (dryRun) {
|
|
122
|
+
process.stdout.write(`${result.printable}\n`)
|
|
123
|
+
return 0
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
process.stdout.write(`Running: ${result.printable}\n`)
|
|
127
|
+
|
|
128
|
+
const child = spawn(result.command, result.args, {
|
|
129
|
+
stdio: "inherit",
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
return await new Promise((resolve, reject) => {
|
|
133
|
+
child.on("close", code => {
|
|
134
|
+
if (code === 0) {
|
|
135
|
+
resolve(0)
|
|
136
|
+
} else {
|
|
137
|
+
reject(new Error(`${result.command} exited with code ${code}`))
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
child.on("error", error => {
|
|
142
|
+
reject(error)
|
|
143
|
+
})
|
|
144
|
+
})
|
|
145
|
+
} catch (error) {
|
|
146
|
+
process.stderr.write(`${error.message}\n`)
|
|
147
|
+
return 1
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const isDirectExecution = (() => {
|
|
152
|
+
const [argvPath] = process.argv.slice(1, 2)
|
|
153
|
+
|
|
154
|
+
if (!argvPath) return false
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
return realpathSync(argvPath) === realpathSync(__filename)
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
160
|
+
return false
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw error
|
|
164
|
+
}
|
|
165
|
+
})()
|
|
166
|
+
|
|
167
|
+
if (isDirectExecution) {
|
|
168
|
+
runCli()
|
|
169
|
+
.then(code => {
|
|
170
|
+
process.exit(code)
|
|
171
|
+
})
|
|
172
|
+
.catch(error => {
|
|
173
|
+
process.stderr.write(`${error.message}\n`)
|
|
174
|
+
process.exit(1)
|
|
175
|
+
})
|
|
176
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
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(), "signmax-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
|
+
})
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { 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(), "signmax-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 throws on unsupported manager", () => {
|
|
53
|
+
expect(() => buildInstallCommand("yarn", ["eslint@9.39.1"])).toThrow(/Unsupported package manager/)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test("prepareInstall returns printable command", async () => {
|
|
57
|
+
const result = await prepareInstall({
|
|
58
|
+
managerArg: "npm",
|
|
59
|
+
env: {},
|
|
60
|
+
cwd: process.cwd(),
|
|
61
|
+
manifestPath: fixturePath("manifest-with-peers.json"),
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
expect(result.manager).toBe("npm")
|
|
65
|
+
expect(result.packages).toEqual(["eslint@9.39.1", "prettier@3.6.2"])
|
|
66
|
+
expect(result.printable).toBe("npm install --save-dev --save-exact eslint@9.39.1 prettier@3.6.2")
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test("prepareInstall returns empty when no peers", async () => {
|
|
70
|
+
const result = await prepareInstall({
|
|
71
|
+
managerArg: "npm",
|
|
72
|
+
env: {},
|
|
73
|
+
cwd: process.cwd(),
|
|
74
|
+
manifestPath: fixturePath("manifest-no-peers.json"),
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
expect(result.packages).toEqual([])
|
|
78
|
+
})
|
|
79
|
+
})
|
data/tsconfig.json
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: skyltmax_config
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Signmax AB
|
|
@@ -93,6 +93,7 @@ files:
|
|
|
93
93
|
- ".devcontainer/devcontainer.json"
|
|
94
94
|
- ".devcontainer/docker-compose.yml"
|
|
95
95
|
- ".gitignore"
|
|
96
|
+
- ".prettierignore"
|
|
96
97
|
- ".rubocop.yml"
|
|
97
98
|
- AGENTS.md
|
|
98
99
|
- CHANGELOG.md
|
|
@@ -103,6 +104,13 @@ files:
|
|
|
103
104
|
- Rakefile
|
|
104
105
|
- eslint.config.js
|
|
105
106
|
- eslint.js
|
|
107
|
+
- fixture/.prettierignore
|
|
108
|
+
- fixture/eslint.config.js
|
|
109
|
+
- fixture/package.json
|
|
110
|
+
- fixture/pnpm-lock.yaml
|
|
111
|
+
- fixture/src/index.ts
|
|
112
|
+
- fixture/src/ui/button.tsx
|
|
113
|
+
- fixture/tsconfig.json
|
|
106
114
|
- index.js
|
|
107
115
|
- lib/skyltmax_config.rb
|
|
108
116
|
- lib/skyltmax_config/version.rb
|
|
@@ -112,7 +120,13 @@ files:
|
|
|
112
120
|
- reset.d.ts
|
|
113
121
|
- rubocop.rails.yml
|
|
114
122
|
- rubocop.yml
|
|
123
|
+
- scripts/peer-deps/audit.js
|
|
124
|
+
- scripts/peer-deps/install.js
|
|
115
125
|
- skyltmax_config.gemspec
|
|
126
|
+
- tests/check-peers.test.js
|
|
127
|
+
- tests/fixtures/manifest-no-peers.json
|
|
128
|
+
- tests/fixtures/manifest-with-peers.json
|
|
129
|
+
- tests/install-peers.test.js
|
|
116
130
|
- tsconfig.json
|
|
117
131
|
- typescript.json
|
|
118
132
|
homepage: https://github.com/skyltmax/config
|