certops 1.0.16 → 1.1.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.
@@ -7,7 +7,13 @@ import { domainHookPath, GLOBAL_HOOK } from '../../hooks.js';
7
7
  import { BRAND } from '../../brand.js';
8
8
  const UNIT_PATH = `/etc/systemd/system/${BRAND.serviceUnit}.service`;
9
9
  const API_KEY_ENV = `${BRAND.envPrefix}_API_KEY`;
10
+ function resolveBinPath() {
11
+ // process.argv[1] is the actual path of the running certops script
12
+ return process.argv[1] ?? `/usr/local/bin/${BRAND.binName}`;
13
+ }
10
14
  function buildUnitContent(apiKey) {
15
+ const binPath = resolveBinPath();
16
+ const nodePath = process.execPath;
11
17
  return `\
12
18
  [Unit]
13
19
  Description=${BRAND.displayName} Certificate Monitor
@@ -17,7 +23,7 @@ Wants=network-online.target
17
23
  [Service]
18
24
  Type=simple
19
25
  Environment=${API_KEY_ENV}=${apiKey}
20
- ExecStart=/usr/local/bin/${BRAND.binName} service run
26
+ ExecStart=${nodePath} ${binPath} service run
21
27
  Restart=on-failure
22
28
  RestartSec=30
23
29
  StandardOutput=journal
package/dist/version.js CHANGED
@@ -1,18 +1,19 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- function isPackageJson(value) {
5
- return (typeof value === 'object' &&
6
- value !== null &&
7
- 'version' in value &&
8
- typeof value.version === 'string');
9
- }
10
4
  function readCliVersion() {
11
- const dir = dirname(fileURLToPath(import.meta.url));
12
- const path = join(dir, '..', 'package.json');
13
- const raw = JSON.parse(readFileSync(path, 'utf8'));
14
- if (!isPackageJson(raw))
15
- throw new Error('package.json is missing a valid version field');
16
- return raw.version;
5
+ // Injected at compile time by Bun build --define
6
+ if (process.env.CLI_VERSION)
7
+ return process.env.CLI_VERSION;
8
+ // JS mode (npm package with dist/): read from package.json
9
+ try {
10
+ const dir = dirname(fileURLToPath(import.meta.url));
11
+ const path = join(dir, '..', 'package.json');
12
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
13
+ return raw.version;
14
+ }
15
+ catch {
16
+ return '0.0.0';
17
+ }
17
18
  }
18
19
  export const CLI_VERSION = readCliVersion();
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "certops",
3
- "version": "1.0.16",
3
+ "version": "1.1.0",
4
4
  "description": "SSL Pilot CLI — download and manage your SSL certificates",
5
5
  "type": "module",
6
6
  "files": [
7
- "dist"
7
+ "dist",
8
+ "scripts"
8
9
  ],
9
10
  "bin": {
10
11
  "certops": "./dist/index.js"
@@ -12,7 +13,9 @@
12
13
  "scripts": {
13
14
  "build": "tsc",
14
15
  "dev": "tsx src/index.ts",
15
- "typecheck": "tsc --noEmit"
16
+ "typecheck": "tsc --noEmit",
17
+ "postinstall": "node scripts/postinstall.cjs",
18
+ "preuninstall": "node scripts/preuninstall.cjs"
16
19
  },
17
20
  "publishConfig": {
18
21
  "access": "public"
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ const { createWriteStream, chmodSync, existsSync, unlinkSync } = require('fs')
5
+ const { get } = require('https')
6
+ const { join } = require('path')
7
+
8
+ const { name, version } = require('../package.json')
9
+ const REPO = 'Vimosoftdev/ssl-checker-web'
10
+ const BIN_NAME = 'certops'
11
+ const INSTALL_DIR = '/usr/local/bin'
12
+ const INSTALL_PATH = join(INSTALL_DIR, BIN_NAME)
13
+
14
+ const platformMap = { linux: 'linux', darwin: 'darwin' }
15
+ const archMap = { x64: 'x64', arm64: 'arm64' }
16
+ const plat = platformMap[process.platform]
17
+ const arc = archMap[process.arch]
18
+
19
+ if (!plat || !arc) {
20
+ console.warn(`[certops] Unsupported platform ${process.platform}-${process.arch}. Skipping binary install.`)
21
+ console.warn(`[certops] Install manually: https://github.com/${REPO}/releases/latest`)
22
+ process.exit(0)
23
+ }
24
+
25
+ const isRoot = typeof process.getuid === 'function' && process.getuid() === 0
26
+
27
+ if (!isRoot) {
28
+ console.warn(`[certops] Not running as root — binary not installed to ${INSTALL_PATH}.`)
29
+ console.warn(`[certops] To install system-wide: sudo npm install -g certops`)
30
+ console.warn(`[certops] Or: curl -fsSL https://github.com/${REPO}/releases/latest/download/install.sh | sudo bash`)
31
+ process.exit(0)
32
+ }
33
+
34
+ const assetName = `${BIN_NAME}-${plat}-${arc}`
35
+ const downloadUrl = `https://github.com/${REPO}/releases/download/v${version}/${assetName}`
36
+
37
+ console.log(`[certops] Installing v${version} binary for ${plat}-${arc}…`)
38
+ console.log(`[certops] Downloading ${downloadUrl}`)
39
+
40
+ downloadFile(downloadUrl, INSTALL_PATH)
41
+ .then(() => {
42
+ chmodSync(INSTALL_PATH, 0o755)
43
+ console.log(`[certops] ✓ Installed to ${INSTALL_PATH}`)
44
+ })
45
+ .catch(err => {
46
+ // clean up partial download
47
+ try { if (existsSync(INSTALL_PATH)) unlinkSync(INSTALL_PATH) } catch {}
48
+ console.error(`[certops] Binary install failed: ${err.message}`)
49
+ console.error(`[certops] Fallback: curl -fsSL https://github.com/${REPO}/releases/latest/download/install.sh | sudo bash`)
50
+ // non-fatal — npm install still succeeds
51
+ process.exit(0)
52
+ })
53
+
54
+ function downloadFile(url, dest) {
55
+ return new Promise((resolve, reject) => {
56
+ function fetch(url) {
57
+ get(url, res => {
58
+ if (res.statusCode === 301 || res.statusCode === 302) {
59
+ return fetch(res.headers.location)
60
+ }
61
+ if (res.statusCode !== 200) {
62
+ return reject(new Error(`HTTP ${res.statusCode} from ${url}`))
63
+ }
64
+ const file = createWriteStream(dest)
65
+ res.pipe(file)
66
+ file.on('finish', () => file.close(resolve))
67
+ file.on('error', err => { unlinkSync(dest); reject(err) })
68
+ }).on('error', reject)
69
+ }
70
+ fetch(url)
71
+ })
72
+ }
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ const { unlinkSync, existsSync } = require('fs')
5
+
6
+ const INSTALL_PATH = '/usr/local/bin/certops'
7
+
8
+ try {
9
+ if (existsSync(INSTALL_PATH)) {
10
+ unlinkSync(INSTALL_PATH)
11
+ console.log(`[certops] ✓ Removed binary from ${INSTALL_PATH}`)
12
+ }
13
+ } catch (err) {
14
+ console.warn(`[certops] Could not remove ${INSTALL_PATH}: ${err.message}`)
15
+ }