@outfitter/cli 0.1.0-rc.1 → 0.1.0-rc.2
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/actions.d.ts +1 -12
- package/dist/actions.js +3 -170
- package/dist/cli.d.ts +2 -103
- package/dist/cli.js +4 -51
- package/dist/command.d.ts +2 -73
- package/dist/command.js +4 -42
- package/dist/index.d.ts +7 -606
- package/dist/index.js +11 -11
- package/dist/input.d.ts +2 -277
- package/dist/input.js +11 -426
- package/dist/output.d.ts +2 -68
- package/dist/output.js +4 -150
- package/dist/pagination.d.ts +2 -95
- package/dist/pagination.js +6 -84
- package/dist/render/colors.d.ts +2 -0
- package/dist/render/colors.js +17 -0
- package/dist/render/date.d.ts +2 -0
- package/dist/render/date.js +12 -0
- package/dist/render/format-relative.d.ts +2 -0
- package/dist/render/format-relative.js +8 -0
- package/dist/render/format.d.ts +2 -0
- package/dist/render/format.js +10 -0
- package/dist/render/index.d.ts +13 -0
- package/dist/render/index.js +101 -0
- package/dist/render/json.d.ts +2 -0
- package/dist/render/json.js +10 -0
- package/dist/render/list.d.ts +2 -0
- package/dist/render/list.js +8 -0
- package/dist/render/markdown.d.ts +2 -0
- package/dist/render/markdown.js +10 -0
- package/dist/render/progress.d.ts +2 -0
- package/dist/render/progress.js +8 -0
- package/dist/render/shapes.d.ts +2 -0
- package/dist/render/shapes.js +34 -0
- package/dist/render/table.d.ts +2 -0
- package/dist/render/table.js +11 -0
- package/dist/render/text.d.ts +2 -0
- package/dist/render/text.js +24 -0
- package/dist/render/tree.d.ts +2 -0
- package/dist/render/tree.js +8 -0
- package/dist/shared/@outfitter/cli-2vs2gxa8.js +429 -0
- package/dist/shared/@outfitter/cli-2y3kxew8.d.ts +58 -0
- package/dist/shared/@outfitter/cli-2yq94zst.d.ts +39 -0
- package/dist/shared/@outfitter/cli-33e97cjs.d.ts +42 -0
- package/dist/shared/@outfitter/cli-3hp8qwx3.js +11 -0
- package/dist/shared/@outfitter/cli-6xc869x1.js +26 -0
- package/dist/shared/@outfitter/cli-72kg550t.d.ts +53 -0
- package/dist/shared/@outfitter/cli-7km1e58p.js +85 -0
- package/dist/shared/@outfitter/cli-7na6p4fs.d.ts +59 -0
- package/dist/shared/@outfitter/cli-8aa1vhdn.d.ts +119 -0
- package/dist/shared/@outfitter/cli-8j5k6mr3.js +71 -0
- package/dist/shared/@outfitter/cli-8r0bnyyx.js +43 -0
- package/dist/shared/@outfitter/cli-a4q87517.d.ts +64 -0
- package/dist/shared/@outfitter/cli-afecwfrn.d.ts +13 -0
- package/dist/shared/@outfitter/cli-ag0w4pk0.js +89 -0
- package/dist/shared/@outfitter/cli-azzk8a1d.js +59 -0
- package/dist/shared/@outfitter/cli-bc17qeh2.js +19 -0
- package/dist/shared/@outfitter/cli-bt423m6y.js +4 -0
- package/dist/shared/@outfitter/cli-c8q4f71g.js +144 -0
- package/dist/shared/@outfitter/cli-c9knfqn5.d.ts +30 -0
- package/dist/shared/@outfitter/cli-cf2s94s1.d.ts +42 -0
- package/dist/shared/@outfitter/cli-d4fegbad.d.ts +66 -0
- package/dist/shared/@outfitter/cli-dds0qqvm.d.ts +145 -0
- package/dist/shared/@outfitter/cli-e0ecw3x1.js +64 -0
- package/dist/shared/@outfitter/cli-efy6jfcj.js +52 -0
- package/dist/shared/@outfitter/cli-evx7qcp1.d.ts +300 -0
- package/dist/shared/@outfitter/cli-fheaaa6b.js +25 -0
- package/dist/shared/@outfitter/cli-j19a91ck.js +30 -0
- package/dist/shared/@outfitter/cli-j361wp3g.d.ts +41 -0
- package/dist/shared/@outfitter/cli-jbj78ac5.js +70 -0
- package/dist/shared/@outfitter/cli-mhamvbty.d.ts +34 -0
- package/dist/shared/@outfitter/cli-n51t773m.d.ts +208 -0
- package/dist/shared/@outfitter/cli-p0m2fc51.js +172 -0
- package/dist/shared/@outfitter/cli-ttt7r0j7.d.ts +253 -0
- package/dist/shared/@outfitter/cli-tyajr8qa.d.ts +63 -0
- package/dist/shared/@outfitter/cli-v9mjsvjh.js +118 -0
- package/dist/shared/@outfitter/cli-wqc652mx.js +135 -0
- package/dist/shared/@outfitter/cli-zact3325.js +152 -0
- package/dist/shared/@outfitter/cli-zs6jy1am.d.ts +164 -0
- package/dist/shared/@outfitter/cli-zx598p8q.d.ts +26 -0
- package/dist/terminal/detection.d.ts +2 -0
- package/dist/terminal/detection.js +20 -0
- package/dist/terminal/index.d.ts +2 -0
- package/dist/terminal/index.js +20 -0
- package/dist/types.d.ts +1 -252
- package/dist/types.js +1 -1
- package/package.json +98 -4
- package/dist/shared/@outfitter/cli-4yy82cmp.js +0 -20
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
renderTree
|
|
4
|
+
} from "./cli-6xc869x1.js";
|
|
5
|
+
import {
|
|
6
|
+
renderList
|
|
7
|
+
} from "./cli-fheaaa6b.js";
|
|
8
|
+
import {
|
|
9
|
+
renderTable
|
|
10
|
+
} from "./cli-e0ecw3x1.js";
|
|
11
|
+
import {
|
|
12
|
+
renderJson,
|
|
13
|
+
renderText
|
|
14
|
+
} from "./cli-3hp8qwx3.js";
|
|
15
|
+
import {
|
|
16
|
+
renderMarkdown
|
|
17
|
+
} from "./cli-azzk8a1d.js";
|
|
18
|
+
|
|
19
|
+
// packages/cli/src/render/shapes.ts
|
|
20
|
+
function isCollection(shape) {
|
|
21
|
+
return shape.type === "collection";
|
|
22
|
+
}
|
|
23
|
+
function isHierarchy(shape) {
|
|
24
|
+
return shape.type === "hierarchy";
|
|
25
|
+
}
|
|
26
|
+
function isKeyValue(shape) {
|
|
27
|
+
return shape.type === "keyvalue";
|
|
28
|
+
}
|
|
29
|
+
function isResource(shape) {
|
|
30
|
+
return shape.type === "resource";
|
|
31
|
+
}
|
|
32
|
+
function treeNodeToRecord(node) {
|
|
33
|
+
if (node.children.length === 0) {
|
|
34
|
+
return { [node.name]: null };
|
|
35
|
+
}
|
|
36
|
+
const childRecord = {};
|
|
37
|
+
for (const child of node.children) {
|
|
38
|
+
const childObj = treeNodeToRecord(child);
|
|
39
|
+
Object.assign(childRecord, childObj);
|
|
40
|
+
}
|
|
41
|
+
return { [node.name]: childRecord };
|
|
42
|
+
}
|
|
43
|
+
function isPlainObject(item) {
|
|
44
|
+
return item !== null && typeof item === "object" && !Array.isArray(item);
|
|
45
|
+
}
|
|
46
|
+
var customRenderers = new Map;
|
|
47
|
+
function registerRenderer(shapeType, renderer) {
|
|
48
|
+
customRenderers.set(shapeType, renderer);
|
|
49
|
+
}
|
|
50
|
+
function unregisterRenderer(shapeType) {
|
|
51
|
+
return customRenderers.delete(shapeType);
|
|
52
|
+
}
|
|
53
|
+
function clearRenderers() {
|
|
54
|
+
customRenderers.clear();
|
|
55
|
+
}
|
|
56
|
+
function render(shape, options) {
|
|
57
|
+
const customRenderer = customRenderers.get(shape.type);
|
|
58
|
+
if (customRenderer) {
|
|
59
|
+
return customRenderer(shape, options);
|
|
60
|
+
}
|
|
61
|
+
const format = options?.format;
|
|
62
|
+
if (format === "json") {
|
|
63
|
+
if (isCollection(shape)) {
|
|
64
|
+
return renderJson(shape.items);
|
|
65
|
+
}
|
|
66
|
+
if (isHierarchy(shape)) {
|
|
67
|
+
return renderJson(treeNodeToRecord(shape.root));
|
|
68
|
+
}
|
|
69
|
+
if (isKeyValue(shape)) {
|
|
70
|
+
return renderJson(shape.entries);
|
|
71
|
+
}
|
|
72
|
+
if (isResource(shape)) {
|
|
73
|
+
return renderJson(shape.data);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (format === "list" && isCollection(shape)) {
|
|
77
|
+
const listItems = shape.items.map((item) => {
|
|
78
|
+
if (typeof item === "string") {
|
|
79
|
+
return item;
|
|
80
|
+
}
|
|
81
|
+
if (isPlainObject(item)) {
|
|
82
|
+
const name = item.name;
|
|
83
|
+
if (typeof name === "string") {
|
|
84
|
+
return name;
|
|
85
|
+
}
|
|
86
|
+
return JSON.stringify(item);
|
|
87
|
+
}
|
|
88
|
+
return String(item);
|
|
89
|
+
});
|
|
90
|
+
return renderList(listItems);
|
|
91
|
+
}
|
|
92
|
+
if (format === "table" && isCollection(shape)) {
|
|
93
|
+
const items = shape.items.filter(isPlainObject);
|
|
94
|
+
return renderTable(items, shape.headers ? { headers: shape.headers } : undefined);
|
|
95
|
+
}
|
|
96
|
+
if (format === "tree" && isHierarchy(shape)) {
|
|
97
|
+
return renderTree(treeNodeToRecord(shape.root));
|
|
98
|
+
}
|
|
99
|
+
if (format === "text" && isResource(shape)) {
|
|
100
|
+
return renderText(String(shape.data));
|
|
101
|
+
}
|
|
102
|
+
if (isCollection(shape)) {
|
|
103
|
+
const hasObjectItems = shape.items.every(isPlainObject);
|
|
104
|
+
if (hasObjectItems) {
|
|
105
|
+
const items = shape.items;
|
|
106
|
+
return renderTable(items, shape.headers ? { headers: shape.headers } : undefined);
|
|
107
|
+
}
|
|
108
|
+
const listItems = shape.items.map((item) => {
|
|
109
|
+
if (typeof item === "string") {
|
|
110
|
+
return item;
|
|
111
|
+
}
|
|
112
|
+
return String(item);
|
|
113
|
+
});
|
|
114
|
+
return renderList(listItems);
|
|
115
|
+
}
|
|
116
|
+
if (isHierarchy(shape)) {
|
|
117
|
+
return renderTree(treeNodeToRecord(shape.root));
|
|
118
|
+
}
|
|
119
|
+
if (isKeyValue(shape)) {
|
|
120
|
+
return renderJson(shape.entries);
|
|
121
|
+
}
|
|
122
|
+
if (isResource(shape)) {
|
|
123
|
+
const resourceFormat = shape.format ?? "json";
|
|
124
|
+
if (resourceFormat === "markdown") {
|
|
125
|
+
return renderMarkdown(String(shape.data));
|
|
126
|
+
}
|
|
127
|
+
if (resourceFormat === "text") {
|
|
128
|
+
return renderText(String(shape.data));
|
|
129
|
+
}
|
|
130
|
+
return renderJson(shape.data);
|
|
131
|
+
}
|
|
132
|
+
return renderJson(shape);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { isCollection, isHierarchy, isKeyValue, isResource, treeNodeToRecord, isPlainObject, registerRenderer, unregisterRenderer, clearRenderers, render };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/output.ts
|
|
3
|
+
import {
|
|
4
|
+
safeStringify as contractsSafeStringify,
|
|
5
|
+
exitCodeMap
|
|
6
|
+
} from "@outfitter/contracts";
|
|
7
|
+
var DEFAULT_EXIT_CODE = 1;
|
|
8
|
+
function writeWithBackpressure(stream, data) {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const canContinue = stream.write(data, (error) => {
|
|
11
|
+
if (error)
|
|
12
|
+
reject(error);
|
|
13
|
+
});
|
|
14
|
+
if (canContinue) {
|
|
15
|
+
resolve();
|
|
16
|
+
} else {
|
|
17
|
+
stream.once("drain", () => resolve());
|
|
18
|
+
stream.once("error", reject);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function detectMode(options) {
|
|
23
|
+
if (options?.mode) {
|
|
24
|
+
return options.mode;
|
|
25
|
+
}
|
|
26
|
+
const envJsonl = process.env["OUTFITTER_JSONL"];
|
|
27
|
+
const envJson = process.env["OUTFITTER_JSON"];
|
|
28
|
+
if (envJsonl === "1")
|
|
29
|
+
return "jsonl";
|
|
30
|
+
if (envJson === "1")
|
|
31
|
+
return "json";
|
|
32
|
+
if (envJsonl === "0" || envJson === "0")
|
|
33
|
+
return "human";
|
|
34
|
+
return process.stdout.isTTY ? "human" : "json";
|
|
35
|
+
}
|
|
36
|
+
function isValidCategory(category) {
|
|
37
|
+
return category in exitCodeMap;
|
|
38
|
+
}
|
|
39
|
+
function safeStringify(value, pretty) {
|
|
40
|
+
const wrappedValue = value === undefined ? null : value;
|
|
41
|
+
return contractsSafeStringify(wrappedValue, pretty ? 2 : undefined);
|
|
42
|
+
}
|
|
43
|
+
function formatHuman(data) {
|
|
44
|
+
if (data === null || data === undefined) {
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
if (typeof data === "string") {
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
if (typeof data === "number" || typeof data === "boolean") {
|
|
51
|
+
return String(data);
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(data)) {
|
|
54
|
+
return data.map((item) => formatHuman(item)).join(`
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
if (typeof data === "object") {
|
|
58
|
+
const lines = [];
|
|
59
|
+
for (const [key, value] of Object.entries(data)) {
|
|
60
|
+
lines.push(`${key}: ${formatHuman(value)}`);
|
|
61
|
+
}
|
|
62
|
+
return lines.join(`
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
return String(data);
|
|
66
|
+
}
|
|
67
|
+
function getErrorProperties(error) {
|
|
68
|
+
const errorObj = error;
|
|
69
|
+
return {
|
|
70
|
+
_tag: errorObj._tag,
|
|
71
|
+
category: errorObj.category,
|
|
72
|
+
context: errorObj.context
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function getExitCode(error) {
|
|
76
|
+
const { category } = getErrorProperties(error);
|
|
77
|
+
if (category !== undefined && isValidCategory(category)) {
|
|
78
|
+
return exitCodeMap[category];
|
|
79
|
+
}
|
|
80
|
+
return DEFAULT_EXIT_CODE;
|
|
81
|
+
}
|
|
82
|
+
function serializeErrorToJson(error) {
|
|
83
|
+
const { _tag, category, context } = getErrorProperties(error);
|
|
84
|
+
const result = {
|
|
85
|
+
message: error.message
|
|
86
|
+
};
|
|
87
|
+
if (_tag !== undefined) {
|
|
88
|
+
result._tag = _tag;
|
|
89
|
+
}
|
|
90
|
+
if (category !== undefined) {
|
|
91
|
+
result.category = category;
|
|
92
|
+
}
|
|
93
|
+
if (context !== undefined) {
|
|
94
|
+
result.context = context;
|
|
95
|
+
}
|
|
96
|
+
return JSON.stringify(result);
|
|
97
|
+
}
|
|
98
|
+
function formatErrorHuman(error) {
|
|
99
|
+
const { _tag } = getErrorProperties(error);
|
|
100
|
+
if (_tag) {
|
|
101
|
+
return `${_tag}: ${error.message}`;
|
|
102
|
+
}
|
|
103
|
+
return error.message;
|
|
104
|
+
}
|
|
105
|
+
async function output(data, options) {
|
|
106
|
+
const mode = detectMode(options);
|
|
107
|
+
const stream = options?.stream ?? process.stdout;
|
|
108
|
+
let outputText;
|
|
109
|
+
switch (mode) {
|
|
110
|
+
case "json": {
|
|
111
|
+
const jsonData = data === undefined ? null : data;
|
|
112
|
+
outputText = safeStringify(jsonData, options?.pretty);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "jsonl": {
|
|
116
|
+
if (Array.isArray(data)) {
|
|
117
|
+
if (data.length === 0) {
|
|
118
|
+
outputText = "";
|
|
119
|
+
} else {
|
|
120
|
+
outputText = data.map((item) => safeStringify(item)).join(`
|
|
121
|
+
`);
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
outputText = safeStringify(data);
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
default: {
|
|
129
|
+
outputText = formatHuman(data);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (outputText) {
|
|
134
|
+
await writeWithBackpressure(stream, `${outputText}
|
|
135
|
+
`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function exitWithError(error, options) {
|
|
139
|
+
const exitCode = getExitCode(error);
|
|
140
|
+
const mode = detectMode(options);
|
|
141
|
+
const isJsonMode = mode === "json" || mode === "jsonl";
|
|
142
|
+
if (isJsonMode) {
|
|
143
|
+
process.stderr.write(`${serializeErrorToJson(error)}
|
|
144
|
+
`);
|
|
145
|
+
} else {
|
|
146
|
+
process.stderr.write(`${formatErrorHuman(error)}
|
|
147
|
+
`);
|
|
148
|
+
}
|
|
149
|
+
process.exit(exitCode);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export { output, exitWithError };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { CollectIdsOptions, ConfirmDestructiveOptions, ExpandFileOptions, FilterExpression, KeyValuePair, NormalizeIdOptions, ParseGlobOptions, Range, SortCriteria } from "./cli-ttt7r0j7";
|
|
2
|
+
import { CancelledError, ValidationError } from "@outfitter/contracts";
|
|
3
|
+
import { Result } from "better-result";
|
|
4
|
+
/**
|
|
5
|
+
* Collect IDs from various input formats.
|
|
6
|
+
*
|
|
7
|
+
* Handles space-separated, comma-separated, repeated flags, @file, and stdin.
|
|
8
|
+
*
|
|
9
|
+
* @param input - Raw input from CLI arguments
|
|
10
|
+
* @param options - Collection options
|
|
11
|
+
* @returns Array of collected IDs
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // All these produce the same result:
|
|
16
|
+
* // wm show id1 id2 id3
|
|
17
|
+
* // wm show id1,id2,id3
|
|
18
|
+
* // wm show --ids id1 --ids id2
|
|
19
|
+
* // wm show @ids.txt
|
|
20
|
+
* const ids = await collectIds(args.ids, {
|
|
21
|
+
* allowFile: true,
|
|
22
|
+
* allowStdin: true,
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare function collectIds(input: string | readonly string[], options?: CollectIdsOptions): Promise<string[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Expand @file references to file contents.
|
|
29
|
+
*
|
|
30
|
+
* If the input starts with @, reads the file and returns its contents.
|
|
31
|
+
* Otherwise, returns the input unchanged.
|
|
32
|
+
*
|
|
33
|
+
* @param input - Raw input that may be a @file reference
|
|
34
|
+
* @param options - Expansion options
|
|
35
|
+
* @returns File contents or original input
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // wm create @template.md
|
|
40
|
+
* const content = await expandFileArg(args.content);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function expandFileArg(input: string, options?: ExpandFileOptions): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Parse and expand glob patterns.
|
|
46
|
+
*
|
|
47
|
+
* Uses Bun.Glob with workspace constraints.
|
|
48
|
+
*
|
|
49
|
+
* @param pattern - Glob pattern to expand
|
|
50
|
+
* @param options - Glob options
|
|
51
|
+
* @returns Array of matched file paths
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // wm index "src/**\/*.ts"
|
|
56
|
+
* const files = await parseGlob(args.pattern, {
|
|
57
|
+
* cwd: workspaceRoot,
|
|
58
|
+
* ignore: ["node_modules/**"],
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
declare function parseGlob(pattern: string, options?: ParseGlobOptions): Promise<string[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Parse key=value pairs from CLI input.
|
|
65
|
+
*
|
|
66
|
+
* @param input - Raw input containing key=value pairs
|
|
67
|
+
* @returns Array of parsed key-value pairs
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // --set key=value --set key2=value2
|
|
72
|
+
* // --set key=value,key2=value2
|
|
73
|
+
* const pairs = parseKeyValue(args.set);
|
|
74
|
+
* // => [{ key: "key", value: "value" }, { key: "key2", value: "value2" }]
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function parseKeyValue(input: string | readonly string[]): Result<KeyValuePair[], InstanceType<typeof ValidationError>>;
|
|
78
|
+
/**
|
|
79
|
+
* Parse range inputs (numeric or date).
|
|
80
|
+
*
|
|
81
|
+
* @param input - Range string (e.g., "1-10" or "2024-01-01..2024-12-31")
|
|
82
|
+
* @param type - Type of range to parse
|
|
83
|
+
* @returns Parsed range
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* parseRange("1-10", "number");
|
|
88
|
+
* // => Result<{ type: "number", min: 1, max: 10 }, ValidationError>
|
|
89
|
+
*
|
|
90
|
+
* parseRange("2024-01-01..2024-12-31", "date");
|
|
91
|
+
* // => Result<{ type: "date", start: Date, end: Date }, ValidationError>
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
declare function parseRange(input: string, type: "number" | "date"): Result<Range, InstanceType<typeof ValidationError>>;
|
|
95
|
+
/**
|
|
96
|
+
* Parse filter expressions from CLI input.
|
|
97
|
+
*
|
|
98
|
+
* @param input - Filter string (e.g., "status:active,priority:high")
|
|
99
|
+
* @returns Array of parsed filter expressions
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* parseFilter("status:active,priority:high");
|
|
104
|
+
* // => Result<[
|
|
105
|
+
* // { field: "status", value: "active" },
|
|
106
|
+
* // { field: "priority", value: "high" }
|
|
107
|
+
* // ], ValidationError>
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare function parseFilter(input: string): Result<FilterExpression[], InstanceType<typeof ValidationError>>;
|
|
111
|
+
/**
|
|
112
|
+
* Parse sort specification from CLI input.
|
|
113
|
+
*
|
|
114
|
+
* @param input - Sort string (e.g., "modified:desc,title:asc")
|
|
115
|
+
* @returns Array of parsed sort criteria
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* parseSortSpec("modified:desc,title:asc");
|
|
120
|
+
* // => Result<[
|
|
121
|
+
* // { field: "modified", direction: "desc" },
|
|
122
|
+
* // { field: "title", direction: "asc" }
|
|
123
|
+
* // ], ValidationError>
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
declare function parseSortSpec(input: string): Result<SortCriteria[], InstanceType<typeof ValidationError>>;
|
|
127
|
+
/**
|
|
128
|
+
* Normalize an identifier (trim, lowercase where appropriate).
|
|
129
|
+
*
|
|
130
|
+
* @param input - Raw identifier input
|
|
131
|
+
* @param options - Normalization options
|
|
132
|
+
* @returns Normalized identifier
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* normalizeId(" MY-ID ", { lowercase: true, trim: true });
|
|
137
|
+
* // => Result<"my-id", ValidationError>
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
declare function normalizeId(input: string, options?: NormalizeIdOptions): Result<string, InstanceType<typeof ValidationError>>;
|
|
141
|
+
/**
|
|
142
|
+
* Prompt for confirmation before destructive operations.
|
|
143
|
+
*
|
|
144
|
+
* Respects --yes flag for non-interactive mode.
|
|
145
|
+
*
|
|
146
|
+
* @param options - Confirmation options
|
|
147
|
+
* @returns Whether the user confirmed
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const confirmed = await confirmDestructive({
|
|
152
|
+
* message: "Delete 5 notes?",
|
|
153
|
+
* bypassFlag: flags.yes,
|
|
154
|
+
* itemCount: 5,
|
|
155
|
+
* });
|
|
156
|
+
*
|
|
157
|
+
* if (confirmed.isErr()) {
|
|
158
|
+
* // User cancelled
|
|
159
|
+
* process.exit(0);
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
declare function confirmDestructive(options: ConfirmDestructiveOptions): Promise<Result<boolean, InstanceType<typeof CancelledError>>>;
|
|
164
|
+
export { collectIds, expandFileArg, parseGlob, parseKeyValue, parseRange, parseFilter, parseSortSpec, normalizeId, confirmDestructive };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date and time formatting utilities.
|
|
3
|
+
*
|
|
4
|
+
* Provides human-friendly relative time formatting.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Formats a date as a human-friendly relative time string.
|
|
10
|
+
*
|
|
11
|
+
* Converts timestamps to natural language like "just now", "5 minutes ago",
|
|
12
|
+
* "yesterday", or "in 3 hours". Handles both past and future dates.
|
|
13
|
+
*
|
|
14
|
+
* @param date - Date to format (Date object, timestamp number, or ISO string)
|
|
15
|
+
* @returns Human-friendly relative time string
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* formatRelative(new Date()) // "just now"
|
|
20
|
+
* formatRelative(Date.now() - 30000) // "30 seconds ago"
|
|
21
|
+
* formatRelative(Date.now() - 3600000) // "1 hour ago"
|
|
22
|
+
* formatRelative(Date.now() + 300000) // "in 5 minutes"
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
declare function formatRelative(date: Date | number | string): string;
|
|
26
|
+
export { formatRelative };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { TerminalOptions, getEnvValue, getTerminalWidth, hasNoColorEnv, isInteractive, resolveColorEnv, resolveForceColorEnv, supportsColor } from "../shared/@outfitter/cli-8aa1vhdn";
|
|
2
|
+
export { supportsColor, resolveForceColorEnv, resolveColorEnv, isInteractive, hasNoColorEnv, getTerminalWidth, getEnvValue, TerminalOptions };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getEnvValue,
|
|
4
|
+
getTerminalWidth,
|
|
5
|
+
hasNoColorEnv,
|
|
6
|
+
isInteractive,
|
|
7
|
+
resolveColorEnv,
|
|
8
|
+
resolveForceColorEnv,
|
|
9
|
+
supportsColor
|
|
10
|
+
} from "../shared/@outfitter/cli-jbj78ac5.js";
|
|
11
|
+
import"../shared/@outfitter/cli-bt423m6y.js";
|
|
12
|
+
export {
|
|
13
|
+
supportsColor,
|
|
14
|
+
resolveForceColorEnv,
|
|
15
|
+
resolveColorEnv,
|
|
16
|
+
isInteractive,
|
|
17
|
+
hasNoColorEnv,
|
|
18
|
+
getTerminalWidth,
|
|
19
|
+
getEnvValue
|
|
20
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { TerminalOptions, getEnvValue, getTerminalWidth, hasNoColorEnv, isInteractive, resolveColorEnv, resolveForceColorEnv, supportsColor } from "../shared/@outfitter/cli-8aa1vhdn";
|
|
2
|
+
export { supportsColor, resolveForceColorEnv, resolveColorEnv, isInteractive, hasNoColorEnv, getTerminalWidth, getEnvValue, TerminalOptions };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getEnvValue,
|
|
4
|
+
getTerminalWidth,
|
|
5
|
+
hasNoColorEnv,
|
|
6
|
+
isInteractive,
|
|
7
|
+
resolveColorEnv,
|
|
8
|
+
resolveForceColorEnv,
|
|
9
|
+
supportsColor
|
|
10
|
+
} from "../shared/@outfitter/cli-jbj78ac5.js";
|
|
11
|
+
import"../shared/@outfitter/cli-bt423m6y.js";
|
|
12
|
+
export {
|
|
13
|
+
supportsColor,
|
|
14
|
+
resolveForceColorEnv,
|
|
15
|
+
resolveColorEnv,
|
|
16
|
+
isInteractive,
|
|
17
|
+
hasNoColorEnv,
|
|
18
|
+
getTerminalWidth,
|
|
19
|
+
getEnvValue
|
|
20
|
+
};
|