1ls 0.0.2 → 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 +133 -12
- package/dist/browser/constants.d.ts +3 -0
- package/dist/browser/index.d.ts +15 -0
- package/dist/browser/index.js +15 -0
- package/dist/cli/constants.d.ts +2 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/completions/1ls.bash +63 -0
- package/dist/completions/1ls.zsh +79 -0
- package/dist/completions/install-completions.sh +52 -0
- package/dist/expression/utils.d.ts +2 -1
- package/dist/formats/constants.d.ts +19 -0
- package/dist/formats/ini.d.ts +3 -0
- package/dist/formats/javascript.d.ts +6 -0
- package/dist/formats/json5.d.ts +6 -0
- package/dist/formats/utils.d.ts +3 -3
- package/dist/formatter/colors.d.ts +18 -0
- package/dist/formatter/output.d.ts +1 -1
- package/dist/index.js +85 -42
- package/dist/interactive/app.d.ts +1 -0
- package/dist/interactive/builder.d.ts +10 -0
- package/dist/interactive/fuzzy.d.ts +6 -0
- package/dist/interactive/input.d.ts +7 -0
- package/dist/interactive/methods.d.ts +12 -0
- package/dist/interactive/navigator.d.ts +2 -0
- package/dist/interactive/renderer-builder.d.ts +3 -0
- package/dist/interactive/renderer.d.ts +3 -0
- package/dist/interactive/state.d.ts +5 -0
- package/dist/interactive/terminal.d.ts +21 -0
- package/dist/interactive/types.d.ts +45 -0
- package/dist/navigator/json.d.ts +1 -0
- package/dist/shared/constants.d.ts +6 -0
- package/dist/types.d.ts +2 -0
- package/package.json +40 -13
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Jeff Wainwright
|
|
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
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
# 1ls
|
|
1
|
+
# 1ls
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/yowainwright/1ls/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/yowainwright/1ls)
|
|
5
|
+
|
|
6
|
+
> One-line script
|
|
7
|
+
|
|
8
|
+
A 0 dependency, lightweight, fast data processor with familiar JavaScript syntax.
|
|
9
|
+
|
|
10
|
+
This is useful for writing 1ls, one-line scripts, in the terminal or for short scripts
|
|
11
|
+
that are as concise as possible in a familiar syntax, JavaScript, with dot notation,
|
|
12
|
+
fuzzy matching, and shortening capabilities for maximum efficiency.
|
|
13
|
+
|
|
14
|
+
On top of that, the library is very small because it has no dependencies.
|
|
15
|
+
And, it is compiled with QuickJs for binary builds.
|
|
16
|
+
This means you get good speed compared to jq and fx but it's still, just JS,
|
|
17
|
+
the language y'all know.
|
|
4
18
|
|
|
5
19
|
## Why 1ls?
|
|
6
20
|
|
|
@@ -14,14 +28,15 @@ A 0 dependency, lightweight, fast data processor with family JavaScript syntax.
|
|
|
14
28
|
## Installation
|
|
15
29
|
|
|
16
30
|
```bash
|
|
17
|
-
# Using
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# Using npm
|
|
21
|
-
npm install -g 1ls
|
|
31
|
+
# Using bun (or npm, pnpm, etc)
|
|
32
|
+
# works in the commandline or the web
|
|
33
|
+
bun add -g 1ls
|
|
22
34
|
|
|
35
|
+
# Or via binaries. here you get a QuickJs build
|
|
36
|
+
# Using Homebrew (macOS/Linux)
|
|
37
|
+
brew install yowainwright/1ls/1ls
|
|
23
38
|
# Using curl
|
|
24
|
-
curl -fsSL https://raw.githubusercontent.com/yowainwright/1ls/main/install.sh | bash
|
|
39
|
+
curl -fsSL https://raw.githubusercontent.com/yowainwright/1ls/main/scripts/install.sh | bash
|
|
25
40
|
```
|
|
26
41
|
|
|
27
42
|
## Quick Start
|
|
@@ -42,10 +57,94 @@ echo '[1, 2, 3]' | 1ls '.map(x => x * 2)'
|
|
|
42
57
|
# Chain operations
|
|
43
58
|
echo '[{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]' | 1ls '.filter(x => x.age > 26).map(x => x.name)'
|
|
44
59
|
# Output: ["Alice"]
|
|
60
|
+
|
|
61
|
+
# Interactive mode - explore JSON with fuzzy search
|
|
62
|
+
1ls readFile data.json
|
|
63
|
+
# Opens interactive explorer with fuzzy search, arrow key navigation, and live preview
|
|
45
64
|
```
|
|
46
65
|
|
|
47
66
|
## Examples
|
|
48
67
|
|
|
68
|
+
### Interactive Mode
|
|
69
|
+
|
|
70
|
+
Explore JSON interactively with fuzzy search and build expressions with method discovery:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Open interactive explorer from a file (automatic when no expression)
|
|
74
|
+
1ls readFile data.json
|
|
75
|
+
|
|
76
|
+
# Works with all supported formats
|
|
77
|
+
1ls readFile config.yaml
|
|
78
|
+
1ls readFile config.toml
|
|
79
|
+
|
|
80
|
+
# For remote data, save to a file first
|
|
81
|
+
curl https://api.github.com/users/github > /tmp/user.json
|
|
82
|
+
1ls readFile /tmp/user.json
|
|
83
|
+
|
|
84
|
+
# Or use an expression directly (non-interactive)
|
|
85
|
+
1ls readFile data.json '.users.filter(x => x.active)'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Mode 1: Path Explorer
|
|
89
|
+
|
|
90
|
+
Navigate and search JSON paths:
|
|
91
|
+
|
|
92
|
+
- **Fuzzy search**: Type to filter paths (e.g., "user.name" matches `.users[0].name`, `.user.username`, etc.)
|
|
93
|
+
- **Live preview**: See values as you navigate
|
|
94
|
+
- **Type information**: Shows String, Number, Array, Object, Boolean, or null
|
|
95
|
+
- **↑/↓**: Navigate, **Enter**: Select, **Tab**: Build expression, **Esc/q**: Quit
|
|
96
|
+
|
|
97
|
+
#### Mode 2: Expression Builder
|
|
98
|
+
|
|
99
|
+
Build complex expressions with guided method selection:
|
|
100
|
+
|
|
101
|
+
**Workflow:**
|
|
102
|
+
1. Navigate to a path in Explorer mode → Press **Tab**
|
|
103
|
+
2. Type to fuzzy search methods → **→** to accept
|
|
104
|
+
3. Type to fuzzy search properties → **→** to complete
|
|
105
|
+
4. Repeat to chain methods
|
|
106
|
+
5. Press **Enter** to execute
|
|
107
|
+
|
|
108
|
+
**Example Session:**
|
|
109
|
+
```
|
|
110
|
+
1. Navigate to .users (Array) → Tab
|
|
111
|
+
2. Type "fil" → → (accepts .filter(x => ...))
|
|
112
|
+
3. Type "act" → → (completes with x.active, back to method selection)
|
|
113
|
+
4. Type "map" → → (accepts .map(x => ...))
|
|
114
|
+
5. Type "name" → → (completes with x.name)
|
|
115
|
+
6. Enter → executes: .users.filter(x => x.active).map(x => x.name)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Undo mistakes:**
|
|
119
|
+
- Press **←** at any time to undo the last segment
|
|
120
|
+
- Example: `.users.filter(x => x.active).map(x => x.name)` → **←** → `.users.filter(x => x.active)`
|
|
121
|
+
|
|
122
|
+
**Available Methods by Type:**
|
|
123
|
+
|
|
124
|
+
**Array**: map, filter, reduce, find, findIndex, some, every, sort, reverse, slice, concat, join, flat, flatMap, length
|
|
125
|
+
|
|
126
|
+
**String**: toUpperCase, toLowerCase, trim, trimStart, trimEnd, split, replace, replaceAll, substring, slice, startsWith, endsWith, includes, match, length
|
|
127
|
+
|
|
128
|
+
**Object**: {keys}, {values}, {entries}, {length}
|
|
129
|
+
|
|
130
|
+
**Number**: toFixed, toString
|
|
131
|
+
|
|
132
|
+
**Keyboard Shortcuts:**
|
|
133
|
+
- **↑/↓**: Navigate methods/properties
|
|
134
|
+
- **→ or Tab**: Accept/complete method or property (autocomplete-style)
|
|
135
|
+
- **←**: Undo last segment (remove to previous dot)
|
|
136
|
+
- **Enter**: Execute expression
|
|
137
|
+
- **Type**: Fuzzy search methods/properties
|
|
138
|
+
- **Esc**: Go back to Explorer / Quit
|
|
139
|
+
- **q**: Quit (from Explorer)
|
|
140
|
+
|
|
141
|
+
**Use cases:**
|
|
142
|
+
- Exploring unfamiliar API responses
|
|
143
|
+
- Building filter/map chains interactively
|
|
144
|
+
- Discovering available methods for each type
|
|
145
|
+
- Learning JavaScript array/string methods
|
|
146
|
+
- Prototyping complex data transformations
|
|
147
|
+
|
|
49
148
|
### Working with JSON
|
|
50
149
|
|
|
51
150
|
```bash
|
|
@@ -180,6 +279,7 @@ echo '["a", "b"]' | 1ls '.jn(",")' # Short for .join()
|
|
|
180
279
|
|--------|-------|-------------|
|
|
181
280
|
| `--help` | `-h` | Show help |
|
|
182
281
|
| `--version` | `-v` | Show version |
|
|
282
|
+
| `--interactive` | | Interactive fuzzy search explorer |
|
|
183
283
|
| `--raw` | `-r` | Output raw strings, not JSON |
|
|
184
284
|
| `--pretty` | `-p` | Pretty print output |
|
|
185
285
|
| `--compact` | `-c` | Compact output |
|
|
@@ -317,6 +417,26 @@ done
|
|
|
317
417
|
- Efficient streaming for large files
|
|
318
418
|
- Native binary compilation
|
|
319
419
|
|
|
420
|
+
## Development
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
# Clone the repository
|
|
424
|
+
git clone https://github.com/yowainwright/1ls.git
|
|
425
|
+
cd 1ls
|
|
426
|
+
|
|
427
|
+
# Install dependencies
|
|
428
|
+
bun install
|
|
429
|
+
|
|
430
|
+
# Run tests
|
|
431
|
+
bun test
|
|
432
|
+
|
|
433
|
+
# Build
|
|
434
|
+
bun run build
|
|
435
|
+
|
|
436
|
+
# Build binaries
|
|
437
|
+
bun run build:binary:all
|
|
438
|
+
```
|
|
439
|
+
|
|
320
440
|
## Contributing
|
|
321
441
|
|
|
322
442
|
Contributions are welcome! Please check out the [Contributing Guide](CONTRIBUTING.md).
|
|
@@ -332,10 +452,11 @@ MIT © Jeff Wainwright
|
|
|
332
452
|
| Syntax | JavaScript | DSL | JavaScript |
|
|
333
453
|
| Performance | ⚡ Fast (Bun) | ⚡ Fast | 🚀 Good |
|
|
334
454
|
| Learning Curve | Easy | Steep | Easy |
|
|
335
|
-
| Multi-format |
|
|
336
|
-
|
|
|
337
|
-
|
|
|
338
|
-
|
|
|
455
|
+
| Multi-format | ✓ | x | x |
|
|
456
|
+
| Interactive Mode | ✓ | x | ✓ |
|
|
457
|
+
| Shortcuts | ✓ | x | x |
|
|
458
|
+
| Arrow Functions | ✓ | x | ✓ |
|
|
459
|
+
| File Operations | ✓ | x | x |
|
|
339
460
|
|
|
340
461
|
## Troubleshooting
|
|
341
462
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Lexer } from "../lexer";
|
|
2
|
+
import { ExpressionParser } from "../expression";
|
|
3
|
+
import { JsonNavigator } from "../navigator/json";
|
|
4
|
+
import { parseYAML } from "../formats/yaml";
|
|
5
|
+
import { parseCSV } from "../formats/csv";
|
|
6
|
+
import { parseTOML } from "../formats/toml";
|
|
7
|
+
export { Lexer, ExpressionParser, JsonNavigator };
|
|
8
|
+
export { parseYAML, parseCSV, parseTOML };
|
|
9
|
+
export declare function escapeRegExp(str: string): string;
|
|
10
|
+
export declare const EXPAND_PATTERNS: {
|
|
11
|
+
regex: RegExp;
|
|
12
|
+
replacement: string;
|
|
13
|
+
}[];
|
|
14
|
+
export declare function expandShortcuts(expression: string): string;
|
|
15
|
+
export declare function evaluate(data: unknown, expression: string): unknown;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var q={".":"DOT","[":"LEFT_BRACKET","]":"RIGHT_BRACKET","{":"LEFT_BRACE","}":"RIGHT_BRACE","(":"LEFT_PAREN",")":"RIGHT_PAREN",":":"COLON",",":"COMMA"},z="+-*/%<>!&|=",Z=[" ","\t",`
|
|
2
|
+
`,"\r"];function O(t,e,n){return{type:t,value:e,position:n}}class _{input;position=0;current;constructor(t){this.input=t,this.current=this.input[0]||""}tokenize(){let t=[];while(this.position<this.input.length){if(this.skipWhitespace(),this.position>=this.input.length)break;let e=this.nextToken();if(e)t.push(e)}return t.push(O("EOF","",this.position)),t}nextToken(){let t=this.position,e=q[this.current];if(e){let h=this.current;return this.advance(),O(e,h,t)}if(this.current==="="&&this.peek()===">")return this.advance(),this.advance(),O("ARROW","=>",t);if(this.current==='"'||this.current==="'")return this.readString();let r=this.isDigit(this.current),o=this.current==="-"&&this.isDigit(this.peek());if(r||o)return this.readNumber();if(this.isIdentifierStart(this.current))return this.readIdentifier();if(this.isOperator(this.current))return this.readOperator();return this.advance(),null}readString(){let t=this.position,e=this.current,n=[];this.advance();while(this.current!==e&&this.position<this.input.length){if(this.current==="\\"){if(this.advance(),this.position<this.input.length)n.push(this.current),this.advance();continue}n.push(this.current),this.advance()}if(this.current===e)this.advance();return O("STRING",n.join(""),t)}readNumber(){let t=this.position,e="";if(this.current==="-")e+=this.current,this.advance();while(this.isDigit(this.current))e+=this.current,this.advance();if(this.current==="."&&this.isDigit(this.peek())){e+=this.current,this.advance();while(this.isDigit(this.current))e+=this.current,this.advance()}return O("NUMBER",e,t)}readIdentifier(){let t=this.position,e="";while(this.isIdentifierChar(this.current))e+=this.current,this.advance();return O("IDENTIFIER",e,t)}readOperator(){let t=this.position,e="";while(this.isOperator(this.current))e+=this.current,this.advance();return O("OPERATOR",e,t)}skipWhitespace(){while(this.isWhitespace(this.current))this.advance()}advance(){this.position++,this.current=this.input[this.position]||""}peek(){return this.input[this.position+1]||""}isWhitespace(t){return Z.includes(t)}isDigit(t){return t>="0"&&t<="9"}isIdentifierStart(t){let e=t>="a"&&t<="z",n=t>="A"&&t<="Z";return e||n||t==="_"||t==="$"}isIdentifierChar(t){return this.isIdentifierStart(t)||this.isDigit(t)}isOperator(t){return z.includes(t)}}var T=(t)=>{return{type:"Literal",value:t}},P=(t)=>{if(t==="true")return T(!0);if(t==="false")return T(!1);if(t==="null")return T(null);return};function E(t,e){return`${e} at position ${t.position} (got ${t.type}: "${t.value}")`}function b(t,e){return{type:"PropertyAccess",property:t,object:e}}function dt(t,e){return{type:"IndexAccess",index:t,object:e}}function ft(t,e,n){return{type:"SliceAccess",start:t,end:e,object:n}}function tt(t,e,n){return{type:"MethodCall",method:t,args:e,object:n}}function mt(t,e){return{type:"ObjectOperation",operation:t,object:e}}function At(t){return{type:"ArraySpread",object:t}}function yt(t,e){return{type:"ArrowFunction",params:t,body:e}}function I(t){return{type:"Root",expression:t}}var et=["keys","values","entries","length"];function gt(t){return et.includes(t)}class M{tokens;position=0;current;constructor(t){this.tokens=t,this.current=this.tokens[0]}parse(){if(this.current.type==="EOF")return I();let e=this.parseExpression();return I(e)}parseExpression(){return this.parsePrimary()}parsePrimary(){let t=this.parsePrimaryNode();return this.parsePostfix(t)}parsePrimaryNode(){let t=this.current.type;if(t==="DOT")return this.advance(),this.parseAccessChain();if(t==="LEFT_BRACKET")return this.parseArrayAccess();if(t==="IDENTIFIER")return this.parseIdentifierOrFunction();if(t==="STRING"){let e=this.current.value;return this.advance(),T(e)}if(t==="NUMBER"){let e=Number(this.current.value);return this.advance(),T(e)}if(t==="LEFT_PAREN"){let e=this.parseFunctionParams();return this.parseArrowFunction(e)}throw Error(E(this.current,"Unexpected token"))}parseAccessChain(t){let e=this.current.type;if(e==="IDENTIFIER"){let n=this.current.value;return this.advance(),b(n,t)}if(e==="LEFT_BRACKET")return this.parseBracketAccess(t);if(e==="LEFT_BRACE")return this.parseObjectOperation(t);throw Error(E(this.current,"Expected property name after dot"))}parseBracketAccess(t){if(this.advance(),this.current.type==="RIGHT_BRACKET")return this.advance(),At(t);if(this.current.type==="STRING"){let a=this.current.value;return this.advance(),this.expect("RIGHT_BRACKET"),b(a,t)}let s=this.current.type==="NUMBER",r=this.current.type==="OPERATOR"&&this.current.value==="-",o=this.current.type==="COLON";if(s||r||o)return this.parseNumericIndexOrSlice(t);throw Error(E(this.current,"Unexpected token in bracket access"))}parseNumericIndexOrSlice(t){if(this.current.type==="COLON")return this.parseSliceFromColon(void 0,t);let n=this.parseNumber();if(this.advance(),this.current.type==="COLON")return this.parseSliceFromColon(n,t);return this.expect("RIGHT_BRACKET"),dt(n,t)}parseSliceFromColon(t,e){this.advance();let n=this.current.type==="NUMBER",s=this.current.type==="OPERATOR"&&this.current.value==="-",r=n||s,o=r?this.parseNumber():void 0;if(r)this.advance();return this.expect("RIGHT_BRACKET"),ft(t,o,e)}parseArrayAccess(){return this.parseBracketAccess()}parseObjectOperation(t){if(this.advance(),this.current.type!=="IDENTIFIER")throw Error(E(this.current,"Expected operation name after {"));let n=this.current.value;if(!gt(n)){let s=et.join(", ");throw Error(E(this.current,`Invalid object operation "${n}". Valid operations: ${s}`))}return this.advance(),this.expect("RIGHT_BRACE"),mt(n,t)}parseIdentifierOrFunction(){let t=this.current.value;if(this.advance(),this.current.type==="ARROW")return this.parseArrowFunction([t]);let n=P(t);if(n)return n;return b(t)}parseArrowFunction(t){this.expect("ARROW");let e=this.parseFunctionBody();return yt(t,e)}parseFunctionBody(){if(this.current.type==="LEFT_BRACE"){this.advance();let e=this.parseBinaryExpression();return this.expect("RIGHT_BRACE"),e}return this.parseBinaryExpression()}parseBinaryExpression(){let t=this.parseFunctionTerm();while(this.current.type==="OPERATOR"){let e=this.current.value;this.advance();let n=this.parseFunctionTerm();t=tt(`__operator_${e}__`,[n],t)}return t}parseFunctionTerm(){let t=this.current.type;if(t==="IDENTIFIER")return this.parseIdentifierChain();if(t==="NUMBER"){let e=Number(this.current.value);return this.advance(),T(e)}if(t==="STRING"){let e=this.current.value;return this.advance(),T(e)}if(t==="LEFT_PAREN"){this.advance();let e=this.parseBinaryExpression();return this.expect("RIGHT_PAREN"),e}throw Error(E(this.current,"Unexpected token in function body"))}parseIdentifierChain(){let t=this.current.value;this.advance();let e=P(t);if(e)return e;let n=b(t),s=()=>this.current.type==="DOT",r=()=>this.current.type==="IDENTIFIER",o=()=>this.current.type==="LEFT_PAREN";while(s()||o()){if(o()){let a=n,u=a.property,h=a.object;n=this.parseMethodCall(h?h:I(),u);continue}if(this.advance(),!r())break;let i=this.current.value;this.advance(),n=b(i,n)}return n}parseMethodCall(t,e){this.expect("LEFT_PAREN");let n=this.parseMethodArguments();return this.expect("RIGHT_PAREN"),tt(e,n,t)}parseMethodArguments(){let t=[];while(this.current.type!=="RIGHT_PAREN"&&this.current.type!=="EOF"){let e=this.parseMethodArgument();if(t.push(e),this.current.type==="COMMA")this.advance()}return t}parseMethodArgument(){let t=this.current.type;if(t==="LEFT_PAREN"){let e=this.parseFunctionParams();return this.parseArrowFunction(e)}if(t==="IDENTIFIER"){let e=this.current.value;if(this.advance(),this.current.type==="ARROW")return this.parseArrowFunction([e]);return b(e)}if(t==="NUMBER"){let e=Number(this.current.value);return this.advance(),T(e)}if(t==="STRING"){let e=this.current.value;return this.advance(),T(e)}return this.parseExpression()}parseFunctionParams(){this.expect("LEFT_PAREN");let t=[];while(this.current.type!=="RIGHT_PAREN"&&this.current.type!=="EOF"){if(this.current.type==="IDENTIFIER")t.push(this.current.value),this.advance();if(this.current.type==="COMMA")this.advance()}return this.expect("RIGHT_PAREN"),t}parsePostfix(t){let e=t;while(!0){let n=this.current.type;if(n==="DOT"){e=this.parsePostfixDot(e);continue}if(n==="LEFT_BRACKET"){e=this.parseBracketAccess(e);continue}if(n==="LEFT_PAREN"){if(e.type==="PropertyAccess"&&!e.object){let o=e.property;e=this.parseMethodCall(I(),o);continue}}break}return e}parsePostfixDot(t){this.advance();let e=this.current.type;if(e==="IDENTIFIER"){let n=this.current.value;if(this.advance(),this.current.type==="LEFT_PAREN")return this.parseMethodCall(t,n);return b(n,t)}if(e==="LEFT_BRACKET")return this.parseBracketAccess(t);if(e==="LEFT_BRACE")return this.parseObjectOperation(t);throw Error(E(this.current,"Expected property name after dot"))}parseNumber(){let t=this.current.value==="-";if(t)this.advance();if(this.current.type!=="NUMBER")throw Error(E(this.current,"Expected number after minus sign"));let n=Number(this.current.value);return t?-n:n}advance(){if(this.position++,this.position<this.tokens.length)this.current=this.tokens[this.position]}expect(t){if(this.current.type!==t)throw Error(E(this.current,`Expected ${t} but got ${this.current.type}`));this.advance()}}var Tt={"+":(t,e)=>t+e,"-":(t,e)=>t-e,"*":(t,e)=>t*e,"/":(t,e)=>t/e,"%":(t,e)=>t%e,">":(t,e)=>t>e,"<":(t,e)=>t<e,">=":(t,e)=>t>=e,"<=":(t,e)=>t<=e,"==":(t,e)=>t==e,"===":(t,e)=>t===e,"!=":(t,e)=>t!=e,"!==":(t,e)=>t!==e,"&&":(t,e)=>t&&e,"||":(t,e)=>t||e};function nt(t){return t.startsWith("__operator_")&&t.endsWith("__")}function rt(t){return t.slice(11,-2)}function st(t,e,n){let s=Tt[e];if(!s)throw Error(`Unknown operator: ${e}`);return s(t,n)}function Nt(t,e){return Object.fromEntries(t.map((n,s)=>[n,e[s]]))}function j(t){return Object.values(t)[0]}function it(t){return t!==null&&typeof t==="object"}function B(t,e){if(!it(t))return;return t[e]}function D(t,e){return t<0?e+t:t}function Et(t,e){if(!Array.isArray(t))return;let n=D(e,t.length);return t[n]}function xt(t,e,n){if(!Array.isArray(t))return;let s=t.length,r=e!==void 0?D(e,s):0,o=n!==void 0?D(n,s):s;return t.slice(r,o)}function vt(t,e){if(!it(t))return;switch(e){case"keys":return Object.keys(t);case"values":return Object.values(t);case"entries":return Object.entries(t);case"length":return Array.isArray(t)?t.length:Object.keys(t).length}}var Ot=(t,e)=>{if(t===null||t===void 0)return!1;return typeof t[e]==="function"},bt=(t)=>t instanceof Error?t.message:String(t);function ot(t,e,n){if(!Ot(t,e))throw Error(`Method ${e} does not exist on ${typeof t}`);try{return t[e].call(t,...n)}catch(r){let o=bt(r);throw Error(`Error executing method ${e}: ${o}`)}}class G{evaluate(t,e){switch(t.type){case"Root":return t.expression?this.evaluate(t.expression,e):e;case"PropertyAccess":return this.evaluatePropertyAccess(t,e);case"IndexAccess":return Et(t.object?this.evaluate(t.object,e):e,t.index);case"SliceAccess":return xt(t.object?this.evaluate(t.object,e):e,t.start,t.end);case"ArraySpread":return t.object?this.evaluate(t.object,e):e;case"MethodCall":return this.evaluateMethodCall(t,e);case"ObjectOperation":return vt(t.object?this.evaluate(t.object,e):e,t.operation);case"Literal":return t.value;case"ArrowFunction":return this.createFunction(t);default:throw Error(`Unknown AST node type: ${t.type}`)}}evaluatePropertyAccess(t,e){let n=t.object?this.evaluate(t.object,e):e;return B(n,t.property)}evaluateArg(t,e){return t.type==="ArrowFunction"?this.createFunction(t):this.evaluate(t,e)}evaluateMethodCall(t,e){let n=t.object?this.evaluate(t.object,e):e;if(nt(t.method)){let o=rt(t.method),i=this.evaluate(t.args[0],e);return st(n,o,i)}let r=t.args.map((o)=>this.evaluateArg(o,e));return ot(n,t.method,r)}createFunction(t){return(...e)=>{let n=Nt(t.params,e);return this.evaluateFunctionBody(t.body,n)}}evaluateFunctionBody(t,e){switch(t.type){case"PropertyAccess":return this.evaluatePropertyAccessInFunction(t,e);case"MethodCall":return this.evaluateMethodCallInFunction(t,e);case"Literal":return t.value;case"Root":return t.expression?this.evaluateFunctionBody(t.expression,e):e;default:return this.evaluate(t,j(e))}}evaluatePropertyAccessInFunction(t,e){if(t.object!==void 0){let o=this.evaluateFunctionBody(t.object,e);return B(o,t.property)}if(Object.prototype.hasOwnProperty.call(e,t.property))return e[t.property];let r=j(e);return B(r,t.property)}evaluateMethodCallInFunction(t,e){let n=t.object?this.evaluateFunctionBody(t.object,e):j(e);if(nt(t.method)){let o=rt(t.method),i=this.evaluateFunctionBody(t.args[0],e);return st(n,o,i)}let r=t.args.map((o)=>this.evaluateFunctionBody(o,e));return ot(n,t.method,r)}}var U=[{short:".mp",full:".map",description:"Transform each element",type:"array"},{short:".flt",full:".filter",description:"Filter elements",type:"array"},{short:".rd",full:".reduce",description:"Reduce to single value",type:"array"},{short:".fnd",full:".find",description:"Find first match",type:"array"},{short:".sm",full:".some",description:"Test if any match",type:"array"},{short:".evr",full:".every",description:"Test if all match",type:"array"},{short:".srt",full:".sort",description:"Sort elements",type:"array"},{short:".rvs",full:".reverse",description:"Reverse order",type:"array"},{short:".jn",full:".join",description:"Join to string",type:"array"},{short:".slc",full:".slice",description:"Extract portion",type:"array"},{short:".kys",full:".{keys}",description:"Get object keys",type:"object"},{short:".vls",full:".{values}",description:"Get object values",type:"object"},{short:".ents",full:".{entries}",description:"Get object entries",type:"object"},{short:".len",full:".{length}",description:"Get length/size",type:"object"},{short:".lc",full:".toLowerCase",description:"Convert to lowercase",type:"string"},{short:".uc",full:".toUpperCase",description:"Convert to uppercase",type:"string"},{short:".trm",full:".trim",description:"Remove whitespace",type:"string"},{short:".splt",full:".split",description:"Split string to array",type:"string"},{short:".incl",full:".includes",description:"Check if includes",type:"array"}];var W=(t,e)=>{let s=U.filter((r)=>r.type===t).map((r)=>` ${r.short.padEnd(6)} -> ${r.full.padEnd(14)} ${r.description}`);return`${e}:
|
|
3
|
+
${s.join(`
|
|
4
|
+
`)}`},Te=`Expression Shortcuts:
|
|
5
|
+
|
|
6
|
+
${W("array","Array Methods")}
|
|
7
|
+
|
|
8
|
+
${W("object","Object Methods")}
|
|
9
|
+
|
|
10
|
+
${W("string","String Methods")}
|
|
11
|
+
`;var ct=/[.*+?^${}()|[\]\\]/g,at=U;var St=/^-?\d+$/,wt=/^[+-]?\d+$/,Rt=/^-?\d+\.\d+$/,kt=/^[+-]?\d+\.\d+$/;var V={INTEGER:St,FLOAT:Rt},H={INTEGER:wt,FLOAT:kt};var It=["true","yes","on"],Ct=["false","no","off"],Ft=["null","~",""],Lt=(t)=>It.includes(t),_t=(t)=>Ct.includes(t),Pt=(t)=>Ft.includes(t),C=(t)=>{if(Lt(t))return!0;if(_t(t))return!1;return},F=(t)=>{if(Pt(t))return null;return},ut=(t)=>{if(t==="")return;let e=Number(t);return isNaN(e)?void 0:e};function Mt(t){if(t.startsWith("!!")){let e=t.indexOf(" ");if(e>0)return{tag:t.substring(2,e),content:t.substring(e+1)}}return{tag:null,content:t}}function k(t){let{tag:e,content:n}=Mt(t);if(e==="str")return n;let s=n.startsWith('"')&&n.endsWith('"'),r=n.startsWith("'")&&n.endsWith("'");if(s||r)return n.slice(1,-1);let i=C(n);if(i!==void 0)return i;let a=F(n);if(a!==void 0)return a;if(V.INTEGER.test(n))return parseInt(n,10);if(V.FLOAT.test(n))return parseFloat(n);if(n.startsWith("[")&&n.endsWith("]"))return n.slice(1,-1).split(",").map((c)=>k(c.trim()));if(n.startsWith("{")&&n.endsWith("}")){let c={};return n.slice(1,-1).split(",").forEach((J)=>{let[S,y]=J.split(":").map((p)=>p.trim());if(S&&y)c[S]=k(y)}),c}return n}function jt(t,e){return Array.from({length:e},(s,r)=>e-1-r).reduce((s,r)=>{if(s!==null)return s;let o=t[r],i=o.indexOf("#");if(i>=0){let f=o.substring(0,i);if((f.match(/["']/g)||[]).length%2===0)o=f}let u=o.trim();if(u&&!u.startsWith("-")&&u.includes(":")){let f=u.indexOf(":"),g=u.substring(0,f).trim(),c=u.substring(f+1).trim();if(!c||c==="|"||c===">"||c==="|+"||c===">-")return g}return null},null)}function $(t){let e=t.indexOf("#");if(e<0)return t;let n=t.substring(0,e);return(n.match(/["']/g)||[]).length%2===0?n:t}function Bt(t){let e=t.indexOf(":");if(e<=0)return!1;let n=t.substring(0,e);return!n.includes(" ")||n.startsWith('"')||n.startsWith("'")}function K(t){return t.length-t.trimStart().length}function Dt(t,e,n,s){let r=[],o=e;while(o<t.length){let a=t[o];if(!a.trim()){r.push(""),o++;continue}if(K(a)<=n)break;r.push(a.substring(n+2)),o++}while(r.length>0&&r[r.length-1]==="")r.pop();return{value:s==="|"?r.join(`
|
|
12
|
+
`):r.join(" ").replace(/\s+/g," ").trim(),endIdx:o-1}}function Q(t,e){if(typeof t==="string"&&t.startsWith("*")){let n=t.substring(1);return e[n]!==void 0?e[n]:t}if(Array.isArray(t))return t.map((n)=>Q(n,e));if(typeof t==="object"&&t!==null){let n={};for(let[s,r]of Object.entries(t))if(s==="<<"&&typeof r==="string"&&r.startsWith("*")){let o=r.substring(1),i=e[o];if(typeof i==="object"&&i!==null&&!Array.isArray(i))Object.assign(n,i)}else n[s]=Q(r,e);return n}return t}function Gt(t){let e=t.trim().split(`
|
|
13
|
+
`),n={},o=e.find((h)=>{let f=$(h).trim();return f&&f!=="---"&&f!=="..."})?.trim().startsWith("- ")?[]:{},i=[{container:o,indent:-1}];function a(){return i[i.length-1]}function u(h){while(i.length>1&&h(a()))i.pop()}for(let h=0;h<e.length;h++){let f=e[h],g=$(f),c=g.trim();if(!c||c==="---"||c==="...")continue;let d=K(g);if(c.startsWith("- ")||c==="-"){let y=c==="-"?"":c.substring(2).trim();u((A)=>A.indent>d||A.indent>=d&&!Array.isArray(A.container));let l,p=a();if(Array.isArray(p.container)&&(p.indent===d||p.indent===-1&&d===0)){if(l=p.container,p.indent===-1)p.indent=d}else{if(l=[],p.pendingKey)p.container[p.pendingKey]=l,p.pendingKey=void 0;else if(!Array.isArray(p.container)){let A=jt(e,h);if(A)p.container[A]=l}i.push({container:l,indent:d})}if(Bt(y)){let A=y.indexOf(":"),m=y.substring(0,A).trim(),N=y.substring(A+1).trim(),x=null;if(m.includes(" &")){let w=m.split(" &");m=w[0],x=w[1]}let v={[m]:N?k(N):null};if(l.push(v),x)n[x]=v;i.push({container:v,indent:d+2})}else if(y)l.push(k(y));else{let A={};l.push(A),i.push({container:A,indent:d+2})}continue}let S=c.indexOf(":");if(S>0){let y=c.substring(0,S).trim(),l=c.substring(S+1).trim(),p=null;if(l.startsWith("&")){let m=l.indexOf(" ");if(m>0)p=l.substring(1,m),l=l.substring(m+1);else p=l.substring(1),l=""}u((m)=>m.indent>d||m.indent===d&&Array.isArray(m.container));let L=a(),A=L.container;if(Array.isArray(A))continue;if(l==="|"||l===">"||l==="|+"||l===">-"||l==="|-"||l===">+"){let m=l.startsWith("|")?"|":">",{value:N,endIdx:x}=Dt(e,h+1,d,m);if(A[y]=N,p)n[p]=N;h=x}else if(l){let m=k(l);if(A[y]=m,p)n[p]=m}else{let m=h+1,N=m<e.length,x=N?$(e[m]):"",v=x.trim(),w=N?K(x):-1,lt=v.startsWith("- ")||v==="-",ht=N&&w>d&&v;if(lt&&w>d){if(L.pendingKey=y,p){let R={};n[p]=R}}else if(ht){let R={};if(A[y]=R,p)n[p]=R;i.push({container:R,indent:w})}else if(A[y]=null,p)n[p]=null}}}return Q(o,n)}function pt(t,e){let n=[],s="",r=!1,o=t.split("");return o.forEach((i,a)=>{let u=o[a+1];if(i==='"'){if(r&&u==='"'){s+='"',o.splice(a+1,1);return}r=!r;return}if(i===e&&!r){n.push(s),s="";return}s+=i}),n.push(s),n.map((i)=>i.trim())}function Wt(t){let e=t.trim();if(e.startsWith('"')&&e.endsWith('"'))return e.slice(1,-1).replace(/""/g,'"');let s=ut(e);if(s!==void 0)return s;let r=e.toLowerCase(),o=C(r);if(o!==void 0)return o;let i=F(r);if(i!==void 0)return i;return e}function Ut(t,e=","){let n=t.trim().split(`
|
|
14
|
+
`);if(n.length===0)return[];let s=pt(n[0],e);if(n.length===1)return[];return n.slice(1).reduce((r,o)=>{let i=pt(o,e);if(i.length===0)return r;let a=Object.fromEntries(s.map((u,h)=>[u,Wt(i[h]||"")]));return[...r,a]},[])}function Y(t){if(t.startsWith('"')&&t.endsWith('"'))return t.slice(1,-1).replace(/\\"/g,'"');if(t.startsWith("'")&&t.endsWith("'"))return t.slice(1,-1);if(t==="true")return!0;if(t==="false")return!1;if(H.INTEGER.test(t))return parseInt(t,10);if(H.FLOAT.test(t))return parseFloat(t);if(t.startsWith("[")&&t.endsWith("]"))return t.slice(1,-1).split(",").map((u)=>Y(u.trim()));if(t.startsWith("{")&&t.endsWith("}")){let a={};return t.slice(1,-1).split(",").forEach((h)=>{let[f,g]=h.split("=").map((c)=>c.trim());if(f&&g)a[f]=Y(g)}),a}return t}function Vt(t){let e=t.trim().split(`
|
|
15
|
+
`),n={},s=n,r=[];return e.forEach((o)=>{let i=o,a=i.indexOf("#");if(a>=0){let c=i.substring(0,a);if((c.match(/["']/g)||[]).length%2===0)i=c}let u=i.trim();if(!u)return;if(u.startsWith("[")&&u.endsWith("]")){let c=u.slice(1,-1).split(".");s=n,r=[],c.forEach((d)=>{if(!s[d])s[d]={};s=s[d],r.push(d)});return}let f=u.indexOf("=");if(f>0){let c=u.substring(0,f).trim(),d=u.substring(f+1).trim();s[c]=Y(d)}}),n}function Ht(t){return t.replace(ct,"\\$&")}var $t=at.map((t)=>({regex:new RegExp(`${Ht(t.short)}(?![a-zA-Z])`,"g"),replacement:t.full})).sort((t,e)=>e.replacement.length-t.replacement.length);function Kt(t){return $t.reduce((e,{regex:n,replacement:s})=>e.replace(n,s),t)}function De(t,e){let n=Kt(e),r=new _(n).tokenize(),i=new M(r).parse();return new G().evaluate(i,t)}export{Gt as parseYAML,Vt as parseTOML,Ut as parseCSV,Kt as expandShortcuts,De as evaluate,Ht as escapeRegExp,_ as Lexer,G as JsonNavigator,M as ExpressionParser,$t as EXPAND_PATTERNS};
|
package/dist/cli/constants.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { DataFormat } from "../utils/types";
|
|
2
|
+
import { CliOptions } from "../types";
|
|
2
3
|
export declare const VALID_OUTPUT_FORMATS: readonly ["json", "yaml", "csv", "table"];
|
|
3
4
|
export declare const VALID_INPUT_FORMATS: DataFormat[];
|
|
5
|
+
export declare const DEFAULT_OPTIONS: CliOptions;
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
import { CliOptions } from "../types";
|
|
3
|
+
export declare const getInteractive: () => Promise<typeof import("../interactive/app")>;
|
|
4
|
+
export declare function handleGrepOperation(options: CliOptions): Promise<void>;
|
|
5
|
+
export declare function loadData(options: CliOptions, args: string[]): Promise<unknown>;
|
|
6
|
+
export declare function processExpression(options: CliOptions, jsonData: unknown): Promise<void>;
|
|
2
7
|
export declare function main(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Bash completion for 1ls
|
|
3
|
+
|
|
4
|
+
_1ls_complete() {
|
|
5
|
+
local cur prev opts
|
|
6
|
+
COMPREPLY=()
|
|
7
|
+
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
8
|
+
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
9
|
+
|
|
10
|
+
# Main options
|
|
11
|
+
opts="--help --version --raw --pretty --compact --type --format --list --grep --find --recursive --ignore-case --line-numbers --ext --max-depth --shortcuts --shorten --expand readFile"
|
|
12
|
+
|
|
13
|
+
# Format options
|
|
14
|
+
format_opts="json yaml csv table"
|
|
15
|
+
|
|
16
|
+
# Common JSON path starters
|
|
17
|
+
json_paths=". .[] .{keys} .{values} .{entries}"
|
|
18
|
+
|
|
19
|
+
# Common shorthand methods
|
|
20
|
+
shortcuts=".mp .flt .rd .fnd .sm .evr .srt .rvs .jn .kys .vls .ents .lc .uc .trm"
|
|
21
|
+
|
|
22
|
+
case "${prev}" in
|
|
23
|
+
--format)
|
|
24
|
+
COMPREPLY=( $(compgen -W "${format_opts}" -- ${cur}) )
|
|
25
|
+
return 0
|
|
26
|
+
;;
|
|
27
|
+
--list|--find|readFile)
|
|
28
|
+
# File/directory completion
|
|
29
|
+
COMPREPLY=( $(compgen -f -- ${cur}) )
|
|
30
|
+
return 0
|
|
31
|
+
;;
|
|
32
|
+
--ext)
|
|
33
|
+
# Common extensions
|
|
34
|
+
COMPREPLY=( $(compgen -W "js ts tsx jsx json md txt yml yaml xml html css" -- ${cur}) )
|
|
35
|
+
return 0
|
|
36
|
+
;;
|
|
37
|
+
--shorten|--expand)
|
|
38
|
+
# JSON expressions
|
|
39
|
+
COMPREPLY=( $(compgen -W "${json_paths}" -- ${cur}) )
|
|
40
|
+
return 0
|
|
41
|
+
;;
|
|
42
|
+
*)
|
|
43
|
+
;;
|
|
44
|
+
esac
|
|
45
|
+
|
|
46
|
+
# If current word starts with -, show options
|
|
47
|
+
if [[ ${cur} == -* ]]; then
|
|
48
|
+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
|
49
|
+
return 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# If current word starts with ., suggest JSON paths and shortcuts
|
|
53
|
+
if [[ ${cur} == .* ]]; then
|
|
54
|
+
all_paths="${json_paths} ${shortcuts}"
|
|
55
|
+
COMPREPLY=( $(compgen -W "${all_paths}" -- ${cur}) )
|
|
56
|
+
return 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Default to options
|
|
60
|
+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
complete -F _1ls_complete 1ls
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#compdef 1ls
|
|
2
|
+
# Zsh completion for 1ls
|
|
3
|
+
|
|
4
|
+
_1ls() {
|
|
5
|
+
local -a opts format_opts shortcuts json_paths
|
|
6
|
+
|
|
7
|
+
# Main options
|
|
8
|
+
opts=(
|
|
9
|
+
'--help[Show help]'
|
|
10
|
+
'--version[Show version]'
|
|
11
|
+
'--raw[Raw output (no formatting)]'
|
|
12
|
+
'--pretty[Pretty print JSON]'
|
|
13
|
+
'--compact[Compact JSON]'
|
|
14
|
+
'--type[Show value type info]'
|
|
15
|
+
'--format[Output format]:format:(json yaml csv table)'
|
|
16
|
+
'--list[List files in directory]:directory:_files -/'
|
|
17
|
+
'--grep[Search for pattern]:pattern:'
|
|
18
|
+
'--find[Path to search in]:path:_files'
|
|
19
|
+
'--recursive[Recursive search]'
|
|
20
|
+
'--ignore-case[Case insensitive search]'
|
|
21
|
+
'--line-numbers[Show line numbers]'
|
|
22
|
+
'--ext[Filter by extensions]:extensions:'
|
|
23
|
+
'--max-depth[Maximum recursion depth]:depth:'
|
|
24
|
+
'--shortcuts[Show all available shortcuts]'
|
|
25
|
+
'--shorten[Convert expression to shorthand]:expression:'
|
|
26
|
+
'--expand[Convert shorthand to full form]:expression:'
|
|
27
|
+
'readFile[Read from file]:file:_files'
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Common shorthand methods
|
|
31
|
+
shortcuts=(
|
|
32
|
+
'.mp:map - Transform each element'
|
|
33
|
+
'.flt:filter - Filter elements'
|
|
34
|
+
'.rd:reduce - Reduce to single value'
|
|
35
|
+
'.fnd:find - Find first match'
|
|
36
|
+
'.sm:some - Test if any match'
|
|
37
|
+
'.evr:every - Test if all match'
|
|
38
|
+
'.srt:sort - Sort elements'
|
|
39
|
+
'.rvs:reverse - Reverse order'
|
|
40
|
+
'.jn:join - Join to string'
|
|
41
|
+
'.kys:keys - Get object keys'
|
|
42
|
+
'.vls:values - Get object values'
|
|
43
|
+
'.ents:entries - Get object entries'
|
|
44
|
+
'.lc:toLowerCase - Convert to lowercase'
|
|
45
|
+
'.uc:toUpperCase - Convert to uppercase'
|
|
46
|
+
'.trm:trim - Remove whitespace'
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# JSON path examples
|
|
50
|
+
json_paths=(
|
|
51
|
+
'.:Root object'
|
|
52
|
+
'.[]:All array elements'
|
|
53
|
+
'.{keys}:Object keys'
|
|
54
|
+
'.{values}:Object values'
|
|
55
|
+
'.{entries}:Object entries'
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Check context and provide appropriate completions
|
|
59
|
+
local curcontext="$curcontext" state line
|
|
60
|
+
typeset -A opt_args
|
|
61
|
+
|
|
62
|
+
_arguments -C \
|
|
63
|
+
"${opts[@]}" \
|
|
64
|
+
'*:: :->args'
|
|
65
|
+
|
|
66
|
+
case $state in
|
|
67
|
+
args)
|
|
68
|
+
# If typing starts with ., offer shortcuts and paths
|
|
69
|
+
if [[ $words[$CURRENT] == .* ]]; then
|
|
70
|
+
_describe -t shortcuts 'shortcuts' shortcuts
|
|
71
|
+
_describe -t paths 'json paths' json_paths
|
|
72
|
+
else
|
|
73
|
+
_arguments "${opts[@]}"
|
|
74
|
+
fi
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
_1ls "$@"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "Installing 1ls shell completions..."
|
|
4
|
+
|
|
5
|
+
# Detect shell
|
|
6
|
+
if [ -n "$BASH_VERSION" ]; then
|
|
7
|
+
SHELL_NAME="bash"
|
|
8
|
+
elif [ -n "$ZSH_VERSION" ]; then
|
|
9
|
+
SHELL_NAME="zsh"
|
|
10
|
+
else
|
|
11
|
+
echo "Unsupported shell. Only bash and zsh are supported."
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Get the directory of this script
|
|
16
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
17
|
+
|
|
18
|
+
if [ "$SHELL_NAME" = "bash" ]; then
|
|
19
|
+
# Bash installation
|
|
20
|
+
if [ -d "$HOME/.bash_completion.d" ]; then
|
|
21
|
+
cp "$SCRIPT_DIR/1ls.bash" "$HOME/.bash_completion.d/"
|
|
22
|
+
echo "Installed to ~/.bash_completion.d/"
|
|
23
|
+
echo "Add this to your ~/.bashrc if not already present:"
|
|
24
|
+
echo " source ~/.bash_completion.d/1ls.bash"
|
|
25
|
+
elif [ -f "$HOME/.bashrc" ]; then
|
|
26
|
+
echo "" >> "$HOME/.bashrc"
|
|
27
|
+
echo "# 1ls completions" >> "$HOME/.bashrc"
|
|
28
|
+
echo "source $SCRIPT_DIR/1ls.bash" >> "$HOME/.bashrc"
|
|
29
|
+
echo "Added to ~/.bashrc"
|
|
30
|
+
else
|
|
31
|
+
echo "Could not find suitable location for bash completions"
|
|
32
|
+
echo "Please manually source: $SCRIPT_DIR/1ls.bash"
|
|
33
|
+
fi
|
|
34
|
+
elif [ "$SHELL_NAME" = "zsh" ]; then
|
|
35
|
+
# Zsh installation
|
|
36
|
+
if [ -d "$HOME/.zsh/completions" ]; then
|
|
37
|
+
cp "$SCRIPT_DIR/1ls.zsh" "$HOME/.zsh/completions/_1ls"
|
|
38
|
+
echo "Installed to ~/.zsh/completions/"
|
|
39
|
+
elif [ -d "/usr/local/share/zsh/site-functions" ]; then
|
|
40
|
+
cp "$SCRIPT_DIR/1ls.zsh" "/usr/local/share/zsh/site-functions/_1ls"
|
|
41
|
+
echo "Installed to /usr/local/share/zsh/site-functions/"
|
|
42
|
+
else
|
|
43
|
+
mkdir -p "$HOME/.zsh/completions"
|
|
44
|
+
cp "$SCRIPT_DIR/1ls.zsh" "$HOME/.zsh/completions/_1ls"
|
|
45
|
+
echo "Installed to ~/.zsh/completions/"
|
|
46
|
+
echo "Add this to your ~/.zshrc if not already present:"
|
|
47
|
+
echo " fpath=(~/.zsh/completions \$fpath)"
|
|
48
|
+
echo " autoload -U compinit && compinit"
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo "Reload your shell or run 'source ~/.${SHELL_NAME}rc' to enable completions"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LiteralNode } from "../types";
|
|
2
|
-
|
|
2
|
+
import { BOOLEAN_LITERALS } from "./constants";
|
|
3
|
+
export declare const isBooleanLiteral: (value: string) => value is (typeof BOOLEAN_LITERALS)[number];
|
|
3
4
|
export declare const createLiteralNode: (value: string | number | boolean | null) => LiteralNode;
|
|
4
5
|
export declare const tryParseLiteralIdentifier: (identifier: string) => LiteralNode | undefined;
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
export declare const INTEGER: RegExp;
|
|
2
|
+
export declare const INTEGER_WITH_SIGN: RegExp;
|
|
3
|
+
export declare const FLOAT: RegExp;
|
|
4
|
+
export declare const FLOAT_WITH_SIGN: RegExp;
|
|
5
|
+
export declare const NUMBER: RegExp;
|
|
6
|
+
export declare const ATTRIBUTES: RegExp;
|
|
7
|
+
export declare const SELF_CLOSING: RegExp;
|
|
8
|
+
export declare const OPEN_TAG: RegExp;
|
|
9
|
+
export declare const NESTED_TAGS: RegExp;
|
|
10
|
+
export declare const COMPLETE_TAGS: RegExp;
|
|
11
|
+
export declare const XML_DECLARATION: RegExp;
|
|
12
|
+
export declare const TRAILING_COMMA: RegExp;
|
|
13
|
+
export declare const UNQUOTED_KEY: RegExp;
|
|
14
|
+
export declare const JSON5_FEATURES: RegExp;
|
|
15
|
+
export declare const SECTION_HEADER: RegExp;
|
|
16
|
+
export declare const TOML_SECTION: RegExp;
|
|
17
|
+
export declare const TOML_QUOTED_VALUES: RegExp;
|
|
18
|
+
export declare const TOML_SYNTAX: RegExp;
|
|
19
|
+
export declare const INI_SYNTAX: RegExp;
|
|
1
20
|
export declare const CSV: {
|
|
2
21
|
readonly NUMBER: RegExp;
|
|
3
22
|
};
|
package/dist/formats/ini.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
+
import { INIParseState } from "./types";
|
|
1
2
|
export declare function parseINIValue(value: string): unknown;
|
|
3
|
+
export declare function stripINIComments(line: string): string;
|
|
4
|
+
export declare function processINILine(state: INIParseState, line: string): INIParseState;
|
|
2
5
|
export declare function parseINI(input: string): Record<string, unknown>;
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
import { ParseState } from "./types";
|
|
2
|
+
export declare function isQuoteChar(char: string): boolean;
|
|
3
|
+
export declare function findCommentEnd(chars: string[], startIndex: number, endPattern: string): number;
|
|
4
|
+
export declare function findMultiLineCommentEnd(chars: string[], startIndex: number): number;
|
|
5
|
+
export declare function handleStringChar(state: ParseState, char: string, nextChar: string | undefined): ParseState;
|
|
6
|
+
export declare function handleNormalChar(state: ParseState, char: string, nextChar: string | undefined, chars: string[], index: number): ParseState;
|
|
1
7
|
export declare function stripJSComments(input: string): string;
|
|
2
8
|
export declare function parseJavaScript(input: string): unknown;
|
package/dist/formats/json5.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { ParseState } from "./types";
|
|
2
|
+
export declare function isQuoteChar(char: string): boolean;
|
|
3
|
+
export declare function findCommentEnd(chars: string[], startIndex: number, endPattern: string): number;
|
|
4
|
+
export declare function findMultiLineCommentEnd(chars: string[], startIndex: number): number;
|
|
5
|
+
export declare function handleStringChar(state: ParseState, char: string, nextChar: string | undefined): ParseState;
|
|
6
|
+
export declare function handleNormalChar(state: ParseState, char: string, nextChar: string | undefined, chars: string[], index: number): ParseState;
|
|
1
7
|
export declare function stripJSON5Comments(input: string): string;
|
|
2
8
|
export declare function normalizeJSON5(input: string): string;
|
|
3
9
|
export declare function parseJSON5(input: string): unknown;
|
package/dist/formats/utils.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare const TRUTHY_VALUES: readonly ["true", "yes", "on"];
|
|
2
2
|
export declare const FALSY_VALUES: readonly ["false", "no", "off"];
|
|
3
3
|
export declare const NULL_VALUES: readonly ["null", "~", ""];
|
|
4
|
-
export declare const isTruthyValue: (value: string) =>
|
|
5
|
-
export declare const isFalsyValue: (value: string) =>
|
|
6
|
-
export declare const isNullValue: (value: string) =>
|
|
4
|
+
export declare const isTruthyValue: (value: string) => value is (typeof TRUTHY_VALUES)[number];
|
|
5
|
+
export declare const isFalsyValue: (value: string) => value is (typeof FALSY_VALUES)[number];
|
|
6
|
+
export declare const isNullValue: (value: string) => value is (typeof NULL_VALUES)[number];
|
|
7
7
|
export declare const parseBooleanValue: (value: string) => boolean | undefined;
|
|
8
8
|
export declare const parseNullValue: (value: string) => null | undefined;
|
|
9
9
|
export declare const tryParseNumber: (value: string) => number | undefined;
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
export declare const COLORS: {
|
|
2
|
+
reset: string;
|
|
3
|
+
bright: string;
|
|
4
|
+
dim: string;
|
|
5
|
+
black: string;
|
|
6
|
+
red: string;
|
|
7
|
+
green: string;
|
|
8
|
+
yellow: string;
|
|
9
|
+
blue: string;
|
|
10
|
+
magenta: string;
|
|
11
|
+
cyan: string;
|
|
12
|
+
white: string;
|
|
13
|
+
gray: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const COLOR_PATTERNS: {
|
|
16
|
+
regex: RegExp;
|
|
17
|
+
replacement: string;
|
|
18
|
+
}[];
|
|
1
19
|
export declare function colorize(json: string): string;
|
|
2
20
|
export declare function error(message: string): string;
|
|
3
21
|
export declare function success(message: string): string;
|