@regressionproof/cli 0.3.6 → 0.3.8
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/build/cli.d.ts +2 -0
- package/build/cli.js +52 -0
- package/build/commands/invite/AcceptInvite.d.ts +1 -0
- package/build/commands/invite/AcceptInvite.js +17 -0
- package/build/commands/invite/CreateInvite.d.ts +1 -0
- package/build/commands/invite/CreateInvite.js +42 -0
- package/build/commands/invite/ListInvites.d.ts +1 -0
- package/build/commands/invite/ListInvites.js +18 -0
- package/build/commands/invite/RevokeInvite.d.ts +1 -0
- package/build/commands/invite/RevokeInvite.js +11 -0
- package/build/components/Init.d.ts +4 -0
- package/build/components/Init.js +286 -0
- package/{src → build}/components/Init.tsx +1 -2
- package/build/config/ConfigManager.d.ts +17 -0
- package/build/config/ConfigManager.js +35 -0
- package/build/esm/cli.d.ts +2 -0
- package/build/esm/cli.js +52 -0
- package/build/esm/commands/invite/AcceptInvite.d.ts +1 -0
- package/build/esm/commands/invite/AcceptInvite.js +29 -0
- package/build/esm/commands/invite/CreateInvite.d.ts +1 -0
- package/build/esm/commands/invite/CreateInvite.js +55 -0
- package/build/esm/commands/invite/ListInvites.d.ts +1 -0
- package/build/esm/commands/invite/ListInvites.js +30 -0
- package/build/esm/commands/invite/RevokeInvite.d.ts +1 -0
- package/build/esm/commands/invite/RevokeInvite.js +23 -0
- package/build/esm/components/Init.d.ts +4 -0
- package/build/esm/components/Init.js +301 -0
- package/build/esm/config/ConfigManager.d.ts +17 -0
- package/build/esm/config/ConfigManager.js +34 -0
- package/build/esm/index.d.ts +1 -0
- package/{src/index.ts → build/esm/index.js} +1 -0
- package/build/esm/jest/JestConfigurator.d.ts +12 -0
- package/build/esm/jest/JestConfigurator.js +57 -0
- package/build/esm/utilities/slug.d.ts +2 -0
- package/build/esm/utilities/slug.js +22 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +2 -0
- package/build/jest/JestConfigurator.d.ts +12 -0
- package/build/jest/JestConfigurator.js +59 -0
- package/build/utilities/slug.d.ts +2 -0
- package/build/utilities/slug.js +21 -0
- package/package.json +8 -3
- package/.nvmrc +0 -1
- package/.vscode/launch.json +0 -58
- package/.vscode/settings.json +0 -67
- package/.vscode/tasks.json +0 -112
- package/CHANGELOG.md +0 -322
- package/eslint.config.mjs +0 -3
- package/src/cli.ts +0 -53
- package/src/commands/invite/AcceptInvite.ts +0 -21
- package/src/commands/invite/CreateInvite.ts +0 -60
- package/src/commands/invite/ListInvites.ts +0 -33
- package/src/commands/invite/RevokeInvite.ts +0 -18
- package/src/config/ConfigManager.ts +0 -64
- package/src/jest/JestConfigurator.ts +0 -92
- package/src/utilities/slug.ts +0 -22
- package/terms.md +0 -3
- package/tsconfig.json +0 -42
- /package/{src → build}/.spruce/settings.json +0 -0
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const API_URL =
|
|
2
|
-
process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
|
|
3
|
-
|
|
4
|
-
export default async function acceptInvite(token: string): Promise<void> {
|
|
5
|
-
const response = await fetch(`${API_URL}/invites/accept`, {
|
|
6
|
-
method: 'POST',
|
|
7
|
-
headers: {
|
|
8
|
-
'Content-Type': 'application/json',
|
|
9
|
-
},
|
|
10
|
-
body: JSON.stringify({ token }),
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
if (!response.ok) {
|
|
14
|
-
const text = await response.text()
|
|
15
|
-
throw new Error(`Invite accept failed: ${response.status} ${text}`)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const data = (await response.json()) as { url: string; token: string }
|
|
19
|
-
console.log('Project URL:', data.url)
|
|
20
|
-
console.log('Project token:', data.token)
|
|
21
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import ConfigManager from '../../config/ConfigManager.js'
|
|
2
|
-
import { getRepoNameFromGit, toSlug } from '../../utilities/slug.js'
|
|
3
|
-
|
|
4
|
-
const API_URL =
|
|
5
|
-
process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
|
|
6
|
-
|
|
7
|
-
class InviteCreator {
|
|
8
|
-
public constructor(private configManager = new ConfigManager()) {}
|
|
9
|
-
|
|
10
|
-
public async run(projectNameArg?: string, note?: string): Promise<void> {
|
|
11
|
-
const projectName = this.resolveProjectName(projectNameArg)
|
|
12
|
-
const creds = this.configManager.loadCredentials(projectName)
|
|
13
|
-
if (!creds) {
|
|
14
|
-
throw new Error(
|
|
15
|
-
`No credentials found for ${projectName}. Run regressionproof init first.`
|
|
16
|
-
)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const response = await fetch(`${API_URL}/invites`, {
|
|
20
|
-
method: 'POST',
|
|
21
|
-
headers: {
|
|
22
|
-
'Content-Type': 'application/json',
|
|
23
|
-
Authorization: `Bearer ${creds.token}`,
|
|
24
|
-
},
|
|
25
|
-
body: JSON.stringify({ name: projectName, note }),
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
if (!response.ok) {
|
|
29
|
-
const text = await response.text()
|
|
30
|
-
throw new Error(`Invite create failed: ${response.status} ${text}`)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const data = (await response.json()) as InviteCreateResponse
|
|
34
|
-
console.log('Invite token:', data.token)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private resolveProjectName(projectNameArg?: string): string {
|
|
38
|
-
const provided = projectNameArg ? toSlug(projectNameArg) : ''
|
|
39
|
-
const name = provided || getRepoNameFromGit()
|
|
40
|
-
if (!name) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
'Project name is required. Provide it explicitly or ensure git origin is set.'
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
return name
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export default async function createInvite(
|
|
50
|
-
projectName?: string,
|
|
51
|
-
note?: string
|
|
52
|
-
): Promise<void> {
|
|
53
|
-
const creator = new InviteCreator()
|
|
54
|
-
await creator.run(projectName, note)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
interface InviteCreateResponse {
|
|
58
|
-
token: string
|
|
59
|
-
projectName: string
|
|
60
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const API_URL =
|
|
2
|
-
process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
|
|
3
|
-
|
|
4
|
-
export default async function listInvites(projectName?: string): Promise<void> {
|
|
5
|
-
const query = projectName ? `?name=${encodeURIComponent(projectName)}` : ''
|
|
6
|
-
const response = await fetch(`${API_URL}/invites${query}`)
|
|
7
|
-
|
|
8
|
-
if (!response.ok) {
|
|
9
|
-
const text = await response.text()
|
|
10
|
-
throw new Error(`Invite list failed: ${response.status} ${text}`)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const data = (await response.json()) as {
|
|
14
|
-
projectName: string
|
|
15
|
-
createdAt: string
|
|
16
|
-
usedAt?: string | null
|
|
17
|
-
revokedAt?: string | null
|
|
18
|
-
note?: string | null
|
|
19
|
-
status: 'active' | 'used' | 'revoked'
|
|
20
|
-
}[]
|
|
21
|
-
|
|
22
|
-
if (data.length === 0) {
|
|
23
|
-
console.log('No invites found.')
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
for (const invite of data) {
|
|
28
|
-
console.log(
|
|
29
|
-
`${invite.projectName} | ${invite.status} | created ${invite.createdAt}` +
|
|
30
|
-
(invite.note ? ` | ${invite.note}` : '')
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const API_URL =
|
|
2
|
-
process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
|
|
3
|
-
|
|
4
|
-
export default async function revokeInvite(token: string): Promise<void> {
|
|
5
|
-
const response = await fetch(
|
|
6
|
-
`${API_URL}/invites/${encodeURIComponent(token)}`,
|
|
7
|
-
{
|
|
8
|
-
method: 'DELETE',
|
|
9
|
-
}
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
if (!response.ok) {
|
|
13
|
-
const text = await response.text()
|
|
14
|
-
throw new Error(`Invite revoke failed: ${response.status} ${text}`)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
console.log('Invite revoked.')
|
|
18
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import os from 'os'
|
|
3
|
-
import path from 'path'
|
|
4
|
-
|
|
5
|
-
export default class ConfigManager {
|
|
6
|
-
private baseDir: string
|
|
7
|
-
|
|
8
|
-
public constructor(
|
|
9
|
-
baseDir: string = path.join(os.homedir(), '.regressionproof')
|
|
10
|
-
) {
|
|
11
|
-
this.baseDir = baseDir
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public getConfigDir(projectName: string): string {
|
|
15
|
-
return path.join(this.baseDir, projectName)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public saveCredentials(
|
|
19
|
-
projectName: string,
|
|
20
|
-
credentials: Credentials
|
|
21
|
-
): void {
|
|
22
|
-
const configDir = this.getConfigDir(projectName)
|
|
23
|
-
fs.mkdirSync(configDir, { recursive: true })
|
|
24
|
-
|
|
25
|
-
const configPath = path.join(configDir, 'config.json')
|
|
26
|
-
const config: ProjectConfig = {
|
|
27
|
-
remote: {
|
|
28
|
-
url: credentials.url,
|
|
29
|
-
token: credentials.token,
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2))
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public loadCredentials(projectName: string): Credentials | null {
|
|
36
|
-
const configPath = path.join(
|
|
37
|
-
this.getConfigDir(projectName),
|
|
38
|
-
'config.json'
|
|
39
|
-
)
|
|
40
|
-
if (!fs.existsSync(configPath)) {
|
|
41
|
-
return null
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const config: ProjectConfig = JSON.parse(
|
|
45
|
-
fs.readFileSync(configPath, 'utf-8')
|
|
46
|
-
)
|
|
47
|
-
return {
|
|
48
|
-
url: config.remote.url,
|
|
49
|
-
token: config.remote.token,
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface Credentials {
|
|
55
|
-
url: string
|
|
56
|
-
token: string
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface ProjectConfig {
|
|
60
|
-
remote: {
|
|
61
|
-
url: string
|
|
62
|
-
token: string
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
|
|
4
|
-
export default class JestConfigurator {
|
|
5
|
-
private cwd: string
|
|
6
|
-
private reporterPackage = '@regressionproof/jest-reporter'
|
|
7
|
-
|
|
8
|
-
public constructor(cwd: string = process.cwd()) {
|
|
9
|
-
this.cwd = cwd
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
public configure(): JestConfigResult {
|
|
13
|
-
return (
|
|
14
|
-
this.tryConfigurePackageJson() ??
|
|
15
|
-
this.tryConfigureJestConfig('jest.config.ts') ??
|
|
16
|
-
this.tryConfigureJestConfig('jest.config.js') ?? {
|
|
17
|
-
configured: false,
|
|
18
|
-
location: '',
|
|
19
|
-
}
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
private tryConfigurePackageJson(): JestConfigResult | null {
|
|
24
|
-
const packageJsonPath = path.join(this.cwd, 'package.json')
|
|
25
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
26
|
-
return null
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const packageJson = JSON.parse(
|
|
30
|
-
fs.readFileSync(packageJsonPath, 'utf-8')
|
|
31
|
-
)
|
|
32
|
-
if (!packageJson.jest) {
|
|
33
|
-
return null
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (!packageJson.jest.reporters) {
|
|
37
|
-
packageJson.jest.reporters = ['default']
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!packageJson.jest.reporters.includes(this.reporterPackage)) {
|
|
41
|
-
packageJson.jest.reporters.push(this.reporterPackage)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
fs.writeFileSync(
|
|
45
|
-
packageJsonPath,
|
|
46
|
-
JSON.stringify(packageJson, null, 2) + '\n'
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
return { configured: true, location: 'package.json' }
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private tryConfigureJestConfig(filename: string): JestConfigResult | null {
|
|
53
|
-
const configPath = path.join(this.cwd, filename)
|
|
54
|
-
if (!fs.existsSync(configPath)) {
|
|
55
|
-
return null
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let content = fs.readFileSync(configPath, 'utf-8')
|
|
59
|
-
|
|
60
|
-
if (content.includes(this.reporterPackage)) {
|
|
61
|
-
return {
|
|
62
|
-
configured: true,
|
|
63
|
-
location: `${filename} (already configured)`,
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (content.includes('reporters:')) {
|
|
68
|
-
content = content.replace(
|
|
69
|
-
/(reporters:\s*\[)/,
|
|
70
|
-
`$1'${this.reporterPackage}', `
|
|
71
|
-
)
|
|
72
|
-
} else {
|
|
73
|
-
const exportPattern = filename.endsWith('.ts')
|
|
74
|
-
? /(export\s+default\s*\{)/
|
|
75
|
-
: /(module\.exports\s*=\s*\{)/
|
|
76
|
-
|
|
77
|
-
content = content.replace(
|
|
78
|
-
exportPattern,
|
|
79
|
-
`$1\n reporters: ['default', '${this.reporterPackage}'],`
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
fs.writeFileSync(configPath, content)
|
|
84
|
-
|
|
85
|
-
return { configured: true, location: filename }
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export interface JestConfigResult {
|
|
90
|
-
configured: boolean
|
|
91
|
-
location: string
|
|
92
|
-
}
|
package/src/utilities/slug.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process'
|
|
2
|
-
|
|
3
|
-
export function toSlug(input: string): string {
|
|
4
|
-
return input
|
|
5
|
-
.toLowerCase()
|
|
6
|
-
.replace(/\s+/g, '-')
|
|
7
|
-
.replace(/[^a-z0-9-_]/g, '')
|
|
8
|
-
.replace(/-+/g, '-')
|
|
9
|
-
.replace(/^-|-$/g, '')
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function getRepoNameFromGit(): string {
|
|
13
|
-
try {
|
|
14
|
-
const remoteUrl = execSync('git remote get-url origin', {
|
|
15
|
-
encoding: 'utf-8',
|
|
16
|
-
}).trim()
|
|
17
|
-
const match = remoteUrl.match(/[/:]([^/:]+?)(\.git)?$/)
|
|
18
|
-
return toSlug(match?.[1] ?? '')
|
|
19
|
-
} catch {
|
|
20
|
-
return ''
|
|
21
|
-
}
|
|
22
|
-
}
|
package/terms.md
DELETED
package/tsconfig.json
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"skipLibCheck": true,
|
|
4
|
-
"module": "nodenext",
|
|
5
|
-
"esModuleInterop": true,
|
|
6
|
-
"target": "ES2022",
|
|
7
|
-
"lib": [
|
|
8
|
-
"DOM",
|
|
9
|
-
"ES2022"
|
|
10
|
-
],
|
|
11
|
-
"jsx": "react",
|
|
12
|
-
"declaration": true,
|
|
13
|
-
"noImplicitAny": true,
|
|
14
|
-
"allowJs": true,
|
|
15
|
-
"forceConsistentCasingInFileNames": true,
|
|
16
|
-
"noImplicitReturns": true,
|
|
17
|
-
"strict": true,
|
|
18
|
-
"noUnusedLocals": true,
|
|
19
|
-
"resolveJsonModule": true,
|
|
20
|
-
"moduleResolution": "nodenext",
|
|
21
|
-
"sourceMap": false,
|
|
22
|
-
"outDir": "build",
|
|
23
|
-
"baseUrl": "src",
|
|
24
|
-
"experimentalDecorators": true,
|
|
25
|
-
"paths": {
|
|
26
|
-
"#spruce/*": [
|
|
27
|
-
".spruce/*"
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"include": [
|
|
32
|
-
"./src/*.ts",
|
|
33
|
-
"./src/**/*.ts",
|
|
34
|
-
"./src/*.tsx",
|
|
35
|
-
"./src/**/*.tsx",
|
|
36
|
-
"./src/.spruce/**/*"
|
|
37
|
-
],
|
|
38
|
-
"exclude": [
|
|
39
|
-
"build",
|
|
40
|
-
"esm"
|
|
41
|
-
]
|
|
42
|
-
}
|
|
File without changes
|