@quonfig/cli 0.0.6 → 0.0.7
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/README.md +128 -80
- package/dist/codegen/local-config-reader.d.ts +6 -0
- package/dist/codegen/local-config-reader.js +113 -0
- package/dist/commands/create.js +3 -0
- package/dist/commands/generate.d.ts +3 -2
- package/dist/commands/generate.js +18 -10
- package/dist/commands/login.js +5 -2
- package/dist/commands/sdk-key/create.d.ts +11 -0
- package/dist/commands/sdk-key/create.js +100 -0
- package/dist/commands/sdk-key/list.d.ts +10 -0
- package/dist/commands/sdk-key/list.js +48 -0
- package/dist/commands/sdk-key/revoke.d.ts +10 -0
- package/dist/commands/sdk-key/revoke.js +30 -0
- package/dist/commands/sdk-key.d.ts +6 -0
- package/dist/commands/sdk-key.js +15 -0
- package/dist/interactive-prompt.js +0 -4
- package/dist/ui/get-value.js +4 -1
- package/dist/verify/validate.js +28 -8
- package/oclif.manifest.json +277 -128
- package/package.json +1 -1
- package/dist/codegen/config-downloader.d.ts +0 -7
- package/dist/codegen/config-downloader.js +0 -26
- package/dist/commands/download.d.ts +0 -13
- package/dist/commands/download.js +0 -63
- package/dist/commands/serve.d.ts +0 -13
- package/dist/commands/serve.js +0 -101
package/dist/commands/serve.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import { ConfigType } from '@quonfig/node';
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import http from 'node:http';
|
|
5
|
-
import { BaseCommand } from '../index.js';
|
|
6
|
-
import { initQuonfig } from '../quonfig.js';
|
|
7
|
-
import { valueTypeStringForConfig } from '@quonfig/node';
|
|
8
|
-
import { javaScriptClientFormattedContextToContext } from '../util/context.js';
|
|
9
|
-
const allowCORSPreflight = (res) => {
|
|
10
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
11
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
|
12
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, x-quonfig-client-version, authorization');
|
|
13
|
-
};
|
|
14
|
-
const ALWAYS_SEND_CONFIG_TYPES = new Set([ConfigType.FeatureFlag, ConfigType.LogLevel]);
|
|
15
|
-
const base64ToBytes = (base64) => {
|
|
16
|
-
const binString = Buffer.from(base64, 'base64').toString('binary');
|
|
17
|
-
return Uint8Array.from(binString, (m) => m.codePointAt(0));
|
|
18
|
-
};
|
|
19
|
-
export default class Serve extends BaseCommand {
|
|
20
|
-
static args = {
|
|
21
|
-
'data-file': Args.string({ description: 'file to read', required: true }),
|
|
22
|
-
};
|
|
23
|
-
static description = `Serve a datafile on a local port
|
|
24
|
-
|
|
25
|
-
You can download a datafile using the \`download\` command.
|
|
26
|
-
|
|
27
|
-
You'll need to update your JavaScript (or React) client to point to this server.
|
|
28
|
-
|
|
29
|
-
e.g. \`endpoints: ["http://localhost:3099"],\`
|
|
30
|
-
`;
|
|
31
|
-
static examples = ['<%= config.bin %> <%= command.id %> ./quonfig.test.588.config.json --port=3099 '];
|
|
32
|
-
static flags = {
|
|
33
|
-
port: Flags.integer({ default: 3099, description: 'port to serve on' }),
|
|
34
|
-
};
|
|
35
|
-
async run() {
|
|
36
|
-
const { args, flags } = await this.parse(Serve);
|
|
37
|
-
const file = args['data-file'];
|
|
38
|
-
if (!fs.existsSync(file)) {
|
|
39
|
-
return this.error(`File not found: ${file}`);
|
|
40
|
-
}
|
|
41
|
-
let quonfig;
|
|
42
|
-
try {
|
|
43
|
-
quonfig = await initQuonfig(this, file);
|
|
44
|
-
if (!quonfig) {
|
|
45
|
-
throw new Error('Quonfig not initialized');
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
catch (error_) {
|
|
49
|
-
const error = error_;
|
|
50
|
-
if (/No projectEnvId found in config/.test(error.message) ||
|
|
51
|
-
/is not iterable/.test(error.message) ||
|
|
52
|
-
/Unexpected end of JSON input/.test(error.message)) {
|
|
53
|
-
return this.error(`${error.message}\nYour download file seems invalid or corrupt. Please redownload your datafile.`);
|
|
54
|
-
}
|
|
55
|
-
return this.error(error);
|
|
56
|
-
}
|
|
57
|
-
const { port } = flags;
|
|
58
|
-
const server = http.createServer(this.requestHandler(quonfig));
|
|
59
|
-
server.listen(port, (err) => {
|
|
60
|
-
if (err) {
|
|
61
|
-
return this.err(err);
|
|
62
|
-
}
|
|
63
|
-
console.log(`Server is listening on ${port}. Press ctrl-c to stop.`);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
requestHandler(quonfig) {
|
|
67
|
-
return (req, res) => {
|
|
68
|
-
allowCORSPreflight(res);
|
|
69
|
-
// Handle CORS preflight request
|
|
70
|
-
if (req.method === 'OPTIONS') {
|
|
71
|
-
res.writeHead(204);
|
|
72
|
-
res.end();
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const match = req.url?.match(/^\/?\/configs\/eval-with-context\/(.+)$/);
|
|
76
|
-
if (req.method === 'GET' && match) {
|
|
77
|
-
const encodedContext = match[1].split('?')[0];
|
|
78
|
-
console.log(`Received context: ${encodedContext}`);
|
|
79
|
-
console.log(`Decoded context: ${decodeURIComponent(encodedContext)}`);
|
|
80
|
-
const decoded = new TextDecoder().decode(base64ToBytes(decodeURIComponent(encodedContext)));
|
|
81
|
-
const context = javaScriptClientFormattedContextToContext(JSON.parse(decoded));
|
|
82
|
-
this.log(`${new Date().toISOString()}: Provided context: ${JSON.stringify(context)}`);
|
|
83
|
-
const config = {};
|
|
84
|
-
for (const key of quonfig.keys()) {
|
|
85
|
-
const raw = quonfig.rawConfig(key);
|
|
86
|
-
if (raw && (ALWAYS_SEND_CONFIG_TYPES.has(raw.type) || raw.sendToClientSdk)) {
|
|
87
|
-
const valueType = valueTypeStringForConfig(raw) ?? '?';
|
|
88
|
-
config[key] = { value: { [valueType]: quonfig.get(key, context) } };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
92
|
-
res.end(JSON.stringify({ evaluations: config }));
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
this.verboseLog(`No handler for ${req.method} ${req.url}`);
|
|
96
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
97
|
-
res.end('Not Found. You can only GET /configs/eval-with-context/<context>');
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|