@maroonedsoftware/johnny5 0.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.
- package/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/index.d.ts +146 -0
- package/dist/index.js +506 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/docker/index.d.ts +27 -0
- package/dist/integrations/docker/index.js +102 -0
- package/dist/integrations/docker/index.js.map +1 -0
- package/dist/integrations/filesystem/index.d.ts +31 -0
- package/dist/integrations/filesystem/index.js +73 -0
- package/dist/integrations/filesystem/index.js.map +1 -0
- package/dist/integrations/postgres/index.d.ts +24 -0
- package/dist/integrations/postgres/index.js +60 -0
- package/dist/integrations/postgres/index.js.map +1 -0
- package/dist/integrations/redis/index.d.ts +28 -0
- package/dist/integrations/redis/index.js +64 -0
- package/dist/integrations/redis/index.js.map +1 -0
- package/dist/integrations/serverkit/index.d.ts +50 -0
- package/dist/integrations/serverkit/index.js +74 -0
- package/dist/integrations/serverkit/index.js.map +1 -0
- package/dist/integrations/versions/index.d.ts +26 -0
- package/dist/integrations/versions/index.js +56 -0
- package/dist/integrations/versions/index.js.map +1 -0
- package/dist/types-CH7ccr3j.d.ts +119 -0
- package/package.json +113 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/integrations/versions/index.ts
|
|
5
|
+
var nodeVersion = /* @__PURE__ */ __name((options) => ({
|
|
6
|
+
name: `node \u2265 ${options.min}`,
|
|
7
|
+
run: /* @__PURE__ */ __name(async () => {
|
|
8
|
+
const raw = process.versions.node;
|
|
9
|
+
const major = Number(raw.split(".")[0]);
|
|
10
|
+
if (!Number.isFinite(major) || major < options.min) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
message: `running on Node ${raw}; need \u2265 ${options.min}`,
|
|
14
|
+
fixHint: `Install Node ${options.min}+ (e.g. \`fnm install ${options.min}\` or \`nvm install ${options.min}\`).`
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
ok: true,
|
|
19
|
+
message: `Node ${raw}`
|
|
20
|
+
};
|
|
21
|
+
}, "run")
|
|
22
|
+
}), "nodeVersion");
|
|
23
|
+
var pnpmVersion = /* @__PURE__ */ __name((options = {}) => ({
|
|
24
|
+
name: "pnpm version",
|
|
25
|
+
run: /* @__PURE__ */ __name(async (ctx) => {
|
|
26
|
+
let installed;
|
|
27
|
+
try {
|
|
28
|
+
const result = await ctx.shell.run("pnpm", [
|
|
29
|
+
"--version"
|
|
30
|
+
]);
|
|
31
|
+
installed = String(result.stdout).trim();
|
|
32
|
+
} catch {
|
|
33
|
+
return {
|
|
34
|
+
ok: false,
|
|
35
|
+
message: "pnpm not found on PATH",
|
|
36
|
+
fixHint: "Install pnpm via corepack: `corepack enable && corepack prepare pnpm@latest --activate`."
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (options.expected && installed !== options.expected) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
message: `pnpm ${installed}; expected ${options.expected}`,
|
|
43
|
+
fixHint: `Run \`corepack prepare pnpm@${options.expected} --activate\` to match.`
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
ok: true,
|
|
48
|
+
message: `pnpm ${installed}`
|
|
49
|
+
};
|
|
50
|
+
}, "run")
|
|
51
|
+
}), "pnpmVersion");
|
|
52
|
+
export {
|
|
53
|
+
nodeVersion,
|
|
54
|
+
pnpmVersion
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/integrations/versions/index.ts"],"sourcesContent":["import type { Check } from '../../types.js';\n\n/** Options for `nodeVersion`. */\nexport interface NodeVersionOptions {\n /** Minimum Node major version required. The check fails when `process.versions.node` is below this. */\n min: number;\n}\n\n/** Check that `process.versions.node` is at least `options.min` (compared by major version). */\nexport const nodeVersion = (options: NodeVersionOptions): Check => ({\n name: `node ≥ ${options.min}`,\n run: async () => {\n const raw = process.versions.node;\n const major = Number(raw.split('.')[0]);\n if (!Number.isFinite(major) || major < options.min) {\n return {\n ok: false,\n message: `running on Node ${raw}; need ≥ ${options.min}`,\n fixHint: `Install Node ${options.min}+ (e.g. \\`fnm install ${options.min}\\` or \\`nvm install ${options.min}\\`).`,\n };\n }\n return { ok: true, message: `Node ${raw}` };\n },\n});\n\n/** Options for `pnpmVersion`. */\nexport interface PnpmVersionOptions {\n /**\n * If supplied, the installed pnpm version must match exactly. Otherwise\n * only presence on PATH is checked.\n */\n expected?: string;\n}\n\n/**\n * Check that pnpm is on PATH and (optionally) matches a specific version. Fails\n * with a corepack-flavoured fixHint when the binary is missing or mismatched.\n */\nexport const pnpmVersion = (options: PnpmVersionOptions = {}): Check => ({\n name: 'pnpm version',\n run: async ctx => {\n let installed: string;\n try {\n const result = await ctx.shell.run('pnpm', ['--version']);\n installed = String(result.stdout).trim();\n } catch {\n return {\n ok: false,\n message: 'pnpm not found on PATH',\n fixHint: 'Install pnpm via corepack: `corepack enable && corepack prepare pnpm@latest --activate`.',\n };\n }\n if (options.expected && installed !== options.expected) {\n return {\n ok: false,\n message: `pnpm ${installed}; expected ${options.expected}`,\n fixHint: `Run \\`corepack prepare pnpm@${options.expected} --activate\\` to match.`,\n };\n }\n return { ok: true, message: `pnpm ${installed}` };\n },\n});\n"],"mappings":";;;;AASO,IAAMA,cAAc,wBAACC,aAAwC;EAChEC,MAAM,eAAUD,QAAQE,GAAG;EAC3BC,KAAK,mCAAA;AACD,UAAMC,MAAMC,QAAQC,SAASC;AAC7B,UAAMC,QAAQC,OAAOL,IAAIM,MAAM,GAAA,EAAK,CAAA,CAAE;AACtC,QAAI,CAACD,OAAOE,SAASH,KAAAA,KAAUA,QAAQR,QAAQE,KAAK;AAChD,aAAO;QACHU,IAAI;QACJC,SAAS,mBAAmBT,GAAAA,iBAAeJ,QAAQE,GAAG;QACtDY,SAAS,gBAAgBd,QAAQE,GAAG,yBAAyBF,QAAQE,GAAG,uBAAuBF,QAAQE,GAAG;MAC9G;IACJ;AACA,WAAO;MAAEU,IAAI;MAAMC,SAAS,QAAQT,GAAAA;IAAM;EAC9C,GAXK;AAYT,IAd2B;AA6BpB,IAAMW,cAAc,wBAACf,UAA8B,CAAC,OAAc;EACrEC,MAAM;EACNE,KAAK,8BAAMa,QAAAA;AACP,QAAIC;AACJ,QAAI;AACA,YAAMC,SAAS,MAAMF,IAAIG,MAAMhB,IAAI,QAAQ;QAAC;OAAY;AACxDc,kBAAYG,OAAOF,OAAOG,MAAM,EAAEC,KAAI;IAC1C,QAAQ;AACJ,aAAO;QACHV,IAAI;QACJC,SAAS;QACTC,SAAS;MACb;IACJ;AACA,QAAId,QAAQuB,YAAYN,cAAcjB,QAAQuB,UAAU;AACpD,aAAO;QACHX,IAAI;QACJC,SAAS,QAAQI,SAAAA,cAAuBjB,QAAQuB,QAAQ;QACxDT,SAAS,+BAA+Bd,QAAQuB,QAAQ;MAC5D;IACJ;AACA,WAAO;MAAEX,IAAI;MAAMC,SAAS,QAAQI,SAAAA;IAAY;EACpD,GApBK;AAqBT,IAvB2B;","names":["nodeVersion","options","name","min","run","raw","process","versions","node","major","Number","split","isFinite","ok","message","fixHint","pnpmVersion","ctx","installed","result","shell","String","stdout","trim","expected"]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AppConfig } from '@maroonedsoftware/appconfig';
|
|
2
|
+
import { Options, ResultPromise } from 'execa';
|
|
3
|
+
|
|
4
|
+
/** Minimal logger interface that every command and check receives via `CliContext`. */
|
|
5
|
+
interface CliLogger {
|
|
6
|
+
info: (msg: string) => void;
|
|
7
|
+
warn: (msg: string) => void;
|
|
8
|
+
error: (msg: string) => void;
|
|
9
|
+
debug: (msg: string) => void;
|
|
10
|
+
success: (msg: string) => void;
|
|
11
|
+
}
|
|
12
|
+
/** Options accepted by `createDefaultLogger`. */
|
|
13
|
+
interface CreateLoggerOptions {
|
|
14
|
+
/** When true, `debug` writes to stdout; otherwise it's a no-op. */
|
|
15
|
+
verbose?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build the default ANSI-coloured console logger used when a consumer doesn't
|
|
19
|
+
* supply their own. `debug` output is gated on `verbose`.
|
|
20
|
+
*/
|
|
21
|
+
declare const createDefaultLogger: (options?: CreateLoggerOptions) => CliLogger;
|
|
22
|
+
|
|
23
|
+
/** Execa options re-typed to require a string `cwd` at the call site. */
|
|
24
|
+
interface ShellOptions extends Options {
|
|
25
|
+
cwd?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Tiny shell wrapper around execa exposed on `CliContext.shell`. */
|
|
28
|
+
interface Shell {
|
|
29
|
+
/** Run a command, returning the execa result promise. Use this when the caller needs stdout/stderr. */
|
|
30
|
+
run: (command: string, args: string[], options?: ShellOptions) => ResultPromise;
|
|
31
|
+
/** Run a command with inherited stdio, returning the exit code. Failures don't throw — the exit code is returned instead. */
|
|
32
|
+
runStreaming: (command: string, args: string[], options?: ShellOptions) => Promise<number>;
|
|
33
|
+
}
|
|
34
|
+
/** Build a `Shell` bound to `cwd`, logging streaming invocations through `logger.debug`. */
|
|
35
|
+
declare const createShell: (cwd: string, logger: CliLogger) => Shell;
|
|
36
|
+
|
|
37
|
+
/** Value-coercion hint for an option declared on a `CommandModule`. */
|
|
38
|
+
type OptionType = 'string' | 'number' | 'boolean';
|
|
39
|
+
/** Declarative description of a single CLI option (flag). */
|
|
40
|
+
interface OptionSpec {
|
|
41
|
+
/** Commander-style flag string, e.g. `'--name <name>'` or `'-n, --name <name>'`. */
|
|
42
|
+
flags: string;
|
|
43
|
+
description: string;
|
|
44
|
+
type?: OptionType;
|
|
45
|
+
default?: string | number | boolean;
|
|
46
|
+
required?: boolean;
|
|
47
|
+
/** Process env var to read the value from when the flag is not supplied on the CLI. */
|
|
48
|
+
envVar?: string;
|
|
49
|
+
}
|
|
50
|
+
/** Declarative description of a single positional argument. */
|
|
51
|
+
interface ArgSpec {
|
|
52
|
+
name: string;
|
|
53
|
+
description: string;
|
|
54
|
+
required?: boolean;
|
|
55
|
+
variadic?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A single CLI command unit. `defineCommand` is the recommended way to create one
|
|
59
|
+
* so TypeScript can infer `Opts` from the literal.
|
|
60
|
+
*/
|
|
61
|
+
interface CommandModule<Opts = Record<string, unknown>> {
|
|
62
|
+
name?: string;
|
|
63
|
+
description: string;
|
|
64
|
+
options?: OptionSpec[];
|
|
65
|
+
args?: ArgSpec[];
|
|
66
|
+
/** Optional hook that runs *after* CLI parsing but *before* `run`, only when stdin/stdout are TTYs. Lets a command fill in missing options interactively. */
|
|
67
|
+
interactive?: (ctx: CliContext, partial: Partial<Opts>) => Promise<Opts>;
|
|
68
|
+
/** Returning a non-zero number triggers `process.exit(code)`. `void` / `0` means success. */
|
|
69
|
+
run: (opts: Opts, ctx: CliContext, args: string[]) => Promise<number | void>;
|
|
70
|
+
/** When true, unknown options and excess positional args are forwarded to `run` verbatim instead of triggering commander errors. */
|
|
71
|
+
passthrough?: boolean;
|
|
72
|
+
}
|
|
73
|
+
/** A `CommandModule` plus the path under which it should appear in the CLI tree. */
|
|
74
|
+
interface CommandRegistration {
|
|
75
|
+
path: string[];
|
|
76
|
+
module: CommandModule;
|
|
77
|
+
}
|
|
78
|
+
/** A `CommandRegistration` tagged with where it came from — used by the registrar to detect collisions and produce useful error messages. */
|
|
79
|
+
interface DiscoveredCommand extends CommandRegistration {
|
|
80
|
+
source: 'core' | 'plugin';
|
|
81
|
+
sourceName?: string;
|
|
82
|
+
}
|
|
83
|
+
/** Shape that a workspace plugin's commands file must default-export to be picked up by `loadWorkspacePlugins`. */
|
|
84
|
+
interface PluginManifest {
|
|
85
|
+
name: string;
|
|
86
|
+
commands: CommandRegistration[];
|
|
87
|
+
}
|
|
88
|
+
/** Outcome of a single doctor check. `fixHint` is rendered when `--fix` is not in play. */
|
|
89
|
+
interface CheckResult {
|
|
90
|
+
ok: boolean;
|
|
91
|
+
message: string;
|
|
92
|
+
fixHint?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* A single doctor check. `run` must always resolve — throws are caught by the
|
|
96
|
+
* runner and rendered as failures. When `autoFix` is supplied and the user passes
|
|
97
|
+
* `--fix`, the runner invokes it for every failing run.
|
|
98
|
+
*/
|
|
99
|
+
interface Check {
|
|
100
|
+
name: string;
|
|
101
|
+
run: (ctx: CliContext) => Promise<CheckResult>;
|
|
102
|
+
autoFix?: (ctx: CliContext) => Promise<CheckResult>;
|
|
103
|
+
}
|
|
104
|
+
/** Filesystem anchors handed to commands. `repoRoot` is the consumer's workspace, not where johnny5 lives. */
|
|
105
|
+
interface CliPaths {
|
|
106
|
+
cwd: string;
|
|
107
|
+
repoRoot: string;
|
|
108
|
+
}
|
|
109
|
+
/** Per-invocation context handed to every command, check, and plugin hook. */
|
|
110
|
+
interface CliContext {
|
|
111
|
+
paths: CliPaths;
|
|
112
|
+
logger: CliLogger;
|
|
113
|
+
shell: Shell;
|
|
114
|
+
config: AppConfig;
|
|
115
|
+
isInteractive: () => boolean;
|
|
116
|
+
env: NodeJS.ProcessEnv;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { type ArgSpec as A, type CliContext as C, type DiscoveredCommand as D, type OptionSpec as O, type PluginManifest as P, type Shell as S, type CommandRegistration as a, type Check as b, type CliLogger as c, type CommandModule as d, type CheckResult as e, type CliPaths as f, type CreateLoggerOptions as g, type OptionType as h, type ShellOptions as i, createDefaultLogger as j, createShell as k };
|
package/package.json
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@maroonedsoftware/johnny5",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI framework for ServerKit-based applications — plugin registration, doctor runner, and opt-in Postgres/Redis/Docker integrations",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Marooned Software",
|
|
7
|
+
"url": "https://github.com/MaroonedSoftware/serverkit"
|
|
8
|
+
},
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/MaroonedSoftware/serverkit/issues"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/MaroonedSoftware/serverkit/packages/johnny5#readme",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"backend",
|
|
15
|
+
"cli",
|
|
16
|
+
"doctor",
|
|
17
|
+
"framework",
|
|
18
|
+
"injectkit",
|
|
19
|
+
"serverkit",
|
|
20
|
+
"typescript"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/MaroonedSoftware/serverkit.git"
|
|
25
|
+
},
|
|
26
|
+
"private": false,
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./serverkit": {
|
|
37
|
+
"types": "./dist/integrations/serverkit/index.d.ts",
|
|
38
|
+
"import": "./dist/integrations/serverkit/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./postgres": {
|
|
41
|
+
"types": "./dist/integrations/postgres/index.d.ts",
|
|
42
|
+
"import": "./dist/integrations/postgres/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./redis": {
|
|
45
|
+
"types": "./dist/integrations/redis/index.d.ts",
|
|
46
|
+
"import": "./dist/integrations/redis/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./docker": {
|
|
49
|
+
"types": "./dist/integrations/docker/index.d.ts",
|
|
50
|
+
"import": "./dist/integrations/docker/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./versions": {
|
|
53
|
+
"types": "./dist/integrations/versions/index.d.ts",
|
|
54
|
+
"import": "./dist/integrations/versions/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./filesystem": {
|
|
57
|
+
"types": "./dist/integrations/filesystem/index.d.ts",
|
|
58
|
+
"import": "./dist/integrations/filesystem/index.js"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"files": [
|
|
63
|
+
"dist/**"
|
|
64
|
+
],
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@clack/prompts": "^0.11.0",
|
|
67
|
+
"commander": "^14.0.3",
|
|
68
|
+
"execa": "^9.6.0",
|
|
69
|
+
"injectkit": "^1.2.0",
|
|
70
|
+
"@maroonedsoftware/logger": "1.1.0",
|
|
71
|
+
"@maroonedsoftware/appconfig": "1.4.1"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"ioredis": "^5.10.0",
|
|
75
|
+
"kysely": "^0.28.0",
|
|
76
|
+
"pg": "^8.20.0",
|
|
77
|
+
"@maroonedsoftware/koa": "2.2.1"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"@maroonedsoftware/koa": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"ioredis": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"kysely": {
|
|
87
|
+
"optional": true
|
|
88
|
+
},
|
|
89
|
+
"pg": {
|
|
90
|
+
"optional": true
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@types/pg": "^8.20.0",
|
|
95
|
+
"ioredis": "^5.10.1",
|
|
96
|
+
"kysely": "^0.28.6",
|
|
97
|
+
"pg": "^8.20.0",
|
|
98
|
+
"tsup": "^8.5.1",
|
|
99
|
+
"vitest": "^4.1.5",
|
|
100
|
+
"@repo/config-eslint": "0.2.1",
|
|
101
|
+
"@maroonedsoftware/koa": "2.2.1",
|
|
102
|
+
"@repo/config-typescript": "0.1.0"
|
|
103
|
+
},
|
|
104
|
+
"scripts": {
|
|
105
|
+
"build": "tsup",
|
|
106
|
+
"build:ci": "eslint --max-warnings=0 && pnpm run build",
|
|
107
|
+
"dev": "tsup --watch",
|
|
108
|
+
"lint": "eslint --fix",
|
|
109
|
+
"format": "prettier --write .",
|
|
110
|
+
"test": "vitest run",
|
|
111
|
+
"test:ci": "vitest run --coverage"
|
|
112
|
+
}
|
|
113
|
+
}
|