@zjy4fun/json-open 0.1.1 → 0.1.9
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/.github/workflows/publish.yml +3 -2
- package/README.md +70 -60
- package/README.zh-CN.md +7 -0
- package/bin/json.js +194 -9
- package/package.json +6 -2
|
@@ -18,9 +18,8 @@ jobs:
|
|
|
18
18
|
|
|
19
19
|
- uses: actions/setup-node@v4
|
|
20
20
|
with:
|
|
21
|
-
node-version:
|
|
21
|
+
node-version: 22
|
|
22
22
|
registry-url: 'https://registry.npmjs.org'
|
|
23
|
-
cache: 'npm'
|
|
24
23
|
|
|
25
24
|
- run: npm ci
|
|
26
25
|
- run: npm test --if-present
|
|
@@ -33,3 +32,5 @@ jobs:
|
|
|
33
32
|
[ "$TAG_VERSION" = "$PKG_VERSION" ] || (echo "Tag $TAG_VERSION != package.json $PKG_VERSION" && exit 1)
|
|
34
33
|
|
|
35
34
|
- run: npm publish --access public --provenance
|
|
35
|
+
env:
|
|
36
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
|
@@ -1,56 +1,59 @@
|
|
|
1
1
|
# json-open
|
|
2
2
|
|
|
3
|
-
Open JSON in your browser
|
|
3
|
+
Open JSON in your browser as a collapsible tree view.
|
|
4
4
|
|
|
5
|
-
> A tiny CLI for
|
|
6
|
-
|
|
7
|
-
## Demo
|
|
5
|
+
> A tiny CLI for quickly inspecting JSON from APIs, logs, or inline text.
|
|
8
6
|
|
|
9
7
|

