@hasna/microservices 0.0.21 → 0.0.22
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/bin/index.js +130 -28
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -1875,6 +1875,7 @@ var require_commander = __commonJS((exports) => {
|
|
|
1875
1875
|
// src/cli/index.tsx
|
|
1876
1876
|
import fs from "fs";
|
|
1877
1877
|
import path from "path";
|
|
1878
|
+
import { createInterface } from "readline/promises";
|
|
1878
1879
|
|
|
1879
1880
|
// node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
1880
1881
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -2985,17 +2986,58 @@ async function runMicroserviceCommand(name, args, timeout = 30000) {
|
|
|
2985
2986
|
|
|
2986
2987
|
// src/cli/index.tsx
|
|
2987
2988
|
var program2 = new Command;
|
|
2989
|
+
function printJson(value) {
|
|
2990
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
2991
|
+
`);
|
|
2992
|
+
}
|
|
2988
2993
|
program2.name("microservices").description("Production-grade microservice building blocks for SaaS apps").version(getPackageVersion());
|
|
2989
|
-
program2.command("list").description("List all available microservices").option("--installed", "Show only installed microservices").action((opts) => {
|
|
2990
|
-
const
|
|
2994
|
+
program2.command("list").description("List all available microservices").option("--installed", "Show only installed microservices").option("--category <name>", "Filter by category (case-insensitive)").option("--limit <n>", "Limit number of results").option("--offset <n>", "Skip the first N results").option("--json", "Print machine-readable JSON output").action((opts) => {
|
|
2995
|
+
const limit = opts.limit === undefined ? null : Number(opts.limit);
|
|
2996
|
+
const offset = opts.offset === undefined ? 0 : Number(opts.offset);
|
|
2997
|
+
if (limit !== null && (!Number.isInteger(limit) || limit < 0)) {
|
|
2998
|
+
console.error(source_default.red("--limit must be a non-negative integer"));
|
|
2999
|
+
process.exit(1);
|
|
3000
|
+
}
|
|
3001
|
+
if (!Number.isInteger(offset) || offset < 0) {
|
|
3002
|
+
console.error(source_default.red("--offset must be a non-negative integer"));
|
|
3003
|
+
process.exit(1);
|
|
3004
|
+
}
|
|
3005
|
+
const categoryFilter = opts.category?.trim().toLowerCase();
|
|
3006
|
+
let services = opts.installed ? MICROSERVICES.filter((m) => microserviceExists(m.name)) : MICROSERVICES;
|
|
3007
|
+
if (categoryFilter) {
|
|
3008
|
+
services = services.filter((m) => m.category.toLowerCase() === categoryFilter);
|
|
3009
|
+
}
|
|
3010
|
+
const start = offset;
|
|
3011
|
+
const end = limit === null ? undefined : offset + limit;
|
|
3012
|
+
const page = services.slice(start, end);
|
|
3013
|
+
const payload = page.map((m) => ({
|
|
3014
|
+
name: m.name,
|
|
3015
|
+
displayName: m.displayName,
|
|
3016
|
+
binary: m.binary,
|
|
3017
|
+
package: m.package,
|
|
3018
|
+
category: m.category,
|
|
3019
|
+
installed: microserviceExists(m.name),
|
|
3020
|
+
description: m.description
|
|
3021
|
+
}));
|
|
3022
|
+
if (opts.json) {
|
|
3023
|
+
printJson({
|
|
3024
|
+
total: services.length,
|
|
3025
|
+
count: payload.length,
|
|
3026
|
+
offset,
|
|
3027
|
+
limit,
|
|
3028
|
+
category: opts.category ?? null,
|
|
3029
|
+
services: payload
|
|
3030
|
+
});
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
2991
3033
|
console.log(source_default.bold(`
|
|
2992
3034
|
Available microservices:
|
|
2993
3035
|
`));
|
|
2994
|
-
for (const m of
|
|
2995
|
-
const
|
|
2996
|
-
const status = installed ? source_default.green("\u2713 installed") : source_default.gray(" available");
|
|
3036
|
+
for (const m of payload) {
|
|
3037
|
+
const status = m.installed ? source_default.green("\u2713 installed") : source_default.gray(" available");
|
|
2997
3038
|
console.log(` ${status} ${source_default.cyan(m.binary.padEnd(22))} ${m.description.slice(0, 60)}`);
|
|
2998
3039
|
}
|
|
3040
|
+
console.log(source_default.gray(`Showing ${payload.length} of ${services.length} result(s) (offset ${offset}${limit === null ? "" : `, limit ${limit}`}).`));
|
|
2999
3041
|
console.log();
|
|
3000
3042
|
});
|
|
3001
3043
|
program2.command("install [names...]").description("Install microservices globally via bun").option("--all", "Install all microservices").option("--force", "Reinstall even if already installed").action(async (names, opts) => {
|
|
@@ -3017,20 +3059,44 @@ Installing ${targets.length} microservice(s)...
|
|
|
3017
3059
|
}
|
|
3018
3060
|
console.log();
|
|
3019
3061
|
});
|
|
3020
|
-
program2.command("remove <name>").description("Remove an installed microservice").action((name) => {
|
|
3062
|
+
program2.command("remove <name>").description("Remove an installed microservice").option("-y, --yes", "Skip confirmation prompt").action(async (name, opts) => {
|
|
3063
|
+
if (!opts.yes) {
|
|
3064
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
3065
|
+
console.error(source_default.red("Refusing to remove without confirmation in non-interactive mode. Re-run with --yes."));
|
|
3066
|
+
process.exit(1);
|
|
3067
|
+
}
|
|
3068
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
3069
|
+
try {
|
|
3070
|
+
const answer = await rl.question(`Remove ${name} from your global Bun installation? [y/N] `);
|
|
3071
|
+
const confirmed = ["y", "yes"].includes(answer.trim().toLowerCase());
|
|
3072
|
+
if (!confirmed) {
|
|
3073
|
+
console.log(source_default.yellow("Cancelled."));
|
|
3074
|
+
process.exit(1);
|
|
3075
|
+
}
|
|
3076
|
+
} finally {
|
|
3077
|
+
rl.close();
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3021
3080
|
const ok = removeMicroservice(name);
|
|
3022
|
-
if (ok)
|
|
3081
|
+
if (ok) {
|
|
3023
3082
|
console.log(source_default.green(`\u2713 Removed ${name}`));
|
|
3024
|
-
|
|
3025
|
-
|
|
3083
|
+
return;
|
|
3084
|
+
}
|
|
3085
|
+
console.error(source_default.red(`\u2717 Failed to remove ${name} \u2014 is it installed?`));
|
|
3086
|
+
process.exit(1);
|
|
3026
3087
|
});
|
|
3027
|
-
program2.command("status [name]").description("Show installation status").action((name) => {
|
|
3088
|
+
program2.command("status [name]").description("Show installation status").option("--json", "Print machine-readable JSON output").action((name, opts) => {
|
|
3028
3089
|
const targets = name ? [name] : MICROSERVICES.map((m) => m.name);
|
|
3090
|
+
const payload = targets.map((n) => getMicroserviceStatus(n));
|
|
3091
|
+
if (opts.json) {
|
|
3092
|
+
printJson(name ? payload[0] ?? null : payload);
|
|
3093
|
+
return;
|
|
3094
|
+
}
|
|
3029
3095
|
console.log(source_default.bold(`
|
|
3030
3096
|
Microservice status:
|
|
3031
3097
|
`));
|
|
3032
|
-
for (const n of targets) {
|
|
3033
|
-
const s =
|
|
3098
|
+
for (const [index, n] of targets.entries()) {
|
|
3099
|
+
const s = payload[index];
|
|
3034
3100
|
const icon = s.installed ? source_default.green("\u2713") : source_default.gray("\u2717");
|
|
3035
3101
|
const ver = s.version ? source_default.gray(`v${s.version}`) : "";
|
|
3036
3102
|
const env2 = s.meta?.requiredEnv.join(", ") ?? "";
|
|
@@ -3048,8 +3114,12 @@ program2.command("run <name> [args...]").description("Run a command on an instal
|
|
|
3048
3114
|
`);
|
|
3049
3115
|
process.exit(result.exitCode);
|
|
3050
3116
|
});
|
|
3051
|
-
program2.command("search <query>").description("Search microservices by name or keyword").action((query) => {
|
|
3117
|
+
program2.command("search <query>").description("Search microservices by name or keyword").option("--json", "Print machine-readable JSON output").action((query, opts) => {
|
|
3052
3118
|
const results = searchMicroservices(query);
|
|
3119
|
+
if (opts.json) {
|
|
3120
|
+
printJson(results);
|
|
3121
|
+
return;
|
|
3122
|
+
}
|
|
3053
3123
|
if (results.length === 0) {
|
|
3054
3124
|
console.log(source_default.gray(`No microservices matching "${query}"`));
|
|
3055
3125
|
return;
|
|
@@ -3183,13 +3253,17 @@ Initializing ${installed.length} installed microservices...
|
|
|
3183
3253
|
console.log(source_default.gray(" You can now run 'microservices serve-all' to start them."));
|
|
3184
3254
|
}
|
|
3185
3255
|
});
|
|
3186
|
-
program2.command("info <name>").description("Show detailed info about a microservice").action((name) => {
|
|
3256
|
+
program2.command("info <name>").description("Show detailed info about a microservice").option("--json", "Print machine-readable JSON output").action((name, opts) => {
|
|
3187
3257
|
const m = getMicroservice(name);
|
|
3188
3258
|
if (!m) {
|
|
3189
3259
|
console.error(source_default.red(`Unknown microservice: ${name}`));
|
|
3190
3260
|
process.exit(1);
|
|
3191
3261
|
}
|
|
3192
3262
|
const installed = microserviceExists(name);
|
|
3263
|
+
if (opts.json) {
|
|
3264
|
+
printJson({ ...m, installed });
|
|
3265
|
+
return;
|
|
3266
|
+
}
|
|
3193
3267
|
console.log(source_default.bold(`
|
|
3194
3268
|
${m.displayName}`));
|
|
3195
3269
|
console.log(` Package: ${source_default.cyan(m.package)}`);
|
|
@@ -3204,29 +3278,57 @@ ${m.displayName}`));
|
|
|
3204
3278
|
console.log(` Tags: ${m.tags.join(", ")}`);
|
|
3205
3279
|
console.log();
|
|
3206
3280
|
});
|
|
3207
|
-
program2.command("check-env").description("Verify environment variables for all installed microservices").action(() => {
|
|
3281
|
+
program2.command("check-env").description("Verify environment variables for all installed microservices").option("--json", "Print machine-readable JSON output").action((opts) => {
|
|
3208
3282
|
const installed = MICROSERVICES.filter((m) => microserviceExists(m.name));
|
|
3209
3283
|
if (installed.length === 0) {
|
|
3210
|
-
|
|
3284
|
+
if (opts.json) {
|
|
3285
|
+
printJson({
|
|
3286
|
+
summary: { installed: 0, totalMissingRequired: 0, allOk: true },
|
|
3287
|
+
services: []
|
|
3288
|
+
});
|
|
3289
|
+
} else {
|
|
3290
|
+
console.log(source_default.yellow("No microservices installed to check."));
|
|
3291
|
+
}
|
|
3292
|
+
return;
|
|
3293
|
+
}
|
|
3294
|
+
const report = installed.map((m) => {
|
|
3295
|
+
const missingRequired = m.requiredEnv.filter((env2) => !process.env[env2]);
|
|
3296
|
+
const missingOptional = (m.optionalEnv ?? []).filter((env2) => !process.env[env2]);
|
|
3297
|
+
return {
|
|
3298
|
+
name: m.name,
|
|
3299
|
+
missingRequired,
|
|
3300
|
+
missingOptional,
|
|
3301
|
+
ok: missingRequired.length === 0
|
|
3302
|
+
};
|
|
3303
|
+
});
|
|
3304
|
+
const totalMissing = report.reduce((sum, service) => sum + service.missingRequired.length, 0);
|
|
3305
|
+
if (opts.json) {
|
|
3306
|
+
printJson({
|
|
3307
|
+
summary: {
|
|
3308
|
+
installed: installed.length,
|
|
3309
|
+
totalMissingRequired: totalMissing,
|
|
3310
|
+
allOk: totalMissing === 0
|
|
3311
|
+
},
|
|
3312
|
+
services: report
|
|
3313
|
+
});
|
|
3314
|
+
if (totalMissing > 0) {
|
|
3315
|
+
process.exit(1);
|
|
3316
|
+
}
|
|
3211
3317
|
return;
|
|
3212
3318
|
}
|
|
3213
3319
|
console.log(source_default.bold(`
|
|
3214
3320
|
Checking environment for ${installed.length} microservices...
|
|
3215
3321
|
`));
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
console.log(`${source_default.bold(m.name.padEnd(12))} [${status}]`);
|
|
3222
|
-
if (missingRequired.length > 0) {
|
|
3223
|
-
console.log(source_default.red(` Required missing: ${missingRequired.join(", ")}`));
|
|
3224
|
-
totalMissing += missingRequired.length;
|
|
3322
|
+
for (const service of report) {
|
|
3323
|
+
const status = service.missingRequired.length > 0 ? source_default.red("\u2717 Critical Missing") : service.missingOptional.length > 0 ? source_default.yellow("\u26A0 Warning") : source_default.green("\u2713 OK");
|
|
3324
|
+
console.log(`${source_default.bold(service.name.padEnd(12))} [${status}]`);
|
|
3325
|
+
if (service.missingRequired.length > 0) {
|
|
3326
|
+
console.log(source_default.red(` Required missing: ${service.missingRequired.join(", ")}`));
|
|
3225
3327
|
}
|
|
3226
|
-
if (missingOptional.length > 0) {
|
|
3227
|
-
console.log(source_default.gray(` Optional missing: ${missingOptional.join(", ")}`));
|
|
3328
|
+
if (service.missingOptional.length > 0) {
|
|
3329
|
+
console.log(source_default.gray(` Optional missing: ${service.missingOptional.join(", ")}`));
|
|
3228
3330
|
}
|
|
3229
|
-
if (missingRequired.length === 0 && missingOptional.length === 0) {
|
|
3331
|
+
if (service.missingRequired.length === 0 && service.missingOptional.length === 0) {
|
|
3230
3332
|
console.log(source_default.gray(" All variables set."));
|
|
3231
3333
|
}
|
|
3232
3334
|
console.log();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/microservices",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "21 production-grade microservice building blocks for AI-native SaaS — auth, billing, LLM gateway, agent registry, RAG, guardrails, tracing, and more. Each with PostgreSQL, HTTP API, MCP server, and CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|