kami-redis 2.0.2 → 2.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/dist/index.js CHANGED
@@ -1,242 +1,2 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/index.ts
4
- import meow from "meow";
5
- import pc2 from "picocolors";
6
- import { createClient } from "redis";
7
-
8
- // src/utils/clean-up.ts
9
- function cleanup() {
10
- return console.clear();
11
- }
12
-
13
- // src/utils/graceful-exit.ts
14
- async function gracefulExit(code = 0) {
15
- try {
16
- if (process.stdin.isTTY) {
17
- try {
18
- process.stdin.setRawMode(false);
19
- } catch {
20
- }
21
- }
22
- try {
23
- process.stdin.pause();
24
- } catch {
25
- await client.quit();
26
- }
27
- } catch {
28
- } finally {
29
- cleanup();
30
- process.exit(code);
31
- }
32
- }
33
-
34
- // src/utils/is-redis-url.ts
35
- function isRedisUrl(url2) {
36
- let parsed;
37
- try {
38
- parsed = new URL(url2);
39
- } catch {
40
- return false;
41
- }
42
- if (parsed.protocol !== "redis:" && parsed.protocol !== "rediss:") {
43
- return false;
44
- }
45
- if (!parsed.hostname) {
46
- return false;
47
- }
48
- if (parsed.port && Number.isNaN(Number(parsed.port))) {
49
- return false;
50
- }
51
- return true;
52
- }
53
-
54
- // src/utils/prompt-for-key.ts
55
- import inquirer from "inquirer";
56
- async function promptForKey() {
57
- const keys = await client.keys("*");
58
- if (keys.length === 0)
59
- return null;
60
- try {
61
- const { selectedKey } = await inquirer.prompt({
62
- type: "list",
63
- name: "selectedKey",
64
- message: "Select a key to view its value:",
65
- choices: keys,
66
- pageSize: 20,
67
- theme: {
68
- icon: {
69
- cursor: ">"
70
- },
71
- prefix: "0_0"
72
- }
73
- });
74
- return selectedKey;
75
- } catch {
76
- await gracefulExit(0);
77
- }
78
- }
79
-
80
- // src/utils/view-key.ts
81
- import boxen from "boxen";
82
- import highlight from "cli-highlight";
83
- import clipboardy from "clipboardy";
84
- import readline from "readline";
85
- import pc from "picocolors";
86
-
87
- // src/utils/format-value.ts
88
- function formatValue(value) {
89
- if (typeof value === "object" && value !== null) {
90
- return JSON.stringify(value, null, 2);
91
- }
92
- if (typeof value === "string") {
93
- try {
94
- return JSON.stringify(JSON.parse(value), null, 2);
95
- } catch {
96
- return value;
97
- }
98
- }
99
- return String(value);
100
- }
101
-
102
- // src/utils/get-value.ts
103
- async function getValue(selectedKey, type) {
104
- switch (type) {
105
- case "string":
106
- return client.get(selectedKey);
107
- case "hash":
108
- return client.hGetAll(selectedKey);
109
- case "list":
110
- return client.lRange(selectedKey, 0, -1);
111
- case "set":
112
- return client.sMembers(selectedKey);
113
- case "zset":
114
- return client.zRangeWithScores(selectedKey, 0, -1);
115
- default:
116
- return "(unsupported type)";
117
- }
118
- }
119
-
120
- // src/utils/view-key.ts
121
- async function viewKey(selectedKey) {
122
- const type = await client.type(selectedKey);
123
- const value = await getValue(selectedKey, type);
124
- cleanup();
125
- console.log(
126
- boxen(highlight(formatValue(value), { language: "json", ignoreIllegals: true }), {
127
- borderColor: "cyan",
128
- padding: 1,
129
- title: selectedKey,
130
- borderStyle: "round"
131
- })
132
- );
133
- console.log(pc.blue("Press 'd' to delete, 'c' to copy, \u2190 to go back, Ctrl+C to quit."));
134
- readline.emitKeypressEvents(process.stdin);
135
- try {
136
- process.stdin.resume();
137
- } catch {
138
- }
139
- if (process.stdin.isTTY) {
140
- process.stdin.setRawMode(true);
141
- }
142
- return await new Promise((resolve) => {
143
- const onKeypress = async (str, key) => {
144
- if (!key) {
145
- return;
146
- }
147
- if (key.name === "d" && !key.ctrl && !key.meta) {
148
- try {
149
- await client.del(selectedKey);
150
- } catch {
151
- console.error(pc.red("Delete failed:"));
152
- }
153
- cleanup();
154
- resolve("deleted");
155
- return;
156
- }
157
- if (key.name === "c" && !key.ctrl && !key.meta) {
158
- try {
159
- clipboardy.writeSync(formatValue(value));
160
- cleanup();
161
- resolve("back");
162
- } catch (e) {
163
- console.error(pc.red("Copy failed:"), e);
164
- }
165
- return;
166
- }
167
- if (key.name === "left") {
168
- cleanup();
169
- resolve("back");
170
- return;
171
- }
172
- if (key.ctrl && key.name === "c" || key.sequence === "") {
173
- cleanup();
174
- resolve("quit");
175
- }
176
- };
177
- const onData = async (chunk) => {
178
- const s = chunk.toString();
179
- if (s.includes("")) {
180
- cleanup();
181
- resolve("quit");
182
- }
183
- };
184
- process.stdin.on("keypress", onKeypress);
185
- process.stdin.on("data", onData);
186
- });
187
- }
188
-
189
- // src/index.ts
190
- var cli = meow(
191
- `
192
- Usage
193
- kami-redis <url>
194
- `,
195
- {
196
- importMeta: import.meta
197
- }
198
- );
199
- var [url] = cli.input;
200
- if (!url) {
201
- console.log(cli.help);
202
- process.exit(1);
203
- }
204
- if (!isRedisUrl(url)) {
205
- console.log(cli.help);
206
- console.log(pc2.red("Provided URL is not a valid Redis URL"));
207
- process.exit(1);
208
- }
209
- var client = createClient({ url });
210
- async function main() {
211
- try {
212
- cleanup();
213
- await client.connect();
214
- while (true) {
215
- const selectedKey = await promptForKey();
216
- if (!selectedKey) {
217
- console.log("No keys in Redis!");
218
- await client.quit();
219
- process.exit(0);
220
- }
221
- const action = await viewKey(selectedKey);
222
- if (action === "quit") {
223
- await gracefulExit(0);
224
- } else if (action === "deleted") {
225
- continue;
226
- } else if (action === "back") {
227
- continue;
228
- }
229
- }
230
- } catch (err) {
231
- console.error(pc2.red("Unexpected error:"), err);
232
- try {
233
- await client.quit();
234
- } catch {
235
- process.exit(1);
236
- }
237
- }
238
- }
239
- main();
240
- export {
241
- client
242
- };
2
+ import K from"meow";import h from"picocolors";import{createClient as E}from"redis";function p(e){try{let r=new URL(e);return(r.protocol==="redis:"||r.protocol==="rediss:")&&!!r.hostname&&(!r.port||!Number.isNaN(Number(r.port)))}catch{return!1}}import b from"inquirer";async function m(e=0){try{if(process.stdin.isTTY)try{process.stdin.setRawMode(!1)}catch{}try{process.stdin.pause()}catch{await t.quit()}}catch{}finally{console.clear(),process.exit(e)}}async function u(){let e=await t.keys("*");if(e.length===0)return null;try{let{selectedKey:r}=await b.prompt({type:"list",name:"selectedKey",message:"Select a key to view its value:",choices:e,pageSize:20,theme:{icon:{cursor:">"},prefix:"0_0"}});return r}catch{await m(0)}}import R from"boxen";import{highlight as q}from"cli-highlight";import N from"readline";import S from"picocolors";function f(e){if(typeof e=="object"&&e!==null)return JSON.stringify(e,null,2);if(typeof e=="string")try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}return String(e)}async function d(e,r){switch(r){case"string":return t.get(e);case"hash":return t.hGetAll(e);case"list":return t.lRange(e,0,-1);case"set":return t.sMembers(e);case"zset":return t.zRangeWithScores(e,0,-1);default:return"(unsupported type)"}}var y=!1;function T(){!y&&process.stdin.isTTY&&(N.emitKeypressEvents(process.stdin),y=!0)}async function g(e){let r=await t.type(e),w=await d(e,r);return console.clear(),console.log(R(q(f(w),{language:"json",ignoreIllegals:!0}),{borderColor:"cyan",padding:1,title:e,borderStyle:"round"})),console.log(S.dim("d: delete | c: copy | \u2190: back | ctrl+c: quit")),T(),new Promise(s=>{let n=!1,i=()=>{if(!n){if(n=!0,process.stdin.removeListener("keypress",l),process.stdin.isTTY)try{process.stdin.setRawMode(!1)}catch{}process.stdin.pause()}},l=async(M,o)=>{if(!(!o||n)){if(o.ctrl&&o.name==="c"){i(),console.clear(),s("quit");return}if(o.name==="d"){i();try{await t.del(e)}catch{}console.clear(),s("deleted");return}if(o.name==="c"){try{console.log("Copied to clipboard!")}catch(x){console.log("Error copying:",x)}i(),console.clear(),s("back");return}o.name==="left"&&(i(),console.clear(),s("back"))}};process.stdin.isTTY&&process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("keypress",l)})}var c=K("Usage: kami-redis <url>",{importMeta:import.meta}),[a]=c.input;a||(console.log(c.help),process.exit(1));p(a)||(console.log(c.help),console.log(h.red("Invalid Redis URL")),process.exit(1));var t=E({url:a});async function I(){try{for(console.clear(),await t.connect();;){let e=await u();e||(console.log("No keys in Redis"),await t.quit(),process.exit(0)),await g(e)==="quit"&&(await t.quit(),process.exit(0))}}catch(e){console.error(h.red("Error:"),e);try{await t.quit()}catch{}process.exit(1)}}process.on("SIGINT",async()=>{try{await t.quit()}catch{}process.exit(0)});I();export{t as client};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kami-redis",
3
3
  "type": "module",
