@maltty/cli 1.0.0-rc.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 +88 -0
- package/bin/maltty.js +3 -0
- package/dist/_format-CeQhQTl5.js +23 -0
- package/dist/_format-CeQhQTl5.js.map +1 -0
- package/dist/attemptAsync-BdXzRSIT.js +42 -0
- package/dist/attemptAsync-BdXzRSIT.js.map +1 -0
- package/dist/chunk-DsIazq42.js +26 -0
- package/dist/commands/add/command.d.ts +7 -0
- package/dist/commands/add/command.d.ts.map +1 -0
- package/dist/commands/add/command.js +123 -0
- package/dist/commands/add/command.js.map +1 -0
- package/dist/commands/add/config.d.ts +7 -0
- package/dist/commands/add/config.d.ts.map +1 -0
- package/dist/commands/add/config.js +57 -0
- package/dist/commands/add/config.js.map +1 -0
- package/dist/commands/add/index.d.ts +7 -0
- package/dist/commands/add/index.d.ts.map +1 -0
- package/dist/commands/add/index.js +7 -0
- package/dist/commands/add/index.js.map +1 -0
- package/dist/commands/add/middleware.d.ts +7 -0
- package/dist/commands/add/middleware.d.ts.map +1 -0
- package/dist/commands/add/middleware.js +88 -0
- package/dist/commands/add/middleware.js.map +1 -0
- package/dist/commands/build.d.ts +15 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +246 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/commands.d.ts +14 -0
- package/dist/commands/commands.d.ts.map +1 -0
- package/dist/commands/commands.js +189 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/commands/dev.d.ts +13 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +58 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +658 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +305 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/run.d.ts +19 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +478 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/stories.d.ts +11 -0
- package/dist/commands/stories.d.ts.map +1 -0
- package/dist/commands/stories.js +22 -0
- package/dist/commands/stories.js.map +1 -0
- package/dist/config-helpers-pv_2Spux.js +15 -0
- package/dist/config-helpers-pv_2Spux.js.map +1 -0
- package/dist/defu-BBwssjW3.js +192 -0
- package/dist/defu-BBwssjW3.js.map +1 -0
- package/dist/detect-AOq1ehTE.js +61 -0
- package/dist/detect-AOq1ehTE.js.map +1 -0
- package/dist/dist-DW_gRP7_.js +1119 -0
- package/dist/dist-DW_gRP7_.js.map +1 -0
- package/dist/dist-Xa07jNxS.js +15617 -0
- package/dist/dist-Xa07jNxS.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/jiti-CxWlVmZ_.js +5458 -0
- package/dist/jiti-CxWlVmZ_.js.map +1 -0
- package/dist/json-D7WbuVK1.js +43 -0
- package/dist/json-D7WbuVK1.js.map +1 -0
- package/dist/json5-z-PGDMyy.js +777 -0
- package/dist/json5-z-PGDMyy.js.map +1 -0
- package/dist/jsonc-DqZkfC3S.js +401 -0
- package/dist/jsonc-DqZkfC3S.js.map +1 -0
- package/dist/jsonc-KADMdSjU.js +2 -0
- package/dist/lib/templates/command/command.ts.liquid +12 -0
- package/dist/lib/templates/config/config.ts.liquid +16 -0
- package/dist/lib/templates/middleware/middleware.ts.liquid +9 -0
- package/dist/lib/templates/project/gitignore.liquid +3 -0
- package/dist/lib/templates/project/maltty.config.ts.liquid +6 -0
- package/dist/lib/templates/project/package.json.liquid +30 -0
- package/dist/lib/templates/project/src/commands/hello.ts.liquid +12 -0
- package/dist/lib/templates/project/src/config.ts.liquid +16 -0
- package/dist/lib/templates/project/src/index.ts.liquid +13 -0
- package/dist/lib/templates/project/tsconfig.json.liquid +19 -0
- package/dist/lib/templates/project/vitest.config.ts.liquid +8 -0
- package/dist/main-C_8x2aB3.js +274 -0
- package/dist/main-C_8x2aB3.js.map +1 -0
- package/dist/manifest-BIKVDJML.js +112 -0
- package/dist/manifest-BIKVDJML.js.map +1 -0
- package/dist/multipart-parser-MNkxNO83.js +174 -0
- package/dist/multipart-parser-MNkxNO83.js.map +1 -0
- package/dist/node-C91xGGqn.js +644 -0
- package/dist/node-C91xGGqn.js.map +1 -0
- package/dist/node-Drmc03fL.js +3973 -0
- package/dist/node-Drmc03fL.js.map +1 -0
- package/dist/ohash-BPoV4zBH.js +185 -0
- package/dist/ohash-BPoV4zBH.js.map +1 -0
- package/dist/pnpm-workspace.yaml +26 -0
- package/dist/toml-LuHsHQtV.js +646 -0
- package/dist/toml-LuHsHQtV.js.map +1 -0
- package/dist/utils-DlIJNGLQ.js +1905 -0
- package/dist/utils-DlIJNGLQ.js.map +1 -0
- package/dist/validate-C_SXBoLq.js +18 -0
- package/dist/validate-C_SXBoLq.js.map +1 -0
- package/dist/write-CSwG4Stj.js +152 -0
- package/dist/write-CSwG4Stj.js.map +1 -0
- package/dist/yaml-BS9RDuUr.js +1067 -0
- package/dist/yaml-BS9RDuUr.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ByteFarm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @maltty/cli
|
|
2
|
+
|
|
3
|
+
DX companion CLI for the maltty framework. Provides scaffolding, build tooling, a dev server, and diagnostics for maltty-based CLI projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add -D @maltty/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This package installs the `maltty` binary.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
### `maltty init`
|
|
16
|
+
|
|
17
|
+
Scaffold a new maltty CLI project with a recommended directory structure, config file, and starter command.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
maltty init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### `maltty build`
|
|
24
|
+
|
|
25
|
+
Bundle your CLI using tsdown. Reads `maltty.config.ts` for entry point, output directory, and compile targets.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
maltty build
|
|
29
|
+
maltty build --compile # produce standalone binaries
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### `maltty dev`
|
|
33
|
+
|
|
34
|
+
Start a dev server that watches for changes and rebuilds automatically.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
maltty dev
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `maltty commands`
|
|
41
|
+
|
|
42
|
+
List all registered commands in the project.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
maltty commands
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### `maltty doctor`
|
|
49
|
+
|
|
50
|
+
Run diagnostics to verify your project setup, dependencies, and configuration.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
maltty doctor
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `maltty stories`
|
|
57
|
+
|
|
58
|
+
Launch the stories viewer TUI for browsing and previewing component stories in the terminal. Discovers `.stories.tsx` files in the project and renders them with an interactive props editor.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
maltty stories
|
|
62
|
+
maltty stories --include "src/components/**/*.stories.tsx"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
The CLI reads from `maltty.config.ts` in your project root:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { defineConfig } from 'maltty/config'
|
|
71
|
+
|
|
72
|
+
export default defineConfig({
|
|
73
|
+
entry: './src/index.ts',
|
|
74
|
+
commands: './src/commands',
|
|
75
|
+
build: {
|
|
76
|
+
out: './dist',
|
|
77
|
+
target: 'node18',
|
|
78
|
+
minify: false,
|
|
79
|
+
},
|
|
80
|
+
compile: {
|
|
81
|
+
targets: ['darwin-arm64', 'linux-x64'],
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT -- [GitHub](https://github.com/thebytefarm/maltty)
|
package/bin/maltty.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region ../../node_modules/.pnpm/confbox@0.2.4/node_modules/confbox/dist/_chunks/_format.mjs
|
|
2
|
+
const t = Symbol.for(`__confbox_fmt__`), n = /^(\s+)/, r = /(\s+)$/;
|
|
3
|
+
function i(e, t = {}) {
|
|
4
|
+
return {
|
|
5
|
+
sample: t.indent === void 0 && t.preserveIndentation !== !1 && e.slice(0, t?.sampleSize || 1024),
|
|
6
|
+
whiteSpace: t.preserveWhitespace === !1 ? void 0 : {
|
|
7
|
+
start: n.exec(e)?.[0] || ``,
|
|
8
|
+
end: r.exec(e)?.[0] || ``
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function a(e, n, r) {
|
|
13
|
+
!n || typeof n != `object` || Object.defineProperty(n, t, {
|
|
14
|
+
enumerable: !1,
|
|
15
|
+
configurable: !0,
|
|
16
|
+
writable: !0,
|
|
17
|
+
value: i(e, r)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { a as t };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=_format-CeQhQTl5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_format-CeQhQTl5.js","names":[],"sources":["../../../node_modules/.pnpm/confbox@0.2.4/node_modules/confbox/dist/_chunks/_format.mjs"],"sourcesContent":["import{t as e}from\"./libs/detect-indent.mjs\";const t=Symbol.for(`__confbox_fmt__`),n=/^(\\s+)/,r=/(\\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}export{a as n,o as t};"],"x_google_ignoreList":[0],"mappings":";AAA6C,MAAM,IAAE,OAAO,IAAI,kBAAkB,EAAC,IAAE,UAAS,IAAE;AAAS,SAAS,EAAE,GAAE,IAAE,EAAE,EAAC;AAAC,QAAM;EAAC,QAAO,EAAE,WAAS,KAAK,KAAG,EAAE,wBAAsB,CAAC,KAAG,EAAE,MAAM,GAAE,GAAG,cAAY,KAAK;EAAC,YAAW,EAAE,uBAAqB,CAAC,IAAE,KAAK,IAAE;GAAC,OAAM,EAAE,KAAK,EAAE,GAAG,MAAI;GAAG,KAAI,EAAE,KAAK,EAAE,GAAG,MAAI;GAAG;EAAC;;AAAC,SAAS,EAAE,GAAE,GAAE,GAAE;AAAC,EAAC,KAAG,OAAO,KAAG,YAAU,OAAO,eAAe,GAAE,GAAE;EAAC,YAAW,CAAC;EAAE,cAAa,CAAC;EAAE,UAAS,CAAC;EAAE,OAAM,EAAE,GAAE,EAAE;EAAC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region ../utils/dist/result-D_NYcfr2.js
|
|
2
|
+
/**
|
|
3
|
+
* Normalize an unknown caught value into an Error instance.
|
|
4
|
+
*
|
|
5
|
+
* If already an Error, returns it as-is. Otherwise wraps via `new Error(String(value))`.
|
|
6
|
+
*
|
|
7
|
+
* @param value - The unknown value to normalize.
|
|
8
|
+
* @returns An Error instance.
|
|
9
|
+
*/
|
|
10
|
+
function toError(value) {
|
|
11
|
+
if (value instanceof Error) return value;
|
|
12
|
+
return new Error(String(value));
|
|
13
|
+
}
|
|
14
|
+
function ok(value) {
|
|
15
|
+
return [null, value];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Construct a failure Result tuple.
|
|
19
|
+
*
|
|
20
|
+
* Coerces any value to an `Error` via {@link toError} and returns `[Error, null]`.
|
|
21
|
+
* For domain-specific error types (e.g. `AuthError`, `IconsError`), use raw
|
|
22
|
+
* tuple literals instead: `[domainError, null] as const`.
|
|
23
|
+
*
|
|
24
|
+
* @param error - The error value (coerced to Error).
|
|
25
|
+
* @returns A Result tuple `[Error, null]`.
|
|
26
|
+
*/
|
|
27
|
+
function err(error) {
|
|
28
|
+
return [toError(error), null];
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region ../../node_modules/.pnpm/es-toolkit@1.46.1/node_modules/es-toolkit/dist/util/attemptAsync.mjs
|
|
32
|
+
async function attemptAsync(func) {
|
|
33
|
+
try {
|
|
34
|
+
return [null, await func()];
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return [error, null];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { toError as i, err as n, ok as r, attemptAsync as t };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=attemptAsync-BdXzRSIT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attemptAsync-BdXzRSIT.js","names":[],"sources":["../../utils/dist/result-D_NYcfr2.js","../../../node_modules/.pnpm/es-toolkit@1.46.1/node_modules/es-toolkit/dist/util/attemptAsync.mjs"],"sourcesContent":["//#region src/fp/transform.ts\n/**\n* Normalize an unknown caught value into an Error instance.\n*\n* If already an Error, returns it as-is. Otherwise wraps via `new Error(String(value))`.\n*\n* @param value - The unknown value to normalize.\n* @returns An Error instance.\n*/\nfunction toError(value) {\n\tif (value instanceof Error) return value;\n\treturn new Error(String(value));\n}\n//#endregion\n//#region src/fp/result.ts\nfunction ok(value) {\n\treturn [null, value];\n}\n/**\n* Construct a failure Result tuple.\n*\n* Coerces any value to an `Error` via {@link toError} and returns `[Error, null]`.\n* For domain-specific error types (e.g. `AuthError`, `IconsError`), use raw\n* tuple literals instead: `[domainError, null] as const`.\n*\n* @param error - The error value (coerced to Error).\n* @returns A Result tuple `[Error, null]`.\n*/\nfunction err(error) {\n\treturn [toError(error), null];\n}\n//#endregion\nexport { ok as n, toError as r, err as t };\n\n//# sourceMappingURL=result-D_NYcfr2.js.map","async function attemptAsync(func) {\n try {\n const result = await func();\n return [null, result];\n }\n catch (error) {\n return [error, null];\n }\n}\n\nexport { attemptAsync };\n"],"x_google_ignoreList":[1],"mappings":";;;;;;;;;AASA,SAAS,QAAQ,OAAO;AACvB,KAAI,iBAAiB,MAAO,QAAO;AACnC,QAAO,IAAI,MAAM,OAAO,MAAM,CAAC;;AAIhC,SAAS,GAAG,OAAO;AAClB,QAAO,CAAC,MAAM,MAAM;;;;;;;;;;;;AAYrB,SAAS,IAAI,OAAO;AACnB,QAAO,CAAC,QAAQ,MAAM,EAAE,KAAK;;;;AC7B9B,eAAe,aAAa,MAAM;AAC9B,KAAI;AAEA,SAAO,CAAC,MADO,MAAM,MAAM,CACN;UAElB,OAAO;AACV,SAAO,CAAC,OAAO,KAAK"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
21
|
+
value: mod,
|
|
22
|
+
enumerable: true
|
|
23
|
+
}) : target, mod));
|
|
24
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
25
|
+
//#endregion
|
|
26
|
+
export { __require as n, __toESM as r, __commonJSMin as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","names":[],"sources":["../../../src/commands/add/command.ts"],"mappings":";;;cAqBM,iBAAA,EAAmB,OAAA"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { n as loadConfig } from "../../utils-DlIJNGLQ.js";
|
|
2
|
+
import { n as renderTemplate, t as writeFiles } from "../../write-CSwG4Stj.js";
|
|
3
|
+
import { t as isKebabCase } from "../../validate-C_SXBoLq.js";
|
|
4
|
+
import { t as detectProject } from "../../detect-AOq1ehTE.js";
|
|
5
|
+
import { command } from "maltty";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region src/commands/add/command.ts
|
|
9
|
+
const addCommandCommand = command({
|
|
10
|
+
options: z.object({
|
|
11
|
+
args: z.boolean().describe("Include args schema").optional(),
|
|
12
|
+
description: z.string().describe("Command description").optional(),
|
|
13
|
+
name: z.string().describe("Command name (kebab-case)").optional()
|
|
14
|
+
}),
|
|
15
|
+
description: "Add a new command to your project",
|
|
16
|
+
handler: async (ctx) => {
|
|
17
|
+
const [detectError, project] = await detectProject(process.cwd());
|
|
18
|
+
if (detectError) return ctx.fail(detectError.message);
|
|
19
|
+
if (!project) return ctx.fail("Not in a maltty project. Run `maltty init` first.");
|
|
20
|
+
const [, configResult] = await loadConfig({ cwd: project.rootDir });
|
|
21
|
+
const commandName = await resolveCommandName(ctx);
|
|
22
|
+
const commandDescription = await resolveDescription(ctx);
|
|
23
|
+
const includeArgs = await resolveIncludeArgs(ctx);
|
|
24
|
+
ctx.status.spinner.start("Generating command...");
|
|
25
|
+
const [renderError, rendered] = await renderTemplate({
|
|
26
|
+
templateDir: join(import.meta.dirname, "..", "..", "lib", "templates", "command"),
|
|
27
|
+
variables: {
|
|
28
|
+
commandName,
|
|
29
|
+
description: commandDescription,
|
|
30
|
+
includeArgs
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
if (renderError) {
|
|
34
|
+
ctx.status.spinner.stop("Failed");
|
|
35
|
+
return ctx.fail(renderError.message);
|
|
36
|
+
}
|
|
37
|
+
const outputDir = resolveCommandsDir(configResult, project.rootDir);
|
|
38
|
+
const [writeError, result] = await writeFiles({
|
|
39
|
+
files: rendered.map((file) => ({
|
|
40
|
+
content: file.content,
|
|
41
|
+
relativePath: file.relativePath.replace("command.ts", `${commandName}.ts`)
|
|
42
|
+
})),
|
|
43
|
+
outputDir,
|
|
44
|
+
overwrite: false
|
|
45
|
+
});
|
|
46
|
+
if (writeError) {
|
|
47
|
+
ctx.status.spinner.stop("Failed");
|
|
48
|
+
return ctx.fail(writeError.message);
|
|
49
|
+
}
|
|
50
|
+
ctx.status.spinner.stop("Command created!");
|
|
51
|
+
const summary = [...result.written.map((file) => ` created ${file}`), ...result.skipped.map((file) => ` skipped ${file} (already exists)`)].join("\n");
|
|
52
|
+
if (summary.length > 0) ctx.log.raw(summary);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the command name from args or prompt.
|
|
57
|
+
*
|
|
58
|
+
* @param ctx - Command context.
|
|
59
|
+
* @returns The validated command name.
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
async function resolveCommandName(ctx) {
|
|
63
|
+
if (ctx.args.name) {
|
|
64
|
+
if (!isKebabCase(ctx.args.name)) return ctx.fail("Command name must be kebab-case (e.g. deploy)");
|
|
65
|
+
return ctx.args.name;
|
|
66
|
+
}
|
|
67
|
+
return ctx.prompts.text({
|
|
68
|
+
message: "Command name",
|
|
69
|
+
placeholder: "deploy",
|
|
70
|
+
validate: (value) => {
|
|
71
|
+
if (value === void 0 || !isKebabCase(value)) return "Must be kebab-case (e.g. deploy)";
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve the command description from args or prompt.
|
|
77
|
+
*
|
|
78
|
+
* @param ctx - Command context.
|
|
79
|
+
* @returns The command description string.
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
async function resolveDescription(ctx) {
|
|
83
|
+
if (ctx.args.description) return ctx.args.description;
|
|
84
|
+
return ctx.prompts.text({
|
|
85
|
+
defaultValue: "",
|
|
86
|
+
message: "Description",
|
|
87
|
+
placeholder: "What does this command do?"
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Resolve whether to include args from args or prompt.
|
|
92
|
+
*
|
|
93
|
+
* @param ctx - Command context.
|
|
94
|
+
* @returns True when the command should include a zod args schema.
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
async function resolveIncludeArgs(ctx) {
|
|
98
|
+
if (ctx.args.args !== void 0) return ctx.args.args;
|
|
99
|
+
return ctx.prompts.confirm({
|
|
100
|
+
initialValue: true,
|
|
101
|
+
message: "Include args schema?"
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Resolve the commands output directory from the maltty config.
|
|
106
|
+
*
|
|
107
|
+
* Uses the `commands` field from `maltty.config.ts` when available,
|
|
108
|
+
* falling back to the maltty default of `'commands'`.
|
|
109
|
+
*
|
|
110
|
+
* @param configResult - The loaded config result, or null when loading failed.
|
|
111
|
+
* @param rootDir - The project root directory.
|
|
112
|
+
* @returns The absolute path to the commands directory.
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
function resolveCommandsDir(configResult, rootDir) {
|
|
116
|
+
const DEFAULT_COMMANDS = "commands";
|
|
117
|
+
if (configResult) return join(rootDir, configResult.config.commands ?? DEFAULT_COMMANDS);
|
|
118
|
+
return join(rootDir, DEFAULT_COMMANDS);
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
export { addCommandCommand as default };
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","names":[],"sources":["../../../src/commands/add/command.ts"],"sourcesContent":["import { join } from 'node:path'\n\nimport { loadConfig } from '@maltty/config/utils'\nimport type { LoadConfigResult } from '@maltty/config/utils'\nimport { command } from 'maltty'\nimport type { Command, CommandContext } from 'maltty'\nimport { z } from 'zod'\n\nimport { detectProject } from '../../lib/detect.js'\nimport { renderTemplate } from '../../lib/render.js'\nimport { isKebabCase } from '../../lib/validate.js'\nimport { writeFiles } from '../../lib/write.js'\n\nconst options = z.object({\n args: z.boolean().describe('Include args schema').optional(),\n description: z.string().describe('Command description').optional(),\n name: z.string().describe('Command name (kebab-case)').optional(),\n})\n\ntype AddCommandArgs = z.infer<typeof options>\n\nconst addCommandCommand: Command = command({\n options,\n description: 'Add a new command to your project',\n handler: async (ctx: CommandContext<AddCommandArgs>) => {\n const cwd = process.cwd()\n\n const [detectError, project] = await detectProject(cwd)\n if (detectError) {\n return ctx.fail(detectError.message)\n }\n if (!project) {\n return ctx.fail('Not in a maltty project. Run `maltty init` first.')\n }\n\n const [, configResult] = await loadConfig({ cwd: project.rootDir })\n\n const commandName = await resolveCommandName(ctx)\n const commandDescription = await resolveDescription(ctx)\n const includeArgs = await resolveIncludeArgs(ctx)\n\n ctx.status.spinner.start('Generating command...')\n\n const templateDir = join(import.meta.dirname, '..', '..', 'lib', 'templates', 'command')\n const [renderError, rendered] = await renderTemplate({\n templateDir,\n variables: { commandName, description: commandDescription, includeArgs },\n })\n\n if (renderError) {\n ctx.status.spinner.stop('Failed')\n return ctx.fail(renderError.message)\n }\n\n const outputDir = resolveCommandsDir(configResult, project.rootDir)\n const files = rendered.map((file) => ({\n content: file.content,\n relativePath: file.relativePath.replace('command.ts', `${commandName}.ts`),\n }))\n\n const [writeError, result] = await writeFiles({ files, outputDir, overwrite: false })\n\n if (writeError) {\n ctx.status.spinner.stop('Failed')\n return ctx.fail(writeError.message)\n }\n\n ctx.status.spinner.stop('Command created!')\n\n const lines = [\n ...result.written.map((file) => ` created ${file}`),\n ...result.skipped.map((file) => ` skipped ${file} (already exists)`),\n ]\n const summary = lines.join('\\n')\n if (summary.length > 0) {\n ctx.log.raw(summary)\n }\n },\n})\n\nexport default addCommandCommand\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the command name from args or prompt.\n *\n * @param ctx - Command context.\n * @returns The validated command name.\n * @private\n */\nasync function resolveCommandName(ctx: CommandContext<AddCommandArgs>): Promise<string> {\n if (ctx.args.name) {\n if (!isKebabCase(ctx.args.name)) {\n return ctx.fail('Command name must be kebab-case (e.g. deploy)')\n }\n return ctx.args.name\n }\n return ctx.prompts.text({\n message: 'Command name',\n placeholder: 'deploy',\n validate: (value: string | undefined) => {\n if (value === undefined || !isKebabCase(value)) {\n return 'Must be kebab-case (e.g. deploy)'\n }\n return undefined\n },\n })\n}\n\n/**\n * Resolve the command description from args or prompt.\n *\n * @param ctx - Command context.\n * @returns The command description string.\n * @private\n */\nasync function resolveDescription(ctx: CommandContext<AddCommandArgs>): Promise<string> {\n if (ctx.args.description) {\n return ctx.args.description\n }\n return ctx.prompts.text({\n defaultValue: '',\n message: 'Description',\n placeholder: 'What does this command do?',\n })\n}\n\n/**\n * Resolve whether to include args from args or prompt.\n *\n * @param ctx - Command context.\n * @returns True when the command should include a zod args schema.\n * @private\n */\nasync function resolveIncludeArgs(ctx: CommandContext<AddCommandArgs>): Promise<boolean> {\n if (ctx.args.args !== undefined) {\n return ctx.args.args\n }\n return ctx.prompts.confirm({\n initialValue: true,\n message: 'Include args schema?',\n })\n}\n\n/**\n * Resolve the commands output directory from the maltty config.\n *\n * Uses the `commands` field from `maltty.config.ts` when available,\n * falling back to the maltty default of `'commands'`.\n *\n * @param configResult - The loaded config result, or null when loading failed.\n * @param rootDir - The project root directory.\n * @returns The absolute path to the commands directory.\n * @private\n */\nfunction resolveCommandsDir(configResult: LoadConfigResult | null, rootDir: string): string {\n const DEFAULT_COMMANDS = 'commands'\n\n if (configResult) {\n return join(rootDir, configResult.config.commands ?? DEFAULT_COMMANDS)\n }\n\n return join(rootDir, DEFAULT_COMMANDS)\n}\n"],"mappings":";;;;;;;;AAqBA,MAAM,oBAA6B,QAAQ;CACzC,SATc,EAAE,OAAO;EACvB,MAAM,EAAE,SAAS,CAAC,SAAS,sBAAsB,CAAC,UAAU;EAC5D,aAAa,EAAE,QAAQ,CAAC,SAAS,sBAAsB,CAAC,UAAU;EAClE,MAAM,EAAE,QAAQ,CAAC,SAAS,4BAA4B,CAAC,UAAU;EAClE,CAAC;CAMA,aAAa;CACb,SAAS,OAAO,QAAwC;EAGtD,MAAM,CAAC,aAAa,WAAW,MAAM,cAFzB,QAAQ,KAAK,CAE8B;AACvD,MAAI,YACF,QAAO,IAAI,KAAK,YAAY,QAAQ;AAEtC,MAAI,CAAC,QACH,QAAO,IAAI,KAAK,oDAAoD;EAGtE,MAAM,GAAG,gBAAgB,MAAM,WAAW,EAAE,KAAK,QAAQ,SAAS,CAAC;EAEnE,MAAM,cAAc,MAAM,mBAAmB,IAAI;EACjD,MAAM,qBAAqB,MAAM,mBAAmB,IAAI;EACxD,MAAM,cAAc,MAAM,mBAAmB,IAAI;AAEjD,MAAI,OAAO,QAAQ,MAAM,wBAAwB;EAGjD,MAAM,CAAC,aAAa,YAAY,MAAM,eAAe;GACnD,aAFkB,KAAK,OAAO,KAAK,SAAS,MAAM,MAAM,OAAO,aAAa,UAAU;GAGtF,WAAW;IAAE;IAAa,aAAa;IAAoB;IAAa;GACzE,CAAC;AAEF,MAAI,aAAa;AACf,OAAI,OAAO,QAAQ,KAAK,SAAS;AACjC,UAAO,IAAI,KAAK,YAAY,QAAQ;;EAGtC,MAAM,YAAY,mBAAmB,cAAc,QAAQ,QAAQ;EAMnE,MAAM,CAAC,YAAY,UAAU,MAAM,WAAW;GAAE,OALlC,SAAS,KAAK,UAAU;IACpC,SAAS,KAAK;IACd,cAAc,KAAK,aAAa,QAAQ,cAAc,GAAG,YAAY,KAAK;IAC3E,EAAE;GAEoD;GAAW,WAAW;GAAO,CAAC;AAErF,MAAI,YAAY;AACd,OAAI,OAAO,QAAQ,KAAK,SAAS;AACjC,UAAO,IAAI,KAAK,WAAW,QAAQ;;AAGrC,MAAI,OAAO,QAAQ,KAAK,mBAAmB;EAM3C,MAAM,UAJQ,CACZ,GAAG,OAAO,QAAQ,KAAK,SAAS,aAAa,OAAO,EACpD,GAAG,OAAO,QAAQ,KAAK,SAAS,aAAa,KAAK,mBAAmB,CACtE,CACqB,KAAK,KAAK;AAChC,MAAI,QAAQ,SAAS,EACnB,KAAI,IAAI,IAAI,QAAQ;;CAGzB,CAAC;;;;;;;;AAeF,eAAe,mBAAmB,KAAsD;AACtF,KAAI,IAAI,KAAK,MAAM;AACjB,MAAI,CAAC,YAAY,IAAI,KAAK,KAAK,CAC7B,QAAO,IAAI,KAAK,gDAAgD;AAElE,SAAO,IAAI,KAAK;;AAElB,QAAO,IAAI,QAAQ,KAAK;EACtB,SAAS;EACT,aAAa;EACb,WAAW,UAA8B;AACvC,OAAI,UAAU,KAAA,KAAa,CAAC,YAAY,MAAM,CAC5C,QAAO;;EAIZ,CAAC;;;;;;;;;AAUJ,eAAe,mBAAmB,KAAsD;AACtF,KAAI,IAAI,KAAK,YACX,QAAO,IAAI,KAAK;AAElB,QAAO,IAAI,QAAQ,KAAK;EACtB,cAAc;EACd,SAAS;EACT,aAAa;EACd,CAAC;;;;;;;;;AAUJ,eAAe,mBAAmB,KAAuD;AACvF,KAAI,IAAI,KAAK,SAAS,KAAA,EACpB,QAAO,IAAI,KAAK;AAElB,QAAO,IAAI,QAAQ,QAAQ;EACzB,cAAc;EACd,SAAS;EACV,CAAC;;;;;;;;;;;;;AAcJ,SAAS,mBAAmB,cAAuC,SAAyB;CAC1F,MAAM,mBAAmB;AAEzB,KAAI,aACF,QAAO,KAAK,SAAS,aAAa,OAAO,YAAY,iBAAiB;AAGxE,QAAO,KAAK,SAAS,iBAAiB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","names":[],"sources":["../../../src/commands/add/config.ts"],"mappings":";;;cAUM,gBAAA,EAAkB,OAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { t as readManifest } from "../../manifest-BIKVDJML.js";
|
|
2
|
+
import { n as renderTemplate, t as writeFiles } from "../../write-CSwG4Stj.js";
|
|
3
|
+
import { t as detectProject } from "../../detect-AOq1ehTE.js";
|
|
4
|
+
import { command } from "maltty";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
//#region src/commands/add/config.ts
|
|
7
|
+
const addConfigCommand = command({
|
|
8
|
+
description: "Add a config schema to your project",
|
|
9
|
+
handler: async (ctx) => {
|
|
10
|
+
const [detectError, project] = await detectProject(process.cwd());
|
|
11
|
+
if (detectError) return ctx.fail(detectError.message);
|
|
12
|
+
if (!project) return ctx.fail("Not in a maltty project. Run `maltty init` first.");
|
|
13
|
+
const projectName = await resolveProjectName(project.rootDir);
|
|
14
|
+
ctx.status.spinner.start("Generating config...");
|
|
15
|
+
const [renderError, rendered] = await renderTemplate({
|
|
16
|
+
templateDir: join(import.meta.dirname, "..", "..", "lib", "templates", "config"),
|
|
17
|
+
variables: { name: projectName }
|
|
18
|
+
});
|
|
19
|
+
if (renderError) {
|
|
20
|
+
ctx.status.spinner.stop("Failed");
|
|
21
|
+
return ctx.fail(renderError.message);
|
|
22
|
+
}
|
|
23
|
+
const [writeError, result] = await writeFiles({
|
|
24
|
+
files: rendered,
|
|
25
|
+
outputDir: join(project.rootDir, "src"),
|
|
26
|
+
overwrite: false
|
|
27
|
+
});
|
|
28
|
+
if (writeError) {
|
|
29
|
+
ctx.status.spinner.stop("Failed");
|
|
30
|
+
return ctx.fail(writeError.message);
|
|
31
|
+
}
|
|
32
|
+
ctx.status.spinner.stop("Config created!");
|
|
33
|
+
const summary = [...result.written.map((file) => ` created ${file}`), ...result.skipped.map((file) => ` skipped ${file} (already exists)`)].join("\n");
|
|
34
|
+
if (summary.length > 0) ctx.log.raw(summary);
|
|
35
|
+
ctx.log.newline();
|
|
36
|
+
ctx.log.raw("Next steps:");
|
|
37
|
+
ctx.log.raw(" 1. Add fields to the config schema in src/config.ts");
|
|
38
|
+
ctx.log.raw(" 2. Import and pass the schema to cli({ config: { schema: configSchema } })");
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const DEFAULT_NAME = "my-app";
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the project name from the project's package.json.
|
|
44
|
+
*
|
|
45
|
+
* @param rootDir - The project root directory.
|
|
46
|
+
* @returns The project name from package.json, or a default fallback.
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
async function resolveProjectName(rootDir) {
|
|
50
|
+
const [error, manifest] = await readManifest(rootDir);
|
|
51
|
+
if (error || !manifest.name) return DEFAULT_NAME;
|
|
52
|
+
return manifest.name;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { addConfigCommand as default };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../../src/commands/add/config.ts"],"sourcesContent":["import { join } from 'node:path'\n\nimport { readManifest } from '@maltty/utils/manifest'\nimport { command } from 'maltty'\nimport type { Command, CommandContext } from 'maltty'\n\nimport { detectProject } from '../../lib/detect.js'\nimport { renderTemplate } from '../../lib/render.js'\nimport { writeFiles } from '../../lib/write.js'\n\nconst addConfigCommand: Command = command({\n description: 'Add a config schema to your project',\n handler: async (ctx: CommandContext) => {\n const cwd = process.cwd()\n\n const [detectError, project] = await detectProject(cwd)\n if (detectError) {\n return ctx.fail(detectError.message)\n }\n if (!project) {\n return ctx.fail('Not in a maltty project. Run `maltty init` first.')\n }\n\n const projectName = await resolveProjectName(project.rootDir)\n\n ctx.status.spinner.start('Generating config...')\n\n const templateDir = join(import.meta.dirname, '..', '..', 'lib', 'templates', 'config')\n const [renderError, rendered] = await renderTemplate({\n templateDir,\n variables: { name: projectName },\n })\n\n if (renderError) {\n ctx.status.spinner.stop('Failed')\n return ctx.fail(renderError.message)\n }\n\n const outputDir = join(project.rootDir, 'src')\n const [writeError, result] = await writeFiles({ files: rendered, outputDir, overwrite: false })\n\n if (writeError) {\n ctx.status.spinner.stop('Failed')\n return ctx.fail(writeError.message)\n }\n\n ctx.status.spinner.stop('Config created!')\n\n const lines = [\n ...result.written.map((file) => ` created ${file}`),\n ...result.skipped.map((file) => ` skipped ${file} (already exists)`),\n ]\n const summary = lines.join('\\n')\n if (summary.length > 0) {\n ctx.log.raw(summary)\n }\n\n ctx.log.newline()\n ctx.log.raw('Next steps:')\n ctx.log.raw(' 1. Add fields to the config schema in src/config.ts')\n ctx.log.raw(' 2. Import and pass the schema to cli({ config: { schema: configSchema } })')\n },\n})\n\nexport default addConfigCommand\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_NAME = 'my-app'\n\n/**\n * Resolve the project name from the project's package.json.\n *\n * @param rootDir - The project root directory.\n * @returns The project name from package.json, or a default fallback.\n * @private\n */\nasync function resolveProjectName(rootDir: string): Promise<string> {\n const [error, manifest] = await readManifest(rootDir)\n if (error || !manifest.name) {\n return DEFAULT_NAME\n }\n return manifest.name\n}\n"],"mappings":";;;;;;AAUA,MAAM,mBAA4B,QAAQ;CACxC,aAAa;CACb,SAAS,OAAO,QAAwB;EAGtC,MAAM,CAAC,aAAa,WAAW,MAAM,cAFzB,QAAQ,KAAK,CAE8B;AACvD,MAAI,YACF,QAAO,IAAI,KAAK,YAAY,QAAQ;AAEtC,MAAI,CAAC,QACH,QAAO,IAAI,KAAK,oDAAoD;EAGtE,MAAM,cAAc,MAAM,mBAAmB,QAAQ,QAAQ;AAE7D,MAAI,OAAO,QAAQ,MAAM,uBAAuB;EAGhD,MAAM,CAAC,aAAa,YAAY,MAAM,eAAe;GACnD,aAFkB,KAAK,OAAO,KAAK,SAAS,MAAM,MAAM,OAAO,aAAa,SAAS;GAGrF,WAAW,EAAE,MAAM,aAAa;GACjC,CAAC;AAEF,MAAI,aAAa;AACf,OAAI,OAAO,QAAQ,KAAK,SAAS;AACjC,UAAO,IAAI,KAAK,YAAY,QAAQ;;EAItC,MAAM,CAAC,YAAY,UAAU,MAAM,WAAW;GAAE,OAAO;GAAU,WAD/C,KAAK,QAAQ,SAAS,MAAM;GAC8B,WAAW;GAAO,CAAC;AAE/F,MAAI,YAAY;AACd,OAAI,OAAO,QAAQ,KAAK,SAAS;AACjC,UAAO,IAAI,KAAK,WAAW,QAAQ;;AAGrC,MAAI,OAAO,QAAQ,KAAK,kBAAkB;EAM1C,MAAM,UAJQ,CACZ,GAAG,OAAO,QAAQ,KAAK,SAAS,aAAa,OAAO,EACpD,GAAG,OAAO,QAAQ,KAAK,SAAS,aAAa,KAAK,mBAAmB,CACtE,CACqB,KAAK,KAAK;AAChC,MAAI,QAAQ,SAAS,EACnB,KAAI,IAAI,IAAI,QAAQ;AAGtB,MAAI,IAAI,SAAS;AACjB,MAAI,IAAI,IAAI,cAAc;AAC1B,MAAI,IAAI,IAAI,wDAAwD;AACpE,MAAI,IAAI,IAAI,+EAA+E;;CAE9F,CAAC;AAQF,MAAM,eAAe;;;;;;;;AASrB,eAAe,mBAAmB,SAAkC;CAClE,MAAM,CAAC,OAAO,YAAY,MAAM,aAAa,QAAQ;AACrD,KAAI,SAAS,CAAC,SAAS,KACrB,QAAO;AAET,QAAO,SAAS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/commands/add/index.ts"],"mappings":";;;cAGM,UAAA,EAAY,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/commands/add/index.ts"],"sourcesContent":["import { command } from 'maltty'\nimport type { Command } from 'maltty'\n\nconst addCommand: Command = command({\n description: 'Add a command, middleware, or config to your project',\n})\n\nexport default addCommand\n"],"mappings":";;AAGA,MAAM,aAAsB,QAAQ,EAClC,aAAa,wDACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","names":[],"sources":["../../../src/commands/add/middleware.ts"],"mappings":";;;cAkBM,oBAAA,EAAsB,OAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { n as renderTemplate, t as writeFiles } from "../../write-CSwG4Stj.js";
|
|
2
|
+
import { t as isKebabCase } from "../../validate-C_SXBoLq.js";
|
|
3
|
+
import { t as detectProject } from "../../detect-AOq1ehTE.js";
|
|
4
|
+
import { command } from "maltty";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
//#region src/commands/add/middleware.ts
|
|
8
|
+
const addMiddlewareCommand = command({
|
|
9
|
+
options: z.object({
|
|
10
|
+
description: z.string().describe("Middleware description").optional(),
|
|
11
|
+
name: z.string().describe("Middleware name (kebab-case)").optional()
|
|
12
|
+
}),
|
|
13
|
+
description: "Add a new middleware to your project",
|
|
14
|
+
handler: async (ctx) => {
|
|
15
|
+
const [detectError, project] = await detectProject(process.cwd());
|
|
16
|
+
if (detectError) return ctx.fail(detectError.message);
|
|
17
|
+
if (!project) return ctx.fail("Not in a maltty project. Run `maltty init` first.");
|
|
18
|
+
const middlewareName = await resolveMiddlewareName(ctx);
|
|
19
|
+
const middlewareDescription = await resolveDescription(ctx);
|
|
20
|
+
ctx.status.spinner.start("Generating middleware...");
|
|
21
|
+
const [renderError, rendered] = await renderTemplate({
|
|
22
|
+
templateDir: join(import.meta.dirname, "..", "..", "lib", "templates", "middleware"),
|
|
23
|
+
variables: {
|
|
24
|
+
description: middlewareDescription,
|
|
25
|
+
middlewareName
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (renderError) {
|
|
29
|
+
ctx.status.spinner.stop("Failed");
|
|
30
|
+
return ctx.fail(renderError.message);
|
|
31
|
+
}
|
|
32
|
+
const outputDir = join(project.rootDir, "src", "middleware");
|
|
33
|
+
const [writeError, result] = await writeFiles({
|
|
34
|
+
files: rendered.map((file) => ({
|
|
35
|
+
content: file.content,
|
|
36
|
+
relativePath: file.relativePath.replace("middleware.ts", `${middlewareName}.ts`)
|
|
37
|
+
})),
|
|
38
|
+
outputDir,
|
|
39
|
+
overwrite: false
|
|
40
|
+
});
|
|
41
|
+
if (writeError) {
|
|
42
|
+
ctx.status.spinner.stop("Failed");
|
|
43
|
+
return ctx.fail(writeError.message);
|
|
44
|
+
}
|
|
45
|
+
ctx.status.spinner.stop("Middleware created!");
|
|
46
|
+
const summary = [...result.written.map((file) => ` created ${file}`), ...result.skipped.map((file) => ` skipped ${file} (already exists)`)].join("\n");
|
|
47
|
+
if (summary.length > 0) ctx.log.raw(summary);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* Resolve the middleware name from args or prompt.
|
|
52
|
+
*
|
|
53
|
+
* @param ctx - Command context.
|
|
54
|
+
* @returns The validated middleware name.
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
async function resolveMiddlewareName(ctx) {
|
|
58
|
+
if (ctx.args.name) {
|
|
59
|
+
if (!isKebabCase(ctx.args.name)) return ctx.fail("Middleware name must be kebab-case (e.g. auth)");
|
|
60
|
+
return ctx.args.name;
|
|
61
|
+
}
|
|
62
|
+
return ctx.prompts.text({
|
|
63
|
+
message: "Middleware name",
|
|
64
|
+
placeholder: "auth",
|
|
65
|
+
validate: (value) => {
|
|
66
|
+
if (value === void 0 || !isKebabCase(value)) return "Must be kebab-case (e.g. auth)";
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the middleware description from args or prompt.
|
|
72
|
+
*
|
|
73
|
+
* @param ctx - Command context.
|
|
74
|
+
* @returns The middleware description string.
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
async function resolveDescription(ctx) {
|
|
78
|
+
if (ctx.args.description) return ctx.args.description;
|
|
79
|
+
return ctx.prompts.text({
|
|
80
|
+
defaultValue: "",
|
|
81
|
+
message: "Description",
|
|
82
|
+
placeholder: "What does this middleware do?"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { addMiddlewareCommand as default };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/commands/add/middleware.ts"],"sourcesContent":["import { join } from 'node:path'\n\nimport { command } from 'maltty'\nimport type { Command, CommandContext } from 'maltty'\nimport { z } from 'zod'\n\nimport { detectProject } from '../../lib/detect.js'\nimport { renderTemplate } from '../../lib/render.js'\nimport { isKebabCase } from '../../lib/validate.js'\nimport { writeFiles } from '../../lib/write.js'\n\nconst options = z.object({\n description: z.string().describe('Middleware description').optional(),\n name: z.string().describe('Middleware name (kebab-case)').optional(),\n})\n\ntype AddMiddlewareArgs = z.infer<typeof options>\n\nconst addMiddlewareCommand: Command = command({\n options,\n description: 'Add a new middleware to your project',\n handler: async (ctx: CommandContext<AddMiddlewareArgs>) => {\n const [detectError, project] = await detectProject(process.cwd())\n if (detectError) {\n return ctx.fail(detectError.message)\n }\n if (!project) {\n return ctx.fail('Not in a maltty project. Run `maltty init` first.')\n }\n\n const middlewareName = await resolveMiddlewareName(ctx)\n const middlewareDescription = await resolveDescription(ctx)\n\n ctx.status.spinner.start('Generating middleware...')\n\n const templateDir = join(import.meta.dirname, '..', '..', 'lib', 'templates', 'middleware')\n const [renderError, rendered] = await renderTemplate({\n templateDir,\n variables: { description: middlewareDescription, middlewareName },\n })\n\n if (renderError) {\n ctx.status.spinner.stop('Failed')\n return ctx.fail(renderError.message)\n }\n\n const outputDir = join(project.rootDir, 'src', 'middleware')\n const files = rendered.map((file) => ({\n content: file.content,\n relativePath: file.relativePath.replace('middleware.ts', `${middlewareName}.ts`),\n }))\n\n const [writeError, result] = await writeFiles({ files, outputDir, overwrite: false })\n\n if (writeError) {\n ctx.status.spinner.stop('Failed')\n return ctx.fail(writeError.message)\n }\n\n ctx.status.spinner.stop('Middleware created!')\n\n const lines = [\n ...result.written.map((file) => ` created ${file}`),\n ...result.skipped.map((file) => ` skipped ${file} (already exists)`),\n ]\n const summary = lines.join('\\n')\n if (summary.length > 0) {\n ctx.log.raw(summary)\n }\n },\n})\n\nexport default addMiddlewareCommand\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the middleware name from args or prompt.\n *\n * @param ctx - Command context.\n * @returns The validated middleware name.\n * @private\n */\nasync function resolveMiddlewareName(ctx: CommandContext<AddMiddlewareArgs>): Promise<string> {\n if (ctx.args.name) {\n if (!isKebabCase(ctx.args.name)) {\n return ctx.fail('Middleware name must be kebab-case (e.g. auth)')\n }\n return ctx.args.name\n }\n return ctx.prompts.text({\n message: 'Middleware name',\n placeholder: 'auth',\n validate: (value: string | undefined) => {\n if (value === undefined || !isKebabCase(value)) {\n return 'Must be kebab-case (e.g. auth)'\n }\n return undefined\n },\n })\n}\n\n/**\n * Resolve the middleware description from args or prompt.\n *\n * @param ctx - Command context.\n * @returns The middleware description string.\n * @private\n */\nasync function resolveDescription(ctx: CommandContext<AddMiddlewareArgs>): Promise<string> {\n if (ctx.args.description) {\n return ctx.args.description\n }\n return ctx.prompts.text({\n defaultValue: '',\n message: 'Description',\n placeholder: 'What does this middleware do?',\n })\n}\n"],"mappings":";;;;;;;AAkBA,MAAM,uBAAgC,QAAQ;CAC5C,SARc,EAAE,OAAO;EACvB,aAAa,EAAE,QAAQ,CAAC,SAAS,yBAAyB,CAAC,UAAU;EACrE,MAAM,EAAE,QAAQ,CAAC,SAAS,+BAA+B,CAAC,UAAU;EACrE,CAAC;CAMA,aAAa;CACb,SAAS,OAAO,QAA2C;EACzD,MAAM,CAAC,aAAa,WAAW,MAAM,cAAc,QAAQ,KAAK,CAAC;AACjE,MAAI,YACF,QAAO,IAAI,KAAK,YAAY,QAAQ;AAEtC,MAAI,CAAC,QACH,QAAO,IAAI,KAAK,oDAAoD;EAGtE,MAAM,iBAAiB,MAAM,sBAAsB,IAAI;EACvD,MAAM,wBAAwB,MAAM,mBAAmB,IAAI;AAE3D,MAAI,OAAO,QAAQ,MAAM,2BAA2B;EAGpD,MAAM,CAAC,aAAa,YAAY,MAAM,eAAe;GACnD,aAFkB,KAAK,OAAO,KAAK,SAAS,MAAM,MAAM,OAAO,aAAa,aAAa;GAGzF,WAAW;IAAE,aAAa;IAAuB;IAAgB;GAClE,CAAC;AAEF,MAAI,aAAa;AACf,OAAI,OAAO,QAAQ,KAAK,SAAS;AACjC,UAAO,IAAI,KAAK,YAAY,QAAQ;;EAGtC,MAAM,YAAY,KAAK,QAAQ,SAAS,OAAO,aAAa;EAM5D,MAAM,CAAC,YAAY,UAAU,MAAM,WAAW;GAAE,OALlC,SAAS,KAAK,UAAU;IACpC,SAAS,KAAK;IACd,cAAc,KAAK,aAAa,QAAQ,iBAAiB,GAAG,eAAe,KAAK;IACjF,EAAE;GAEoD;GAAW,WAAW;GAAO,CAAC;AAErF,MAAI,YAAY;AACd,OAAI,OAAO,QAAQ,KAAK,SAAS;AACjC,UAAO,IAAI,KAAK,WAAW,QAAQ;;AAGrC,MAAI,OAAO,QAAQ,KAAK,sBAAsB;EAM9C,MAAM,UAJQ,CACZ,GAAG,OAAO,QAAQ,KAAK,SAAS,aAAa,OAAO,EACpD,GAAG,OAAO,QAAQ,KAAK,SAAS,aAAa,KAAK,mBAAmB,CACtE,CACqB,KAAK,KAAK;AAChC,MAAI,QAAQ,SAAS,EACnB,KAAI,IAAI,IAAI,QAAQ;;CAGzB,CAAC;;;;;;;;AAeF,eAAe,sBAAsB,KAAyD;AAC5F,KAAI,IAAI,KAAK,MAAM;AACjB,MAAI,CAAC,YAAY,IAAI,KAAK,KAAK,CAC7B,QAAO,IAAI,KAAK,iDAAiD;AAEnE,SAAO,IAAI,KAAK;;AAElB,QAAO,IAAI,QAAQ,KAAK;EACtB,SAAS;EACT,aAAa;EACb,WAAW,UAA8B;AACvC,OAAI,UAAU,KAAA,KAAa,CAAC,YAAY,MAAM,CAC5C,QAAO;;EAIZ,CAAC;;;;;;;;;AAUJ,eAAe,mBAAmB,KAAyD;AACzF,KAAI,IAAI,KAAK,YACX,QAAO,IAAI,KAAK;AAElB,QAAO,IAAI,QAAQ,KAAK;EACtB,cAAc;EACd,SAAS;EACT,aAAa;EACd,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from "maltty";
|
|
2
|
+
|
|
3
|
+
//#region src/commands/build.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build a maltty CLI project for production.
|
|
6
|
+
*
|
|
7
|
+
* Loads the project's `maltty.config.ts`, invokes the bundler, and reports
|
|
8
|
+
* the output entry file and directory on success. When `--compile` or
|
|
9
|
+
* `--targets` is provided (or `compile` is set in config), also compiles
|
|
10
|
+
* to standalone binaries via Bun.
|
|
11
|
+
*/
|
|
12
|
+
declare const buildCommand: Command;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { buildCommand as default };
|
|
15
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","names":[],"sources":["../../src/commands/build.ts"],"mappings":";;;;;AAO6C;;;;;;cA0BvC,YAAA,EAAc,OAAA"}
|