@jacebenson/jsn 1.0.7 → 2.0.1
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/README.md +196 -243
- package/bin/jsn.js +2 -57
- package/package.json +35 -32
- package/skills/servicenow/SKILL.md +137 -0
- package/src/app.js +172 -0
- package/src/auth.js +517 -0
- package/src/cli.js +174 -0
- package/src/commands/_ticket.js +260 -0
- package/src/commands/auth.js +227 -0
- package/src/commands/catalog.js +325 -0
- package/src/commands/changes.js +7 -0
- package/src/commands/dev/_generic.js +342 -0
- package/src/commands/dev/_simple.js +89 -0
- package/src/commands/dev/eval.js +38 -0
- package/src/commands/dev/flows.js +573 -0
- package/src/commands/dev/forms.js +313 -0
- package/src/commands/dev/lists.js +233 -0
- package/src/commands/dev/logs.js +64 -0
- package/src/commands/dev/rest.js +64 -0
- package/src/commands/dev/scopes.js +156 -0
- package/src/commands/dev/updatesets.js +184 -0
- package/src/commands/dev.js +53 -0
- package/src/commands/groupmembers.js +152 -0
- package/src/commands/grouproles.js +152 -0
- package/src/commands/groups.js +141 -0
- package/src/commands/incidents.js +7 -0
- package/src/commands/profiles.js +91 -0
- package/src/commands/records.js +171 -0
- package/src/commands/requests.js +59 -0
- package/src/commands/setup.js +39 -0
- package/src/commands/skill.js +144 -0
- package/src/commands/tasks.js +7 -0
- package/src/commands/tickets.js +121 -0
- package/src/commands/users.js +144 -0
- package/src/commands/version.js +81 -0
- package/src/config.js +154 -0
- package/src/context.js +62 -0
- package/src/errors.js +101 -0
- package/src/help.js +85 -0
- package/src/helpers.js +182 -0
- package/src/output.js +440 -0
- package/src/sdk.js +615 -0
- package/scripts/install.sh +0 -227
- package/scripts/npm-install.js +0 -235
- package/scripts/pre-commit-check.sh +0 -61
package/scripts/install.sh
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# JSN CLI Installer
|
|
3
|
-
# Installs the latest JSN release from GitHub
|
|
4
|
-
#
|
|
5
|
-
# Usage:
|
|
6
|
-
# curl -fsSL https://jsn.jace.pro/install | bash
|
|
7
|
-
#
|
|
8
|
-
# Environment:
|
|
9
|
-
# JSN_VERSION Install specific version (e.g., 0.4.1)
|
|
10
|
-
# NO_COLOR Disable colored output (https://no-color.org)
|
|
11
|
-
|
|
12
|
-
set -euo pipefail
|
|
13
|
-
|
|
14
|
-
REPO="jacebenson/jsn"
|
|
15
|
-
BINARY_NAME="jsn"
|
|
16
|
-
INSTALL_DIR="${JSN_INSTALL_DIR:-}"
|
|
17
|
-
VERSION="${JSN_VERSION:-}"
|
|
18
|
-
|
|
19
|
-
# Colors - respect NO_COLOR (https://no-color.org)
|
|
20
|
-
if [[ -z "${NO_COLOR:-}" ]] && [[ -t 1 ]]; then
|
|
21
|
-
RED='\033[0;31m'
|
|
22
|
-
GREEN='\033[0;32m'
|
|
23
|
-
YELLOW='\033[1;33m'
|
|
24
|
-
NC='\033[0m'
|
|
25
|
-
BOLD='\033[1m'
|
|
26
|
-
else
|
|
27
|
-
RED=''
|
|
28
|
-
GREEN=''
|
|
29
|
-
YELLOW=''
|
|
30
|
-
NC=''
|
|
31
|
-
BOLD=''
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
info() { echo -e "${GREEN}✓${NC} $1"; }
|
|
35
|
-
step() { echo -e "${BOLD}→${NC} $1"; }
|
|
36
|
-
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
|
37
|
-
error() { echo -e "${RED}✗${NC} $1" >&2; exit 1; }
|
|
38
|
-
|
|
39
|
-
detect_platform() {
|
|
40
|
-
local os arch
|
|
41
|
-
|
|
42
|
-
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
43
|
-
case "$os" in
|
|
44
|
-
linux) PLATFORM="linux" ;;
|
|
45
|
-
darwin) PLATFORM="darwin" ;;
|
|
46
|
-
mingw*|msys*|cygwin*)
|
|
47
|
-
PLATFORM="windows"
|
|
48
|
-
BINARY_NAME="jsn.exe"
|
|
49
|
-
;;
|
|
50
|
-
*) error "Unsupported OS: $os" ;;
|
|
51
|
-
esac
|
|
52
|
-
|
|
53
|
-
arch=$(uname -m)
|
|
54
|
-
case "$arch" in
|
|
55
|
-
x86_64|amd64) ARCH="amd64" ;;
|
|
56
|
-
arm64|aarch64) ARCH="arm64" ;;
|
|
57
|
-
armv7l) ARCH="arm" ;;
|
|
58
|
-
*) error "Unsupported architecture: $arch" ;;
|
|
59
|
-
esac
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get_latest_version() {
|
|
63
|
-
# Use redirect URL instead of API to avoid rate limits
|
|
64
|
-
local url
|
|
65
|
-
url=$(curl -fsSL -o /dev/null -w '%{url_effective}' "https://github.com/${REPO}/releases/latest" 2>/dev/null) || true
|
|
66
|
-
local version="${url##*/}"
|
|
67
|
-
version="${version#v}"
|
|
68
|
-
|
|
69
|
-
if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
70
|
-
error "Could not determine latest version. Check your network connection."
|
|
71
|
-
fi
|
|
72
|
-
|
|
73
|
-
echo "$version"
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
setup_install_dir() {
|
|
77
|
-
if [[ -z "$INSTALL_DIR" ]]; then
|
|
78
|
-
if [[ -w "/usr/local/bin" ]]; then
|
|
79
|
-
INSTALL_DIR="/usr/local/bin"
|
|
80
|
-
else
|
|
81
|
-
INSTALL_DIR="$HOME/.local/bin"
|
|
82
|
-
fi
|
|
83
|
-
fi
|
|
84
|
-
mkdir -p "$INSTALL_DIR"
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
download_and_install() {
|
|
88
|
-
local version="$1"
|
|
89
|
-
local tmp_dir
|
|
90
|
-
tmp_dir=$(mktemp -d)
|
|
91
|
-
trap "rm -rf '$tmp_dir'" EXIT
|
|
92
|
-
|
|
93
|
-
# Determine archive extension
|
|
94
|
-
local ext
|
|
95
|
-
if [[ "$PLATFORM" == "windows" ]]; then
|
|
96
|
-
ext="zip"
|
|
97
|
-
else
|
|
98
|
-
ext="tar.gz"
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
local filename="jsn_v${version}_${PLATFORM}_${ARCH}.${ext}"
|
|
102
|
-
local url="https://github.com/${REPO}/releases/download/v${version}/${filename}"
|
|
103
|
-
|
|
104
|
-
step "Downloading JSN v${version} for ${PLATFORM}/${ARCH}..."
|
|
105
|
-
if ! curl -fsSL "$url" -o "${tmp_dir}/${filename}"; then
|
|
106
|
-
error "Download failed from $url"
|
|
107
|
-
fi
|
|
108
|
-
|
|
109
|
-
step "Extracting..."
|
|
110
|
-
cd "$tmp_dir"
|
|
111
|
-
if [[ "$PLATFORM" == "windows" ]]; then
|
|
112
|
-
unzip -q "$filename"
|
|
113
|
-
else
|
|
114
|
-
tar -xzf "$filename"
|
|
115
|
-
fi
|
|
116
|
-
|
|
117
|
-
# Find binary using shell globbing (Windows find is different)
|
|
118
|
-
local binary_file=""
|
|
119
|
-
for f in jsn jsn.exe jsn_*; do
|
|
120
|
-
if [[ -f "$f" ]] && [[ "$f" != "*.tar.gz" ]] && [[ "$f" != "*.zip" ]]; then
|
|
121
|
-
binary_file="$f"
|
|
122
|
-
break
|
|
123
|
-
fi
|
|
124
|
-
done
|
|
125
|
-
|
|
126
|
-
if [[ -z "$binary_file" ]]; then
|
|
127
|
-
error "Could not find binary in archive"
|
|
128
|
-
ls -la
|
|
129
|
-
exit 1
|
|
130
|
-
fi
|
|
131
|
-
|
|
132
|
-
step "Installing to $INSTALL_DIR..."
|
|
133
|
-
if [[ -w "$INSTALL_DIR" ]]; then
|
|
134
|
-
mv "$binary_file" "$INSTALL_DIR/$BINARY_NAME"
|
|
135
|
-
else
|
|
136
|
-
mv "$binary_file" "$INSTALL_DIR/$BINARY_NAME" 2>/dev/null || {
|
|
137
|
-
warn "Need sudo access to install to $INSTALL_DIR"
|
|
138
|
-
sudo mv "$binary_file" "$INSTALL_DIR/$BINARY_NAME"
|
|
139
|
-
}
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
chmod +x "$INSTALL_DIR/$BINARY_NAME" 2>/dev/null || true
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
setup_path() {
|
|
146
|
-
# Check if already in PATH
|
|
147
|
-
if [[ ":$PATH:" == *":$INSTALL_DIR:"* ]]; then
|
|
148
|
-
return 0
|
|
149
|
-
fi
|
|
150
|
-
|
|
151
|
-
# Determine shell config file
|
|
152
|
-
local shell_rc=""
|
|
153
|
-
if [[ "$PLATFORM" == "windows" ]]; then
|
|
154
|
-
# On Windows, always use .bashrc for Git Bash
|
|
155
|
-
shell_rc="$HOME/.bashrc"
|
|
156
|
-
else
|
|
157
|
-
case "${SHELL:-}" in
|
|
158
|
-
*/zsh) shell_rc="$HOME/.zshrc" ;;
|
|
159
|
-
*/bash) shell_rc="$HOME/.bashrc" ;;
|
|
160
|
-
*) shell_rc="$HOME/.profile" ;;
|
|
161
|
-
esac
|
|
162
|
-
fi
|
|
163
|
-
|
|
164
|
-
# Check if already in config
|
|
165
|
-
if [[ -f "$shell_rc" ]] && grep -qF "$INSTALL_DIR" "$shell_rc" 2>/dev/null; then
|
|
166
|
-
return 0
|
|
167
|
-
fi
|
|
168
|
-
|
|
169
|
-
step "Adding $INSTALL_DIR to PATH in $shell_rc"
|
|
170
|
-
echo "" >> "$shell_rc"
|
|
171
|
-
echo "# Added by JSN installer" >> "$shell_rc"
|
|
172
|
-
echo "export PATH=\"$INSTALL_DIR:\$PATH\"" >> "$shell_rc"
|
|
173
|
-
info "Added to $shell_rc"
|
|
174
|
-
warn "Run: source $shell_rc"
|
|
175
|
-
|
|
176
|
-
# On Windows, also warn about CMD/PowerShell
|
|
177
|
-
if [[ "$PLATFORM" == "windows" ]]; then
|
|
178
|
-
echo ""
|
|
179
|
-
warn "For Command Prompt or PowerShell, add this to your PATH manually:"
|
|
180
|
-
echo " $INSTALL_DIR"
|
|
181
|
-
echo " setx PATH \"%PATH%;$INSTALL_DIR\""
|
|
182
|
-
fi
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
verify_install() {
|
|
186
|
-
local installed_version
|
|
187
|
-
if installed_version=$("$INSTALL_DIR/$BINARY_NAME" version 2>/dev/null | tail -1); then
|
|
188
|
-
info "${installed_version}"
|
|
189
|
-
return 0
|
|
190
|
-
fi
|
|
191
|
-
error "Installation failed - JSN not working"
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
main() {
|
|
195
|
-
step "Installing JSN..."
|
|
196
|
-
|
|
197
|
-
detect_platform
|
|
198
|
-
|
|
199
|
-
if [[ -n "$VERSION" ]]; then
|
|
200
|
-
# Strip leading 'v' if present
|
|
201
|
-
VERSION="${VERSION#v}"
|
|
202
|
-
if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
203
|
-
error "Invalid version format: $VERSION (expected: 0.4.1)"
|
|
204
|
-
fi
|
|
205
|
-
else
|
|
206
|
-
VERSION=$(get_latest_version)
|
|
207
|
-
fi
|
|
208
|
-
|
|
209
|
-
setup_install_dir
|
|
210
|
-
download_and_install "$VERSION"
|
|
211
|
-
setup_path
|
|
212
|
-
verify_install "$PLATFORM"
|
|
213
|
-
|
|
214
|
-
echo ""
|
|
215
|
-
info "JSN installed successfully!"
|
|
216
|
-
echo ""
|
|
217
|
-
echo " Run 'jsn' to get started (setup will run automatically on first use)"
|
|
218
|
-
echo ""
|
|
219
|
-
|
|
220
|
-
if [[ "$PLATFORM" == "windows" ]]; then
|
|
221
|
-
warn "Windows users: Add $INSTALL_DIR to your PATH manually:"
|
|
222
|
-
echo " setx PATH \"%PATH%;$INSTALL_DIR\""
|
|
223
|
-
echo ""
|
|
224
|
-
fi
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
main "$@"
|
package/scripts/npm-install.js
DELETED
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* JSN npm postinstall script
|
|
4
|
-
*
|
|
5
|
-
* Downloads the correct platform-specific binary from GitHub releases
|
|
6
|
-
* and places it in the `binary/` directory for the wrapper to find.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const https = require('https');
|
|
10
|
-
const fs = require('fs');
|
|
11
|
-
const path = require('path');
|
|
12
|
-
const os = require('os');
|
|
13
|
-
const { execSync } = require('child_process');
|
|
14
|
-
|
|
15
|
-
const REPO = 'jacebenson/jsn';
|
|
16
|
-
const BINARY_DIR = path.join(__dirname, '..', 'binary');
|
|
17
|
-
|
|
18
|
-
const PLATFORM_MAP = {
|
|
19
|
-
darwin: 'darwin',
|
|
20
|
-
linux: 'linux',
|
|
21
|
-
win32: 'windows',
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const ARCH_MAP = {
|
|
25
|
-
x64: 'amd64',
|
|
26
|
-
arm64: 'arm64',
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
function detectPlatform() {
|
|
30
|
-
const platform = os.platform();
|
|
31
|
-
const arch = os.arch();
|
|
32
|
-
|
|
33
|
-
const mappedPlatform = PLATFORM_MAP[platform];
|
|
34
|
-
const mappedArch = ARCH_MAP[arch];
|
|
35
|
-
|
|
36
|
-
if (!mappedPlatform) {
|
|
37
|
-
throw new Error(
|
|
38
|
-
`Unsupported platform: ${platform}. ` +
|
|
39
|
-
`Supported platforms: ${Object.keys(PLATFORM_MAP).join(', ')}`
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!mappedArch) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
`Unsupported architecture: ${arch}. ` +
|
|
46
|
-
`Supported architectures: ${Object.keys(ARCH_MAP).join(', ')}`
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Windows arm64 can run amd64 binaries, so fall back
|
|
51
|
-
if (mappedPlatform === 'windows' && mappedArch === 'arm64') {
|
|
52
|
-
console.log(
|
|
53
|
-
'Warning: Windows arm64 build not available, using amd64 binary.'
|
|
54
|
-
);
|
|
55
|
-
return { platform: 'windows', arch: 'amd64', fallback: true };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return { platform: mappedPlatform, arch: mappedArch };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function getVersion() {
|
|
62
|
-
// npm sets this during install
|
|
63
|
-
if (process.env.npm_package_version) {
|
|
64
|
-
return process.env.npm_package_version;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Fallback: read package.json
|
|
68
|
-
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
69
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
70
|
-
return pkg.version;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function downloadFile(url, dest) {
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
const file = fs.createWriteStream(dest);
|
|
76
|
-
https
|
|
77
|
-
.get(url, { timeout: 30000 }, (response) => {
|
|
78
|
-
if (response.statusCode === 301 || response.statusCode === 302) {
|
|
79
|
-
// Follow redirect
|
|
80
|
-
return downloadFile(response.headers.location, dest)
|
|
81
|
-
.then(resolve)
|
|
82
|
-
.catch(reject);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (response.statusCode !== 200) {
|
|
86
|
-
reject(
|
|
87
|
-
new Error(
|
|
88
|
-
`Download failed: HTTP ${response.statusCode} for ${url}`
|
|
89
|
-
)
|
|
90
|
-
);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
response.pipe(file);
|
|
95
|
-
file.on('finish', () => {
|
|
96
|
-
file.close(resolve);
|
|
97
|
-
});
|
|
98
|
-
})
|
|
99
|
-
.on('error', (err) => {
|
|
100
|
-
fs.unlink(dest, () => {});
|
|
101
|
-
reject(err);
|
|
102
|
-
})
|
|
103
|
-
.on('timeout', () => {
|
|
104
|
-
fs.unlink(dest, () => {});
|
|
105
|
-
reject(new Error('Download timeout'));
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function extractArchive(archivePath, destDir) {
|
|
111
|
-
const ext = path.extname(archivePath);
|
|
112
|
-
const isWindows = os.platform() === 'win32';
|
|
113
|
-
|
|
114
|
-
if (archivePath.endsWith('.zip')) {
|
|
115
|
-
// Use PowerShell on Windows, unzip elsewhere
|
|
116
|
-
if (isWindows) {
|
|
117
|
-
execSync(
|
|
118
|
-
`powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force"`,
|
|
119
|
-
{ stdio: 'inherit' }
|
|
120
|
-
);
|
|
121
|
-
} else {
|
|
122
|
-
execSync(`unzip -q -o "${archivePath}" -d "${destDir}"`, {
|
|
123
|
-
stdio: 'inherit',
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
} else if (archivePath.endsWith('.tar.gz')) {
|
|
127
|
-
execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, {
|
|
128
|
-
stdio: 'inherit',
|
|
129
|
-
});
|
|
130
|
-
} else {
|
|
131
|
-
throw new Error(`Unknown archive format: ${archivePath}`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function findBinary(extractDir) {
|
|
136
|
-
const binaryName = os.platform() === 'win32' ? 'jsn.exe' : 'jsn';
|
|
137
|
-
|
|
138
|
-
// The archive contains just the binary directly
|
|
139
|
-
const directPath = path.join(extractDir, binaryName);
|
|
140
|
-
if (fs.existsSync(directPath)) {
|
|
141
|
-
return directPath;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Sometimes archives have nested directories
|
|
145
|
-
const entries = fs.readdirSync(extractDir);
|
|
146
|
-
for (const entry of entries) {
|
|
147
|
-
const entryPath = path.join(extractDir, entry);
|
|
148
|
-
const stat = fs.statSync(entryPath);
|
|
149
|
-
if (stat.isDirectory()) {
|
|
150
|
-
const nestedPath = path.join(entryPath, binaryName);
|
|
151
|
-
if (fs.existsSync(nestedPath)) {
|
|
152
|
-
return nestedPath;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
throw new Error(
|
|
158
|
-
`Could not find ${binaryName} in extracted archive. Contents: ${entries.join(', ')}`
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
async function main() {
|
|
163
|
-
// Skip if running in development (from git repo)
|
|
164
|
-
if (fs.existsSync(path.join(__dirname, '..', 'go.mod'))) {
|
|
165
|
-
console.log('Development environment detected. Skipping binary download.');
|
|
166
|
-
console.log('Build the binary manually: go build ./cmd/jsn');
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const { platform, arch } = detectPlatform();
|
|
171
|
-
const version = getVersion();
|
|
172
|
-
|
|
173
|
-
// Development placeholder version
|
|
174
|
-
if (version === '0.0.0') {
|
|
175
|
-
console.log('Warning: version is 0.0.0, skipping binary download.');
|
|
176
|
-
console.log('This is expected when installing from source.');
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const ext = platform === 'windows' ? 'zip' : 'tar.gz';
|
|
181
|
-
const filename = `jsn_v${version}_${platform}_${arch}.${ext}`;
|
|
182
|
-
const url = `https://github.com/${REPO}/releases/download/v${version}/${filename}`;
|
|
183
|
-
|
|
184
|
-
console.log(`Downloading JSN v${version} for ${platform}/${arch}...`);
|
|
185
|
-
console.log(` ${url}`);
|
|
186
|
-
|
|
187
|
-
// Ensure binary directory exists
|
|
188
|
-
if (!fs.existsSync(BINARY_DIR)) {
|
|
189
|
-
fs.mkdirSync(BINARY_DIR, { recursive: true });
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jsn-install-'));
|
|
193
|
-
const archivePath = path.join(tmpDir, filename);
|
|
194
|
-
|
|
195
|
-
try {
|
|
196
|
-
await downloadFile(url, archivePath);
|
|
197
|
-
console.log('Extracting...');
|
|
198
|
-
extractArchive(archivePath, tmpDir);
|
|
199
|
-
|
|
200
|
-
const extractedBinary = findBinary(tmpDir);
|
|
201
|
-
const binaryName = platform === 'windows' ? 'jsn.exe' : 'jsn';
|
|
202
|
-
const finalPath = path.join(BINARY_DIR, binaryName);
|
|
203
|
-
|
|
204
|
-
// Move binary to final location
|
|
205
|
-
fs.copyFileSync(extractedBinary, finalPath);
|
|
206
|
-
|
|
207
|
-
// Make executable on Unix
|
|
208
|
-
if (platform !== 'windows') {
|
|
209
|
-
fs.chmodSync(finalPath, 0o755);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
console.log(`Installed JSN binary to ${finalPath}`);
|
|
213
|
-
} catch (err) {
|
|
214
|
-
console.error(`Error: ${err.message}`);
|
|
215
|
-
console.error('');
|
|
216
|
-
console.error('Failed to download the JSN binary.');
|
|
217
|
-
console.error('You can still use the CLI if you have a binary installed manually.');
|
|
218
|
-
console.error('Download from: https://github.com/jacebenson/jsn/releases');
|
|
219
|
-
|
|
220
|
-
// Don't fail the npm install — the user can fix this later
|
|
221
|
-
process.exit(0);
|
|
222
|
-
} finally {
|
|
223
|
-
// Cleanup temp directory
|
|
224
|
-
try {
|
|
225
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
226
|
-
} catch {
|
|
227
|
-
// Ignore cleanup errors
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
main().catch((err) => {
|
|
233
|
-
console.error(`Unexpected error: ${err.message}`);
|
|
234
|
-
process.exit(0); // Don't fail npm install
|
|
235
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# pre-commit-check.sh - Run this before committing to check architecture compliance
|
|
3
|
-
|
|
4
|
-
echo "🔍 Checking architecture patterns..."
|
|
5
|
-
|
|
6
|
-
# Check for forbidden SDK patterns
|
|
7
|
-
FORBIDDEN_PATTERNS=(
|
|
8
|
-
"func.*Client.*ListForm"
|
|
9
|
-
"func.*Client.*ListList"
|
|
10
|
-
"func.*Client.*GetSP"
|
|
11
|
-
"func.*Client.*ListSP"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
ERRORS=0
|
|
15
|
-
|
|
16
|
-
for pattern in "${FORBIDDEN_PATTERNS[@]}"; do
|
|
17
|
-
matches=$(grep -r "$pattern" internal/sdk/*.go 2>/dev/null | grep -v "_test.go" | grep -v "^Binary")
|
|
18
|
-
if [ ! -z "$matches" ]; then
|
|
19
|
-
echo "❌ Found forbidden SDK pattern: $pattern"
|
|
20
|
-
echo "$matches"
|
|
21
|
-
ERRORS=$((ERRORS + 1))
|
|
22
|
-
fi
|
|
23
|
-
done
|
|
24
|
-
|
|
25
|
-
# Check that commands don't import old SDK types
|
|
26
|
-
BAD_IMPORTS=(
|
|
27
|
-
"sdk.FormSection"
|
|
28
|
-
"sdk.FormElement"
|
|
29
|
-
"sdk.ListLayout"
|
|
30
|
-
"sdk.ListElement"
|
|
31
|
-
"sdk.SPPage"
|
|
32
|
-
"sdk.SPWidgetInstance"
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
for pattern in "${BAD_IMPORTS[@]}"; do
|
|
36
|
-
matches=$(grep -r "$pattern" internal/commands/**/*.go 2>/dev/null)
|
|
37
|
-
if [ ! -z "$matches" ]; then
|
|
38
|
-
echo "❌ Command using SDK type instead of local type: $pattern"
|
|
39
|
-
echo "$matches"
|
|
40
|
-
ERRORS=$((ERRORS + 1))
|
|
41
|
-
fi
|
|
42
|
-
done
|
|
43
|
-
|
|
44
|
-
# Run architecture tests
|
|
45
|
-
echo "🧪 Running architecture tests..."
|
|
46
|
-
if ! go test ./internal/sdk -run TestNoSDKHelperMethods -run TestCommandsUseDirectSDKList > /dev/null 2>&1; then
|
|
47
|
-
echo "❌ Architecture tests failed"
|
|
48
|
-
go test ./internal/sdk -v -run "TestNoSDKHelperMethods|TestCommandsUseDirectSDKList"
|
|
49
|
-
ERRORS=$((ERRORS + 1))
|
|
50
|
-
fi
|
|
51
|
-
|
|
52
|
-
if [ $ERRORS -eq 0 ]; then
|
|
53
|
-
echo "✅ All architecture checks passed!"
|
|
54
|
-
exit 0
|
|
55
|
-
else
|
|
56
|
-
echo ""
|
|
57
|
-
echo "⚠️ Architecture violations found!"
|
|
58
|
-
echo " Remember: Commands should call app.SDK.List() directly with local types."
|
|
59
|
-
echo " See internal/commands/dev/forms.go for the correct pattern."
|
|
60
|
-
exit 1
|
|
61
|
-
fi
|