bindler 1.1.0 → 1.1.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/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli.ts
4
4
  import { Command } from "commander";
5
- import chalk26 from "chalk";
5
+ import chalk27 from "chalk";
6
6
 
7
7
  // src/commands/new.ts
8
8
  import { existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
@@ -1758,7 +1758,7 @@ async function infoCommand() {
1758
1758
  `));
1759
1759
  console.log(chalk14.white(" Manage multiple projects behind Cloudflare Tunnel"));
1760
1760
  console.log(chalk14.white(" with Nginx and PM2\n"));
1761
- console.log(chalk14.dim(" Version: ") + chalk14.white("1.1.0"));
1761
+ console.log(chalk14.dim(" Version: ") + chalk14.white("1.1.1"));
1762
1762
  console.log(chalk14.dim(" Author: ") + chalk14.white("alfaoz"));
1763
1763
  console.log(chalk14.dim(" License: ") + chalk14.white("MIT"));
1764
1764
  console.log(chalk14.dim(" GitHub: ") + chalk14.cyan("https://github.com/alfaoz/bindler"));
@@ -3094,14 +3094,88 @@ async function completionCommand(shell) {
3094
3094
  }
3095
3095
  }
3096
3096
 
3097
+ // src/lib/update-check.ts
3098
+ import chalk26 from "chalk";
3099
+ import { existsSync as existsSync9, readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
3100
+ import { join as join6 } from "path";
3101
+ import { homedir as homedir3 } from "os";
3102
+ var CHECK_INTERVAL = 24 * 60 * 60 * 1e3;
3103
+ var CACHE_DIR = join6(homedir3(), ".config", "bindler");
3104
+ var CACHE_FILE = join6(CACHE_DIR, ".update-check");
3105
+ function readCache() {
3106
+ try {
3107
+ if (existsSync9(CACHE_FILE)) {
3108
+ return JSON.parse(readFileSync6(CACHE_FILE, "utf-8"));
3109
+ }
3110
+ } catch {
3111
+ }
3112
+ return { lastCheck: 0, latestVersion: null };
3113
+ }
3114
+ function writeCache(data) {
3115
+ try {
3116
+ if (!existsSync9(CACHE_DIR)) {
3117
+ mkdirSync5(CACHE_DIR, { recursive: true });
3118
+ }
3119
+ writeFileSync5(CACHE_FILE, JSON.stringify(data));
3120
+ } catch {
3121
+ }
3122
+ }
3123
+ async function fetchLatestVersion() {
3124
+ try {
3125
+ const controller = new AbortController();
3126
+ const timeout = setTimeout(() => controller.abort(), 3e3);
3127
+ const response = await fetch("https://registry.npmjs.org/bindler/latest", {
3128
+ signal: controller.signal
3129
+ });
3130
+ clearTimeout(timeout);
3131
+ if (!response.ok) return null;
3132
+ const data = await response.json();
3133
+ return data.version || null;
3134
+ } catch {
3135
+ return null;
3136
+ }
3137
+ }
3138
+ function compareVersions(current, latest) {
3139
+ const c = current.split(".").map(Number);
3140
+ const l = latest.split(".").map(Number);
3141
+ for (let i = 0; i < 3; i++) {
3142
+ if ((l[i] || 0) > (c[i] || 0)) return 1;
3143
+ if ((l[i] || 0) < (c[i] || 0)) return -1;
3144
+ }
3145
+ return 0;
3146
+ }
3147
+ async function checkForUpdates() {
3148
+ const cache = readCache();
3149
+ const now = Date.now();
3150
+ if (now - cache.lastCheck < CHECK_INTERVAL) {
3151
+ if (cache.latestVersion && compareVersions("1.1.1", cache.latestVersion) < 0) {
3152
+ showUpdateMessage(cache.latestVersion);
3153
+ }
3154
+ return;
3155
+ }
3156
+ fetchLatestVersion().then((latestVersion) => {
3157
+ writeCache({ lastCheck: now, latestVersion });
3158
+ if (latestVersion && compareVersions("1.1.1", latestVersion) < 0) {
3159
+ showUpdateMessage(latestVersion);
3160
+ }
3161
+ });
3162
+ }
3163
+ function showUpdateMessage(latestVersion) {
3164
+ console.log("");
3165
+ console.log(chalk26.yellow(` Update available: ${"1.1.1"} \u2192 ${latestVersion}`));
3166
+ console.log(chalk26.dim(` Run: npm update -g bindler`));
3167
+ console.log("");
3168
+ }
3169
+
3097
3170
  // src/cli.ts
3098
3171
  var program = new Command();
3099
- program.name("bindler").description("Manage multiple projects behind Cloudflare Tunnel with Nginx and PM2").version("1.0.0");
3100
- program.hook("preAction", () => {
3172
+ program.name("bindler").description("Manage multiple projects behind Cloudflare Tunnel with Nginx and PM2").version("1.1.1");
3173
+ program.hook("preAction", async () => {
3101
3174
  try {
3102
3175
  initConfig();
3103
3176
  } catch (error) {
3104
3177
  }
3178
+ checkForUpdates();
3105
3179
  });
3106
3180
  program.command("new").description("Create and register a new project").option("-n, --name <name>", "Project name").option("-t, --type <type>", "Project type (static or npm)", "static").option("-p, --path <path>", "Project directory path").option("-h, --hostname <hostname>", "Hostname for the project").option("-b, --base-path <path>", "Base path for path-based routing (e.g., /api)").option("--port <port>", "Port number (npm projects only)").option("-s, --start <command>", "Start command (npm projects only)").option("-l, --local", "Local project (skip Cloudflare, use .local hostname)").option("--apply", "Apply nginx config after creating").action(async (options) => {
3107
3181
  await newCommand(options);
@@ -3114,73 +3188,73 @@ program.command("status").description("Show detailed status of all projects").ac
3114
3188
  });
3115
3189
  program.command("start [name]").description("Start an npm project with PM2").option("-a, --all", "Start all npm projects").action(async (name, options) => {
3116
3190
  if (!name && !options.all) {
3117
- console.log(chalk26.red("Usage: bindler start <name> or bindler start --all"));
3118
- console.log(chalk26.dim("\nExamples:"));
3119
- console.log(chalk26.dim(" bindler start myapp"));
3120
- console.log(chalk26.dim(" bindler start --all # start all npm projects"));
3191
+ console.log(chalk27.red("Usage: bindler start <name> or bindler start --all"));
3192
+ console.log(chalk27.dim("\nExamples:"));
3193
+ console.log(chalk27.dim(" bindler start myapp"));
3194
+ console.log(chalk27.dim(" bindler start --all # start all npm projects"));
3121
3195
  process.exit(1);
3122
3196
  }
3123
3197
  await startCommand(name, options);
3124
3198
  });
3125
3199
  program.command("stop [name]").description("Stop an npm project").option("-a, --all", "Stop all npm projects").action(async (name, options) => {
3126
3200
  if (!name && !options.all) {
3127
- console.log(chalk26.red("Usage: bindler stop <name> or bindler stop --all"));
3128
- console.log(chalk26.dim("\nExamples:"));
3129
- console.log(chalk26.dim(" bindler stop myapp"));
3130
- console.log(chalk26.dim(" bindler stop --all # stop all npm projects"));
3201
+ console.log(chalk27.red("Usage: bindler stop <name> or bindler stop --all"));
3202
+ console.log(chalk27.dim("\nExamples:"));
3203
+ console.log(chalk27.dim(" bindler stop myapp"));
3204
+ console.log(chalk27.dim(" bindler stop --all # stop all npm projects"));
3131
3205
  process.exit(1);
3132
3206
  }
3133
3207
  await stopCommand(name, options);
3134
3208
  });
3135
3209
  program.command("restart [name]").description("Restart an npm project").option("-a, --all", "Restart all npm projects").action(async (name, options) => {
3136
3210
  if (!name && !options.all) {
3137
- console.log(chalk26.red("Usage: bindler restart <name> or bindler restart --all"));
3138
- console.log(chalk26.dim("\nExamples:"));
3139
- console.log(chalk26.dim(" bindler restart myapp"));
3140
- console.log(chalk26.dim(" bindler restart --all # restart all npm projects"));
3211
+ console.log(chalk27.red("Usage: bindler restart <name> or bindler restart --all"));
3212
+ console.log(chalk27.dim("\nExamples:"));
3213
+ console.log(chalk27.dim(" bindler restart myapp"));
3214
+ console.log(chalk27.dim(" bindler restart --all # restart all npm projects"));
3141
3215
  process.exit(1);
3142
3216
  }
3143
3217
  await restartCommand(name, options);
3144
3218
  });
3145
3219
  program.command("logs [name]").description("Show logs for an npm project").option("-f, --follow", "Follow log output").option("-l, --lines <n>", "Number of lines to show", "200").action(async (name, options) => {
3146
3220
  if (!name) {
3147
- console.log(chalk26.red("Usage: bindler logs <name>"));
3148
- console.log(chalk26.dim("\nExamples:"));
3149
- console.log(chalk26.dim(" bindler logs myapp"));
3150
- console.log(chalk26.dim(" bindler logs myapp --follow"));
3151
- console.log(chalk26.dim(" bindler logs myapp --lines 500"));
3221
+ console.log(chalk27.red("Usage: bindler logs <name>"));
3222
+ console.log(chalk27.dim("\nExamples:"));
3223
+ console.log(chalk27.dim(" bindler logs myapp"));
3224
+ console.log(chalk27.dim(" bindler logs myapp --follow"));
3225
+ console.log(chalk27.dim(" bindler logs myapp --lines 500"));
3152
3226
  process.exit(1);
3153
3227
  }
3154
3228
  await logsCommand(name, { ...options, lines: parseInt(options.lines, 10) });
3155
3229
  });
3156
3230
  program.command("update [name]").description("Update project configuration").option("-h, --hostname <hostname>", "New hostname").option("--port <port>", "New port number").option("-s, --start <command>", "New start command").option("-p, --path <path>", "New project path").option("-e, --env <vars...>", "Environment variables (KEY=value)").option("--enable", "Enable the project").option("--disable", "Disable the project").action(async (name, options) => {
3157
3231
  if (!name) {
3158
- console.log(chalk26.red("Usage: bindler update <name> [options]"));
3159
- console.log(chalk26.dim("\nExamples:"));
3160
- console.log(chalk26.dim(" bindler update myapp --hostname newapp.example.com"));
3161
- console.log(chalk26.dim(" bindler update myapp --port 4000"));
3162
- console.log(chalk26.dim(" bindler update myapp --disable"));
3232
+ console.log(chalk27.red("Usage: bindler update <name> [options]"));
3233
+ console.log(chalk27.dim("\nExamples:"));
3234
+ console.log(chalk27.dim(" bindler update myapp --hostname newapp.example.com"));
3235
+ console.log(chalk27.dim(" bindler update myapp --port 4000"));
3236
+ console.log(chalk27.dim(" bindler update myapp --disable"));
3163
3237
  process.exit(1);
3164
3238
  }
3165
3239
  await updateCommand(name, options);
3166
3240
  });
3167
3241
  program.command("edit [name]").description("Edit project configuration in $EDITOR").action(async (name) => {
3168
3242
  if (!name) {
3169
- console.log(chalk26.red("Usage: bindler edit <name>"));
3170
- console.log(chalk26.dim("\nOpens the project config in your $EDITOR"));
3171
- console.log(chalk26.dim("\nExample:"));
3172
- console.log(chalk26.dim(" bindler edit myapp"));
3243
+ console.log(chalk27.red("Usage: bindler edit <name>"));
3244
+ console.log(chalk27.dim("\nOpens the project config in your $EDITOR"));
3245
+ console.log(chalk27.dim("\nExample:"));
3246
+ console.log(chalk27.dim(" bindler edit myapp"));
3173
3247
  process.exit(1);
3174
3248
  }
3175
3249
  await editCommand(name);
3176
3250
  });
3177
3251
  program.command("remove [name]").alias("rm").description("Remove a project from registry").option("-f, --force", "Skip confirmation").option("--apply", "Apply nginx config after removing").action(async (name, options) => {
3178
3252
  if (!name) {
3179
- console.log(chalk26.red("Usage: bindler remove <name>"));
3180
- console.log(chalk26.dim("\nExamples:"));
3181
- console.log(chalk26.dim(" bindler remove myapp"));
3182
- console.log(chalk26.dim(" bindler remove myapp --force # skip confirmation"));
3183
- console.log(chalk26.dim(" bindler rm myapp # alias"));
3253
+ console.log(chalk27.red("Usage: bindler remove <name>"));
3254
+ console.log(chalk27.dim("\nExamples:"));
3255
+ console.log(chalk27.dim(" bindler remove myapp"));
3256
+ console.log(chalk27.dim(" bindler remove myapp --force # skip confirmation"));
3257
+ console.log(chalk27.dim(" bindler rm myapp # alias"));
3184
3258
  process.exit(1);
3185
3259
  }
3186
3260
  await removeCommand(name, options);
@@ -3199,10 +3273,10 @@ program.command("info").description("Show bindler information and stats").action
3199
3273
  });
3200
3274
  program.command("check [hostname]").description("Check DNS propagation and HTTP accessibility for a hostname").option("-v, --verbose", "Show verbose output").action(async (hostname, options) => {
3201
3275
  if (!hostname) {
3202
- console.log(chalk26.red("Usage: bindler check <hostname>"));
3203
- console.log(chalk26.dim("\nExamples:"));
3204
- console.log(chalk26.dim(" bindler check myapp.example.com"));
3205
- console.log(chalk26.dim(" bindler check myapp # uses project name"));
3276
+ console.log(chalk27.red("Usage: bindler check <hostname>"));
3277
+ console.log(chalk27.dim("\nExamples:"));
3278
+ console.log(chalk27.dim(" bindler check myapp.example.com"));
3279
+ console.log(chalk27.dim(" bindler check myapp # uses project name"));
3206
3280
  process.exit(1);
3207
3281
  }
3208
3282
  await checkCommand(hostname, options);