Skip to content

Commit 38c4466

Browse files
committed
some updates to scripts/repl.sh
1 parent d6e1668 commit 38c4466

File tree

2 files changed

+182
-81
lines changed

2 files changed

+182
-81
lines changed

scripts/docs/repl.sh.md

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,20 @@ This script will start a REPL for the project, with:
2020
1. [Imports & variables](#imports--variables)
2121
1. [`$`](#)
2222
2. [`bn` & `JBI`](#bn--jbi)
23-
3. [`client`, `db`, `coll`, `table`](#client-db-coll-table)
23+
3. [`client`, `db`](#client-db)
24+
4. [`coll`, `table`, `coll_`, `table_` 🚨](#coll-table-coll_-table_-)
2425
4. [`dbAdmin`, `admin`, `isAstra`](#dbadmin-admin-isastra)
2526
2. ["Macros"](#macros)
2627
1. [`cl`](#cl)
27-
2. [`cda`/`tda`](#cdatda)
28-
3. [`cfa`/`tfa`](#cfatfa)
28+
2. [`cda`/`tda`/`cda_`/`tda_`](#cdatdacda_tda_)
29+
3. [`cfa`/`tfa`/`cfa_`/`tfa_`](#cfatfacfa_tfa_)
2930
4. [`cif(doc)`/`tif(row)`](#cifdoctifrow)
3031
5. [`+<Promise>`](#promise)
32+
3. [Configuration (`cfg`)](#configuration-cfg)
33+
1. [`cfg.plusOutput`](#cfgplusoutput)
34+
2. [`cfg.logging`](#cfglogging)
35+
3. [`cfg.fa`](#cfgfa)
36+
3137
4. [See also](#see-also)
3238

3339
## Prerequisites
@@ -110,17 +116,33 @@ These will be set to the imports of `bignumber.js` and `json-bigint`, respective
110116
'{"num":36.03}'
111117
```
112118

113-
#### `client`, `db`, `coll`, `table`
119+
#### `client`, `db`
120+
121+
Yeah, these are exactly what you think they are. Just remember that it is entirely on you to ensure that the database actually exists.
122+
123+
```ts
124+
> await db.info()
125+
{ ... }
126+
```
127+
128+
#### `coll`, `table`, `coll_`, `table_` 🚨
114129

115-
Yeah, these are exactly what you think they are. Just remember that it is entirely on you to ensure that the db/keyspace/collection/table actually exist.
130+
Yeah, these are exactly what you think they are. Just remember that it is entirely on you to ensure that the database actually exists.
116131

117132
Running the test script beforehand will set these up for you automatically (assuming the coll/table/ks names are left as default).
118133

119134
```ts
120-
> await coll.options()
135+
> await table.definition()
121136
{ ... }
122137
```
123138

139+
> [!IMPORTANT]
140+
> These variables are **special**; they are wrapped in a custom `Proxy` which allows property access to be _case-insensitive_ and _partially-complete_.
141+
142+
This means that you can access properties like `table.findOne({})` or `table.findOn({})` or `table.findo({})` and they will all work the same.
143+
144+
The shortest matching property will be used, so `insert` will match `insertOne` instead of `insertMany`.
145+
124146
#### `dbAdmin`, `admin`, `isAstra`
125147

126148
- `isAstra` will be set to `true` if the `CLIENT_DB_ENVIRONMENT` is `'astra' | undefined` and `-local` is not set
@@ -151,9 +173,9 @@ Just typing `cl` into the REPL will clear the console. It's like magic.
151173
>
152174
```
153175

154-
#### `cda`/`tda`
176+
#### `cda`/`tda`/`cda_`/`tda_`
155177

156-
Just typing in `cda` or `tda` into the REPL will run `await coll/table.deleteMany({})` for you.
178+
Just typing in `cda` or `tda` into the REPL will run `await coll/table.deleteMany({})` for you. Ditto for their `_` counterparts.
157179

158180
No explicit `await` required! Just type it in and watch the magic (synchronously) happen.
159181

@@ -162,9 +184,9 @@ No explicit `await` required! Just type it in and watch the magic (synchronously
162184
{ deletedCount: -1 }
163185
```
164186

165-
#### `cfa`/`tfa`
187+
#### `cfa`/`tfa`/`cfa_`/`tfa_`
166188

167-
Just typing in `cfa` or `tfa` into the REPL will run `await coll/table.find({}).toArray()` for you.
189+
Just typing in `cfa` or `tfa` into the REPL will run `await coll/table.find({}).toArray()` for you. Ditto for their `_` counterparts.
168190

169191
No explicit `await` required! Just type it in and watch the magic (synchronously) happen.
170192

@@ -215,6 +237,43 @@ It'll also return `1` if the promise resolves successfully, and `0` if it reject
215237
1
216238
```
217239

240+
### Configuration (`cfg`)
241+
242+
The `cfg` variable is a utility object that allows you to configure certain aspects the REPL environment.
243+
244+
```ts
245+
> cfg.plusOutput.minimal
246+
"Set plus output to 'minimal'"
247+
> cfg.fa.project({})
248+
'Set *fa projection to {}'
249+
```
250+
251+
#### `cfg.plusOutput`
252+
253+
This configuration object allows you to set the output level of the `+<Promise>` macro.
254+
255+
The available options are:
256+
- `cfg.plusOutput.default`: Prints the default output level
257+
- `cfg.plusOutput.verbose`: Prints the same as the default, but prints the whole error object if the promise rejects
258+
- `cfg.plusOutput.minimal`: Prints only the response or error message, and nothing else
259+
260+
#### `cfg.logging`
261+
262+
This configuration object allows you to manage the logging of events emitted by the various client objects.
263+
264+
The available options are:
265+
- `cfg.logging.on`: Enables logging
266+
- `cfg.logging.off`: Disables logging
267+
268+
The default value is set by the [`-l` flag](#enabling-verbose-logging--l---logging) if it is set, otherwise it will be `false`.
269+
270+
#### `cfg.fa`
271+
272+
This configuration object allows you to set options regarding the [`*fa` utility macros](#cfatfacfa_tfa_) (such as `cfa` or `tfa_`).
273+
274+
The available options are:
275+
- `cfg.fa.project(projection)`: Sets the projection to be used in the `find` query. The default is `{ '*': 1 }`, which means all fields will be returned.
276+
218277
## See also
219278

220279
- [The custom checker script](./check.sh.md)

scripts/repl.sh

Lines changed: 113 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,54 @@ node -i -e "
5959
const bn = require('bignumber.js');
6060
const JBI = require('json-bigint');
6161
62-
let fetchNative = new $.FetchNative()
62+
const fetchNative = new $.FetchNative()
6363
let fetchInfo;
6464
65-
let fetcher = {
65+
const fetcher = {
6666
fetch(info) {
6767
fetchInfo = info;
6868
return fetchNative.fetch(info);
6969
}
7070
}
7171
72+
const cfg = {
73+
plusOutput: {
74+
_value: 'default',
75+
get verbose() {
76+
this._value = 'verbose';
77+
return 'Set plus output to \'verbose\'';
78+
},
79+
get default() {
80+
this._value = 'default';
81+
return 'Set plus output to \'default\'';
82+
},
83+
get minimal() {
84+
this._value = 'minimal';
85+
return 'Set plus output to \'minimal\'';
86+
},
87+
},
88+
logging: {
89+
_on: !!process.env.LOG_ALL_TO_STDOUT,
90+
get on() {
91+
this._on = true;
92+
return 'Enabled event logging';
93+
},
94+
get off() {
95+
this._on = false;
96+
return 'Disabled event logging';
97+
},
98+
},
99+
fa: {
100+
_projection: {
101+
'*': 1,
102+
},
103+
project(projection) {
104+
this._projection = projection;
105+
return 'Set *fa projection to ' + JSON.stringify(projection);
106+
},
107+
},
108+
};
109+
72110
let client = new $.DataAPIClient(process.env.CLIENT_DB_TOKEN, { environment: process.env.CLIENT_DB_ENVIRONMENT, logging: [{ events: 'all', emits: 'event' }], httpOptions: { client: 'custom', fetcher } });
73111
let db = client.db(process.env.CLIENT_DB_URL, { keyspace: '$default_keyspace_name' });
74112
let dbAdmin = db.admin({ environment: process.env.CLIENT_DB_ENVIRONMENT });
@@ -79,15 +117,13 @@ node -i -e "
79117
? client.admin()
80118
: null;
81119
82-
let coll = db.collection('$default_coll_name');
83-
let coll_ = db.collection('$default_coll_name', { keyspace: 'other_keyspace', embeddingApiKey: process.env.TEST_OPENAI_KEY });
84-
let table = db.table('$default_table_name');
85-
let table_ = db.table('$default_table_name', { keyspace: 'other_keyspace', embeddingApiKey: process.env.TEST_OPENAI_KEY });
120+
let coll = withLaxPropertyAccess(db.collection('$default_coll_name'));
121+
let coll_ = withLaxPropertyAccess(db.collection('$default_coll_name', { keyspace: 'other_keyspace', embeddingApiKey: process.env.TEST_OPENAI_KEY }));
122+
let table = withLaxPropertyAccess(db.table('$default_table_name'));
123+
let table_ = withLaxPropertyAccess(db.table('$default_table_name', { keyspace: 'other_keyspace', embeddingApiKey: process.env.TEST_OPENAI_KEY }));
86124
87-
if (process.env.LOG_ALL_TO_STDOUT) {
88-
for (const event of ['commandSucceeded', 'adminCommandSucceeded', 'commandFailed', 'adminCommandFailed', /.*Warning/]) {
89-
client.on(event, (e) => console.dir(e, { depth: null }));
90-
}
125+
for (const event of ['commandSucceeded', 'adminCommandSucceeded', 'commandFailed', 'adminCommandFailed', /.*Warning/]) {
126+
client.on(event, (e) => cfg.logging._on && console.dir(e, { depth: null }));
91127
}
92128
93129
Object.defineProperty(this, 'cl', {
@@ -97,48 +133,34 @@ node -i -e "
97133
},
98134
});
99135
100-
Object.defineProperty(this, 'cda', {
101-
get: sp(() => coll.deleteMany({})),
102-
});
103-
104-
Object.defineProperty(this, 'tda', {
105-
get: sp(() => table.deleteMany({})),
106-
});
107-
108-
Object.defineProperty(this, 'cfa', {
109-
get: sp(() => coll.find({}).project({ '*': 1 }).toArray()),
110-
});
111-
112-
Object.defineProperty(this, 'tfa', {
113-
get: sp(() => table.find({}).project({ '*': 1 }).toArray()),
114-
});
115-
116-
Object.defineProperty(this, 'cda_', {
117-
get: sp(() => coll_.deleteMany({})),
118-
});
119-
120-
Object.defineProperty(this, 'tda_', {
121-
get: sp(() => table_.deleteMany({})),
122-
});
123-
124-
Object.defineProperty(this, 'cfa_', {
125-
get: sp(() => coll_.find({}).project({ '*': 1 }).toArray()),
126-
});
127-
128-
Object.defineProperty(this, 'tfa_', {
129-
get: sp(() => table_.find({}).project({ '*': 1 }).toArray()),
130-
});
131-
132-
const cif = sp(async (doc) => {
133-
const { insertedId } = await coll.insertOne(doc);
134-
return await coll.findOne({ _id: insertedId });
135-
});
136-
137-
const tif = sp(async (row) => {
138-
row = { text: $.UUID.v4().toString(), int: 0, ...row };
139-
await table.insertOne(row);
140-
return await table.findOne({ text: row.text, int: row.int });
141-
});
136+
for (const [pre, post, obj] of [
137+
['c', '', coll],
138+
['t', '', table],
139+
['c', '_', coll_],
140+
['t', '_', table_],
141+
]) {
142+
Object.defineProperty(this, pre + 'da' + post, {
143+
get: sp(() => obj.deleteMany({})),
144+
});
145+
146+
Object.defineProperty(this, pre + 'fa' + post, {
147+
get: sp(() => obj.find({}).project(cfg.fa._projection).toArray()),
148+
});
149+
150+
Object.defineProperty(this, pre + 'if' + post, {
151+
value: sp(async (doc) => {
152+
const toInsert = (pre === 't')
153+
? { text: $.UUID.v4().toString(), int: 0, ...doc }
154+
: doc;
155+
156+
const { insertedId } = await obj.insertOne(toInsert);
157+
158+
return (pre === 't')
159+
? await obj.findOne(insertedId)
160+
: await obj.findOne({ _id: insertedId });
161+
}),
162+
});
163+
}
142164
143165
const originalEmit = process.emit;
144166
@@ -150,21 +172,12 @@ node -i -e "
150172
};
151173
152174
const { styleText } = require('node:util');
153-
let promisePlusVerbosity = 'low';
154-
155-
Object.defineProperty(this, 'vl', {
156-
get: () => (promisePlusVerbosity = 'low', 0),
157-
});
158-
159-
Object.defineProperty(this, 'vh', {
160-
get: () => (promisePlusVerbosity = 'high', 0),
161-
});
162175
163176
Promise.prototype[Symbol.toPrimitive] = function() {
164177
let ok = 1;
165178
166-
switch (promisePlusVerbosity) {
167-
case 'high':
179+
switch (cfg.plusOutput._value) {
180+
case 'default':
168181
sp(() => this
169182
.then((r) => {
170183
console.log(styleText('gray', '\nCommand:'));
@@ -177,13 +190,12 @@ node -i -e "
177190
ok = 0;
178191
console.log(styleText('gray', '\nCommand:'));
179192
console.dir(JSON.parse(fetchInfo.body), { colors: true });
180-
console.log(styleText('gray', '\nError:'));
181-
console.dir(e, { colors: true });
193+
console.log(styleText('gray', '\nError - ' + e.name + ':'));
194+
console.log(styleText('red', e.message));
182195
console.log(styleText('gray', '\nSuccess?:'));
183-
}))()
184-
196+
}))();
185197
break;
186-
case 'low':
198+
case 'verbose':
187199
sp(() => this
188200
.then((r) => {
189201
console.log(styleText('gray', '\nCommand:'));
@@ -196,13 +208,43 @@ node -i -e "
196208
ok = 0;
197209
console.log(styleText('gray', '\nCommand:'));
198210
console.dir(JSON.parse(fetchInfo.body), { colors: true });
199-
console.log(styleText('gray', '\nError - ' + e.name + ':'));
200-
console.log(styleText('red', e.message));
211+
console.log(styleText('gray', '\nError:'));
212+
console.dir(e, { colors: true });
201213
console.log(styleText('gray', '\nSuccess?:'));
202-
}))()
214+
}))();
215+
break;
216+
case 'minimal':
217+
sp(() => this
218+
.then((r) => {
219+
console.dir(r, { colors: true });
220+
})
221+
.catch((e) => {
222+
ok = 0;
223+
console.log(styleText('red', e.message));
224+
}))();
203225
break;
204226
}
205227
206228
return ok;
207229
}
230+
231+
function withLaxPropertyAccess(obj) {
232+
const props = [...Object.getOwnPropertyNames(Object.getPrototypeOf(obj)), ...Object.getOwnPropertyNames(obj)];
233+
234+
return new Proxy(obj, {
235+
get(target, prop, receiver) {
236+
const matching = props
237+
.filter((k) => k.toLowerCase().startsWith(prop.toLowerCase()))
238+
.sort((a, b) => a.length - b.length);
239+
240+
const value = target[matching[0] ?? prop];
241+
242+
if (typeof value === 'function') {
243+
return value.bind(target);
244+
}
245+
246+
return value;
247+
}
248+
});
249+
}
208250
"

0 commit comments

Comments
 (0)