4
- "version": "2.0.2",
4
+ "version": "2.1.0",
5
5
  "description": "Browse, inspect, copy, and delete Redis keys from your CLI",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
@@ -10,9 +10,14 @@
10
10
  "bin": {
11
11
  "kami-redis": "dist/index.js"
12
12
  },
13
+ "files": [
14
+ "/dist",
15
+ "README.md",
16
+ "package.json"
17
+ ],
13
18
  "scripts": {
14
19
  "dev": "bun run --watch src/index.ts",
15
- "build": "tsup src/index.ts",
20
+ "build": "tsup",
16
21
  "lint": "eslint",
17
22
  "lint:fix": "eslint --fix",
18
23
  "release": "bun run build && changeset publish",
@@ -1,8 +0,0 @@
1
- # Changesets
2
-
3
- Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
- with multi-package repos, or single-package repos to help you version and publish your code. You can
5
- find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
-
7
- We have a quick list of common questions to get you started engaging with this project in
8
- [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
3
- "changelog": "@changesets/cli/changelog",
4
- "commit": false,
5
- "fixed": [],
6
- "linked": [],
7
- "access": "public",
8
- "baseBranch": "main",
9
- "updateInternalDependencies": "patch",
10
- "ignore": []
11
- }
@@ -1,17 +0,0 @@
1
- name: CI
2
- on:
3
- push:
4
- branches:
5
- - "**"
6
-
7
- jobs:
8
- build:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - uses: actions/checkout@v3
12
- - uses: oven-sh/setup-bun@v2
13
- with:
14
- bun-version: latest
15
-
16
- - run: bun install
17
- - run: bun run lint && bun run build
@@ -1,32 +0,0 @@
1
- name: Publish
2
- on:
3
- workflow_run:
4
- workflows: [CI]
5
- branches: [main]
6
- types: [completed]
7
-
8
- concurrency: ${{ github.workflow }}-${{ github.ref }}
9
-
10
- permissions:
11
- contents: write
12
- pull-requests: write
13
-
14
- jobs:
15
- publish:
16
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
17
- runs-on: ubuntu-latest
18
- steps:
19
- - uses: actions/checkout@v3
20
- - uses: oven-sh/setup-bun@v2
21
- with:
22
- bun-version: latest
23
-
24
- - run: bun install
25
- - name: Create Release Pull Request or Publish
26
- id: changesets
27
- uses: changesets/action@v1
28
- with:
29
- publish: bun run release
30
- env:
31
- GITHUB_TOKEN: ${{ secrets.GHUB_TOKEN }}
32
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,51 +0,0 @@
1
- {
2
- // Disable the default formatter, use eslint instead
3
- "prettier.enable": false,
4
- "editor.formatOnSave": false,
5
-
6
- // Auto fix
7
- "editor.codeActionsOnSave": {
8
- "source.fixAll.eslint": "explicit",
9
- "source.organizeImports": "never"
10
- },
11
-
12
- // Silent the stylistic rules in you IDE, but still auto fix them
13
- "eslint.rules.customizations": [
14
- { "rule": "style/*", "severity": "off", "fixable": true },
15
- { "rule": "format/*", "severity": "off", "fixable": true },
16
- { "rule": "*-indent", "severity": "off", "fixable": true },
17
- { "rule": "*-spacing", "severity": "off", "fixable": true },
18
- { "rule": "*-spaces", "severity": "off", "fixable": true },
19
- { "rule": "*-order", "severity": "off", "fixable": true },
20
- { "rule": "*-dangle", "severity": "off", "fixable": true },
21
- { "rule": "*-newline", "severity": "off", "fixable": true },
22
- { "rule": "*quotes", "severity": "off", "fixable": true },
23
- { "rule": "*semi", "severity": "off", "fixable": true }
24
- ],
25
-
26
- // Enable eslint for all supported languages
27
- "eslint.validate": [
28
- "javascript",
29
- "javascriptreact",
30
- "typescript",
31
- "typescriptreact",
32
- "vue",
33
- "html",
34
- "markdown",
35
- "json",
36
- "json5",
37
- "jsonc",
38
- "yaml",
39
- "toml",
40
- "xml",
41
- "gql",
42
- "graphql",
43
- "astro",
44
- "svelte",
45
- "css",
46
- "less",
47
- "scss",
48
- "pcss",
49
- "postcss"
50
- ]
51
- }
package/CHANGELOG.md DELETED
@@ -1,19 +0,0 @@
1
- # kami-redis
2
-
3
- ## 2.0.2
4
-
5
- ### Patch Changes
6
-
7
- - c9fe624: added shebang
8
-
9
- ## 2.0.1
10
-
11
- ### Patch Changes
12
-
13
- - b2e2ed5: added bin (forgot to add bin)
14
-
15
- ## 2.0.0
16
-
17
- ### Major Changes
18
-
19
- - e7c8743: initial update