|
|
10
8
|
|
|
11
9
|
---
|
|
12
10
|
|
|
13
|
-
## Why
|
|
11
|
+
## Why json-open?
|
|
14
12
|
|
|
15
|
-
Reading JSON in
|
|
13
|
+
Reading JSON in terminal is often painful:
|
|
16
14
|
|
|
17
15
|
- Long output is hard to scan
|
|
18
16
|
- Deep nesting is hard to understand quickly
|
|
19
|
-
-
|
|
17
|
+
- Full-featured tools can feel heavy for quick checks
|
|
20
18
|
|
|
21
|
-
`json-open` keeps
|
|
19
|
+
`json-open` keeps it simple: **pipe JSON in, inspect it visually in seconds**.
|
|
22
20
|
|
|
23
21
|
---
|
|
24
22
|
|
|
25
23
|
## Features
|
|
26
24
|
|
|
27
|
-
- ✅
|
|
28
|
-
- ✅
|
|
29
|
-
- ✅
|
|
30
|
-
- ✅
|
|
31
|
-
- ✅
|
|
32
|
-
- ✅
|
|
25
|
+
- ✅ Read from stdin (pipe)
|
|
26
|
+
- ✅ Read inline JSON text
|
|
27
|
+
- ✅ Open browser automatically (macOS / Linux / Windows)
|
|
28
|
+
- ✅ Collapsible tree view
|
|
29
|
+
- ✅ Expand all / Collapse all
|
|
30
|
+
- ✅ Local temp file rendering (no remote upload)
|
|
31
|
+
- ✅ **Auto-parse serialized JSON strings** (escaped/double-encoded)
|
|
32
|
+
- ✅ **Deep nested JSON string expansion** (auto-unwrap JSON strings inside objects)
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
38
|
-
###
|
|
38
|
+
### npm (recommended)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm i -g @zjy4fun/json-open
|
|
42
|
+
```
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
After install, use the global command:
|
|
41
45
|
|
|
42
46
|
```bash
|
|
43
|
-
|
|
44
|
-
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> ~/.npmrc
|
|
47
|
+
json --version
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
### Run once with npx (no global install)
|
|
48
51
|
|
|
49
52
|
```bash
|
|
50
|
-
|
|
53
|
+
npx @zjy4fun/json-open '{"hello":"world"}'
|
|
51
54
|
```
|
|
52
55
|
|
|
53
|
-
###
|
|
56
|
+
### Local development
|
|
54
57
|
|
|
55
58
|
```bash
|
|
56
59
|
git clone https://github.com/zjy4fun/json-open.git
|
|
@@ -59,11 +62,9 @@ npm install
|
|
|
59
62
|
npm link
|
|
60
63
|
```
|
|
61
64
|
|
|
62
|
-
After that, the `json` command is available globally.
|
|
63
|
-
|
|
64
65
|
---
|
|
65
66
|
|
|
66
|
-
## Quick
|
|
67
|
+
## Quick Start
|
|
67
68
|
|
|
68
69
|
```bash
|
|
69
70
|
# 1) API response
|
|
@@ -76,56 +77,71 @@ json '{"hello":"world","list":[1,2,3]}'
|
|
|
76
77
|
cat response.json | json
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
The command opens your browser and shows a JSON tree
|
|
80
|
+
The command opens your default browser and shows a structured JSON tree.
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
83
|
-
##
|
|
84
|
+
## CLI Usage
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
```bash
|
|
87
|
+
json [inline-json]
|
|
88
|
+
```
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
Verify missing fields or type mismatches after API changes.
|
|
90
|
+
Input sources:
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
- `stdin` (pipe)
|
|
93
|
+
- Inline JSON argument
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
Share a clearer structure view when discussing payloads.
|
|
95
|
+
Options:
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
- `-h, --help` Show help
|
|
98
|
+
- `-v, --version` Show version
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
Examples:
|
|
100
101
|
|
|
101
102
|
```bash
|
|
102
|
-
json
|
|
103
|
+
json --help
|
|
104
|
+
json --version
|
|
105
|
+
json '{"ok":true}'
|
|
103
106
|
```
|
|
104
107
|
|
|
105
|
-
|
|
108
|
+
If no input is provided, usage help is printed.
|
|
109
|
+
|
|
110
|
+
---
|
|
106
111
|
|
|
107
|
-
|
|
108
|
-
- inline argument JSON string
|
|
112
|
+
## Serialized JSON String Support
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
`json-open` now automatically handles serialized/escaped JSON strings — a common pain point when working with logs, databases, and APIs.
|
|
111
115
|
|
|
112
116
|
```bash
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
# Double-encoded JSON string (e.g. from database or API response body)
|
|
118
|
+
json '"{\"name\":\"test\",\"age\":25}"'
|
|
119
|
+
# → auto-detects and parses as { "name": "test", "age": 25 }
|
|
115
120
|
|
|
116
|
-
|
|
121
|
+
# Nested JSON strings inside objects
|
|
122
|
+
json '{"status":"ok","data":"{\"users\":[{\"id\":1}]}"}'
|
|
123
|
+
# → auto-expands "data" field into a real JSON tree
|
|
117
124
|
|
|
118
|
-
|
|
125
|
+
# Multi-level serialization
|
|
126
|
+
json '"\"[1,2,3]\""'
|
|
127
|
+
# → recursively unwraps to [1, 2, 3]
|
|
128
|
+
```
|
|
119
129
|
|
|
120
|
-
|
|
130
|
+
This works for:
|
|
131
|
+
- Escaped JSON from `JSON.stringify()` output
|
|
132
|
+
- Log files with embedded JSON payloads
|
|
133
|
+
- API responses where a field contains a JSON string
|
|
134
|
+
- Database columns storing serialized JSON
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
---
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
- `Publish to GitHub Packages`: publish to GPR
|
|
126
|
-
- `Publish to npm (Trusted Publishing)`: reserved for npm OIDC flow
|
|
138
|
+
## Common Use Cases
|
|
127
139
|
|
|
128
|
-
|
|
140
|
+
- API debugging (inspect response shape quickly)
|
|
141
|
+
- Backend/frontend contract checks
|
|
142
|
+
- Ad-hoc JSON visualization from logs
|
|
143
|
+
- Payload discussion/demo with teammates
|
|
144
|
+
- **Inspecting serialized JSON from databases or message queues**
|
|
129
145
|
|
|
130
146
|
---
|
|
131
147
|
|
|
@@ -135,24 +151,18 @@ Issues and PRs are welcome.
|
|
|
135
151
|
|
|
136
152
|
### Good contribution ideas
|
|
137
153
|
|
|
138
|
-
- Better
|
|
154
|
+
- Better JSON parse error location hints
|
|
139
155
|
- Theme switch (light/dark)
|
|
140
156
|
- Direct file path support (e.g. `json ./data.json`)
|
|
141
|
-
-
|
|
157
|
+
- Search / highlight / copy JSON path
|
|
142
158
|
|
|
143
|
-
### Local
|
|
159
|
+
### Local dev
|
|
144
160
|
|
|
145
161
|
```bash
|
|
146
162
|
npm install
|
|
147
163
|
npm test
|
|
148
164
|
```
|
|
149
165
|
|
|
150
|
-
Before submitting:
|
|
151
|
-
|
|
152
|
-
- Ensure code runs correctly
|
|
153
|
-
- Ensure README examples still work
|
|
154
|
-
- Keep changes focused and clear
|
|
155
|
-
|
|
156
166
|
---
|
|
157
167
|
|
|
158
168
|
## License
|
package/README.zh-CN.md
CHANGED
package/bin/json.js
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from 'node:fs/promises'
|
|
3
|
+
import fsSync from 'node:fs'
|
|
3
4
|
import os from 'node:os'
|
|
4
5
|
import path from 'node:path'
|
|
5
6
|
import { spawn } from 'node:child_process'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
|
|
9
|
+
function getCliVersion() {
|
|
10
|
+
try {
|
|
11
|
+
const currentFile = fileURLToPath(import.meta.url)
|
|
12
|
+
const packageJsonPath = path.resolve(path.dirname(currentFile), '..', 'package.json')
|
|
13
|
+
const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf8'))
|
|
14
|
+
return packageJson.version
|
|
15
|
+
} catch {
|
|
16
|
+
return 'unknown'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function printHelp() {
|
|
21
|
+
console.log(`json-open
|
|
22
|
+
|
|
23
|
+
Usage:
|
|
24
|
+
json <json-string>
|
|
25
|
+
cat data.json | json
|
|
26
|
+
curl https://example.com/api | json
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
-h, --help Show help
|
|
30
|
+
-v, --version Show version`)
|
|
31
|
+
}
|
|
6
32
|
|
|
7
33
|
function readStdin() {
|
|
8
34
|
return new Promise((resolve, reject) => {
|
|
@@ -74,8 +100,11 @@ function valueToHtml(value, key = null) {
|
|
|
74
100
|
return `<div class=\"line\">${keyHtml}<span>${escapeHtml(String(value))}</span></div>`
|
|
75
101
|
}
|
|
76
102
|
|
|
77
|
-
function toHtml(jsonObj) {
|
|
78
|
-
const
|
|
103
|
+
function toHtml(jsonObj, deepParsedObj) {
|
|
104
|
+
const rawBody = valueToHtml(jsonObj)
|
|
105
|
+
const parsedBody = valueToHtml(deepParsedObj)
|
|
106
|
+
// 检测是否有差异(有嵌套 JSON 字符串可以展开)
|
|
107
|
+
const hasDiff = JSON.stringify(jsonObj) !== JSON.stringify(deepParsedObj)
|
|
79
108
|
return `<!doctype html>
|
|
80
109
|
<html lang=\"en\">
|
|
81
110
|
<head>
|
|
@@ -104,6 +133,8 @@ function toHtml(jsonObj) {
|
|
|
104
133
|
margin-bottom: 16px;
|
|
105
134
|
display: flex;
|
|
106
135
|
gap: 8px;
|
|
136
|
+
align-items: center;
|
|
137
|
+
flex-wrap: wrap;
|
|
107
138
|
}
|
|
108
139
|
button {
|
|
109
140
|
border: 1px solid #475569;
|
|
@@ -116,6 +147,51 @@ function toHtml(jsonObj) {
|
|
|
116
147
|
button:hover {
|
|
117
148
|
background: #334155;
|
|
118
149
|
}
|
|
150
|
+
/* 开关样式 */
|
|
151
|
+
.toggle-wrap {
|
|
152
|
+
display: flex;
|
|
153
|
+
align-items: center;
|
|
154
|
+
gap: 8px;
|
|
155
|
+
margin-left: auto;
|
|
156
|
+
font-size: 13px;
|
|
157
|
+
color: #94a3b8;
|
|
158
|
+
}
|
|
159
|
+
.toggle-wrap.hidden { display: none; }
|
|
160
|
+
.toggle {
|
|
161
|
+
position: relative;
|
|
162
|
+
width: 40px;
|
|
163
|
+
height: 22px;
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
}
|
|
166
|
+
.toggle input {
|
|
167
|
+
opacity: 0;
|
|
168
|
+
width: 0;
|
|
169
|
+
height: 0;
|
|
170
|
+
}
|
|
171
|
+
.toggle .slider {
|
|
172
|
+
position: absolute;
|
|
173
|
+
inset: 0;
|
|
174
|
+
background: #334155;
|
|
175
|
+
border-radius: 22px;
|
|
176
|
+
transition: background 0.2s;
|
|
177
|
+
}
|
|
178
|
+
.toggle .slider::before {
|
|
179
|
+
content: '';
|
|
180
|
+
position: absolute;
|
|
181
|
+
width: 16px;
|
|
182
|
+
height: 16px;
|
|
183
|
+
left: 3px;
|
|
184
|
+
bottom: 3px;
|
|
185
|
+
background: #e2e8f0;
|
|
186
|
+
border-radius: 50%;
|
|
187
|
+
transition: transform 0.2s;
|
|
188
|
+
}
|
|
189
|
+
.toggle input:checked + .slider {
|
|
190
|
+
background: #58a6ff;
|
|
191
|
+
}
|
|
192
|
+
.toggle input:checked + .slider::before {
|
|
193
|
+
transform: translateX(18px);
|
|
194
|
+
}
|
|
119
195
|
details {
|
|
120
196
|
margin-left: 16px;
|
|
121
197
|
}
|
|
@@ -154,17 +230,71 @@ function toHtml(jsonObj) {
|
|
|
154
230
|
<div class=\"toolbar\">
|
|
155
231
|
<button id=\"expand-all\">Expand all</button>
|
|
156
232
|
<button id=\"collapse-all\">Collapse all</button>
|
|
233
|
+
<div class=\"toggle-wrap${hasDiff ? '' : ' hidden'}\" title=\"Parse embedded JSON strings inside values\">
|
|
234
|
+
<span>Parse JSON strings</span>
|
|
235
|
+
<label class=\"toggle\">
|
|
236
|
+
<input type=\"checkbox\" id=\"deep-parse-toggle\" />
|
|
237
|
+
<span class=\"slider\"></span>
|
|
238
|
+
</label>
|
|
239
|
+
</div>
|
|
157
240
|
</div>
|
|
158
|
-
<main>${
|
|
241
|
+
<main id=\"raw-view\">${rawBody}</main>
|
|
242
|
+
<main id=\"parsed-view\" style=\"display:none\">${parsedBody}</main>
|
|
159
243
|
<script>
|
|
160
|
-
const details = () => Array.from(document.querySelectorAll('details'))
|
|
244
|
+
const details = () => Array.from(document.querySelectorAll('main:not([style*=\"display:none\"]) details'))
|
|
161
245
|
document.getElementById('expand-all').addEventListener('click', () => details().forEach((d) => d.open = true))
|
|
162
246
|
document.getElementById('collapse-all').addEventListener('click', () => details().forEach((d) => d.open = false))
|
|
247
|
+
|
|
248
|
+
const toggle = document.getElementById('deep-parse-toggle')
|
|
249
|
+
const rawView = document.getElementById('raw-view')
|
|
250
|
+
const parsedView = document.getElementById('parsed-view')
|
|
251
|
+
if (toggle) {
|
|
252
|
+
toggle.addEventListener('change', () => {
|
|
253
|
+
if (toggle.checked) {
|
|
254
|
+
rawView.style.display = 'none'
|
|
255
|
+
parsedView.style.display = ''
|
|
256
|
+
} else {
|
|
257
|
+
rawView.style.display = ''
|
|
258
|
+
parsedView.style.display = 'none'
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
}
|
|
163
262
|
</script>
|
|
164
263
|
</body>
|
|
165
264
|
</html>`
|
|
166
265
|
}
|
|
167
266
|
|
|
267
|
+
/**
|
|
268
|
+
* 递归遍历 JSON 对象,尝试将值为 JSON 字符串的字段自动解析为对象
|
|
269
|
+
* 比如 { "data": "{\"name\":\"test\"}" } → { "data": { "name": "test" } }
|
|
270
|
+
* 这在 API 响应和日志中非常常见
|
|
271
|
+
*/
|
|
272
|
+
function deepParseJsonStrings(obj) {
|
|
273
|
+
if (obj === null || obj === undefined) return obj
|
|
274
|
+
if (Array.isArray(obj)) return obj.map(deepParseJsonStrings)
|
|
275
|
+
if (typeof obj === 'object') {
|
|
276
|
+
const result = {}
|
|
277
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
278
|
+
result[key] = deepParseJsonStrings(value)
|
|
279
|
+
}
|
|
280
|
+
return result
|
|
281
|
+
}
|
|
282
|
+
if (typeof obj === 'string') {
|
|
283
|
+
const trimmed = obj.trim()
|
|
284
|
+
// 只尝试解析看起来像 JSON 对象或数组的字符串
|
|
285
|
+
if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
|
286
|
+
(trimmed.startsWith('[') && trimmed.endsWith(']'))) {
|
|
287
|
+
try {
|
|
288
|
+
const parsed = JSON.parse(trimmed)
|
|
289
|
+
return deepParseJsonStrings(parsed)
|
|
290
|
+
} catch {
|
|
291
|
+
return obj
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return obj
|
|
296
|
+
}
|
|
297
|
+
|
|
168
298
|
function openInBrowser(filePath) {
|
|
169
299
|
const platform = process.platform
|
|
170
300
|
const command = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open'
|
|
@@ -178,10 +308,22 @@ function openInBrowser(filePath) {
|
|
|
178
308
|
}
|
|
179
309
|
|
|
180
310
|
async function main() {
|
|
181
|
-
const
|
|
311
|
+
const args = process.argv.slice(2)
|
|
312
|
+
|
|
313
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
314
|
+
printHelp()
|
|
315
|
+
process.exit(0)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (args.includes('-v') || args.includes('--version')) {
|
|
319
|
+
console.log(getCliVersion())
|
|
320
|
+
process.exit(0)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const inlineInput = args.join(' ').trim()
|
|
182
324
|
|
|
183
325
|
if (!inlineInput && process.stdin.isTTY) {
|
|
184
|
-
|
|
326
|
+
printHelp()
|
|
185
327
|
process.exit(1)
|
|
186
328
|
}
|
|
187
329
|
|
|
@@ -196,11 +338,54 @@ async function main() {
|
|
|
196
338
|
try {
|
|
197
339
|
parsed = JSON.parse(input)
|
|
198
340
|
} catch {
|
|
199
|
-
|
|
200
|
-
|
|
341
|
+
// 尝试处理 JSON 序列化后的字符串(双重转义)
|
|
342
|
+
// 比如:"{\"name\":\"test\"}" 或 '"{\\\"name\\\":\\\"test\\\"}"'
|
|
343
|
+
// 这种情况常见于:日志输出、API 响应中嵌套的 JSON 字符串、数据库存储的 JSON
|
|
344
|
+
try {
|
|
345
|
+
// 第一步:去掉首尾引号(如果有的话)
|
|
346
|
+
let cleaned = input.trim()
|
|
347
|
+
if ((cleaned.startsWith('"') && cleaned.endsWith('"')) ||
|
|
348
|
+
(cleaned.startsWith("'") && cleaned.endsWith("'"))) {
|
|
349
|
+
cleaned = cleaned.slice(1, -1)
|
|
350
|
+
}
|
|
351
|
+
// 第二步:处理转义字符
|
|
352
|
+
// 替换 \" → ",\\ → \,\n → 换行,\t → tab
|
|
353
|
+
cleaned = cleaned
|
|
354
|
+
.replace(/\\"/g, '"')
|
|
355
|
+
.replace(/\\\\/g, '\\')
|
|
356
|
+
.replace(/\\n/g, '\n')
|
|
357
|
+
.replace(/\\t/g, '\t')
|
|
358
|
+
.replace(/\\r/g, '\r')
|
|
359
|
+
parsed = JSON.parse(cleaned)
|
|
360
|
+
console.log('ℹ️ Detected serialized JSON string, auto-unescaped.')
|
|
361
|
+
} catch {
|
|
362
|
+
// 第三步:尝试递归解析(多层序列化的情况)
|
|
363
|
+
try {
|
|
364
|
+
let result = input.trim()
|
|
365
|
+
let depth = 0
|
|
366
|
+
const maxDepth = 5
|
|
367
|
+
while (typeof result === 'string' && depth < maxDepth) {
|
|
368
|
+
result = JSON.parse(result)
|
|
369
|
+
depth++
|
|
370
|
+
}
|
|
371
|
+
if (typeof result === 'object' && result !== null) {
|
|
372
|
+
parsed = result
|
|
373
|
+
console.log(`ℹ️ Detected ${depth}-level serialized JSON string, auto-parsed.`)
|
|
374
|
+
} else {
|
|
375
|
+
console.error('Input is not valid JSON.')
|
|
376
|
+
process.exit(1)
|
|
377
|
+
}
|
|
378
|
+
} catch {
|
|
379
|
+
console.error('Input is not valid JSON.')
|
|
380
|
+
process.exit(1)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
201
383
|
}
|
|
202
384
|
|
|
203
|
-
|
|
385
|
+
// 生成深度解析版本(展开嵌套 JSON 字符串),但默认不启用
|
|
386
|
+
const deepParsed = deepParseJsonStrings(parsed)
|
|
387
|
+
|
|
388
|
+
const html = toHtml(parsed, deepParsed)
|
|
204
389
|
const filePath = path.join(os.tmpdir(), `json-viewer-${Date.now()}.html`)
|
|
205
390
|
await fs.writeFile(filePath, html, 'utf8')
|
|
206
391
|
openInBrowser(filePath)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zjy4fun/json-open",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Open JSON (stdin or inline text) in a browser with collapsible tree view",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,8 +17,12 @@
|
|
|
17
17
|
"browser",
|
|
18
18
|
"formatter"
|
|
19
19
|
],
|
|
20
|
-
"author": "",
|
|
20
|
+
"author": "zjy4fun",
|
|
21
21
|
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/zjy4fun/json-open"
|
|
25
|
+
},
|
|
22
26
|
"publishConfig": {
|
|
23
27
|
"access": "public",
|
|
24
28
|
"registry": "https://registry.npmjs.org"
|