Skip to content

Commit 3b20359

Browse files
committed
Typescript CLI skeleton and packages config
0 parents  commit 3b20359

16 files changed

+4181
-0
lines changed

.eslintrc.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
parser: '@typescript-eslint/parser',
4+
plugins: ['@typescript-eslint'],
5+
extends: [
6+
'eslint:recommended',
7+
'plugin:@typescript-eslint/recommended',
8+
'prettier',
9+
],
10+
rules: {
11+
'@typescript-eslint/no-unused-vars': [
12+
'error',
13+
{
14+
argsIgnorePattern: '^_',
15+
},
16+
],
17+
},
18+
};

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
build

.prettierignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Package directories
2+
node_modules
3+
4+
# Test coverage
5+
.nyc_output
6+
coverage
7+
8+
# TypeScript build
9+
build

.prettierrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"trailingComma": "all",
3+
"tabWidth": 2,
4+
"singleQuote": true
5+
}

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Krinql CLI

package.json

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "krinql-cli",
3+
"version": "0.0.1",
4+
"description": "A simple developer-friendly CLI for using Krinql",
5+
"main": "./build/cli.js",
6+
"bin": {
7+
"krinql": "./build/cli.js",
8+
"krinql-cli": "./build/cli.js"
9+
},
10+
"engines": {
11+
"node": ">=14.0.0"
12+
},
13+
"files": [
14+
"/assets",
15+
"/build"
16+
],
17+
"keywords": [
18+
"cli",
19+
"krinql",
20+
"codex",
21+
"AI"
22+
],
23+
"author": "Krinql <[email protected]> (krinql.com)",
24+
"homepage": "https://krinql.com",
25+
"bugs": "https://github.com/krinql/cli/issues",
26+
"scripts": {
27+
"build": "tsc",
28+
"package:linux": "pkg . --no-bytecode --targets node14-linux-x64 --output bin/linux/snip",
29+
"package:macos": "pkg . --no-bytecode --targets node14-macos-x64 --output bin/macos/snip",
30+
"format": "prettier --loglevel warn --write \"**/*.{ts,js,json,yaml}\"",
31+
"format:check": "prettier --loglevel warn --check \"**/*.{ts,js,json,yaml}\"",
32+
"lint": "eslint \"src/**/*.ts\" --fix",
33+
"lint:check": "eslint \"src/**/*.ts\""
34+
},
35+
"dependencies": {
36+
"axios": "^0.24.0",
37+
"chalk": "4.1.1",
38+
"figlet": "^1.5.2",
39+
"ora": "5.4.1",
40+
"yargs": "17.0.1"
41+
},
42+
"devDependencies": {
43+
"@types/figlet": "^1.5.4",
44+
"@types/node": "16.0.1",
45+
"@types/yargs": "17.0.2",
46+
"@typescript-eslint/eslint-plugin": "4.28.2",
47+
"@typescript-eslint/parser": "4.28.2",
48+
"eslint": "7.30.0",
49+
"eslint-config-prettier": "8.3.0",
50+
"pkg": "5.3.0",
51+
"prettier": "2.3.2",
52+
"ts-node": "10.0.0",
53+
"typescript": "4.3.5"
54+
},
55+
"pkg": {
56+
"scripts": "build/**/*.js"
57+
},
58+
"ava": {
59+
"extensions": [
60+
"ts"
61+
],
62+
"require": [
63+
"ts-node/register"
64+
]
65+
}
66+
}

src/cli.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env node
2+
3+
import yargs from 'yargs';
4+
import { hideBin } from 'yargs/helpers';
5+
6+
import handleError from './handleError';
7+
8+
yargs(hideBin(process.argv))
9+
// Use the commands directory to scaffold.
10+
.commandDir('commands')
11+
// Default command if none supplied - shows help.
12+
.command(
13+
'$0',
14+
'The Krinql CLI usage',
15+
() => undefined,
16+
() => {
17+
yargs.showHelp();
18+
},
19+
)
20+
// Enable strict mode.
21+
.strict()
22+
// Useful aliases.
23+
.alias({ h: 'help' })
24+
// Be nice.
25+
.epilogue('For more information, checkout https://krinql.com')
26+
// Handle failures.
27+
.fail(handleError).argv;

src/commands/login.outputs.ts

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import chalk from 'chalk';
2+
import figlet from 'figlet';
3+
4+
export const welcome = (): void => {
5+
const welcomeAsciiText = figlet.textSync('Krinql')
6+
7+
process.stdout.write(`
8+
${welcomeAsciiText}
9+
10+
Welcome to Krinql.
11+
Access krinql features without leaving your terminal or IDE.
12+
13+
`);
14+
};
15+
16+
export const userConfigFound = (profile: string): Promise<never> => {
17+
process.stdout.write(`
18+
The profile ${chalk.cyan(profile)} is already configured! 👌
19+
20+
If you would like to login using a new profile, run the following:
21+
22+
${chalk.bold(
23+
`$ krinql login --reauth`,
24+
)}
25+
26+
`);
27+
28+
process.exit(0);
29+
};
30+
31+
export const deviceConfigured = async (configPath: string): Promise<never> => {
32+
process.stdout.write(`
33+
✨ Configuration written to ${chalk.cyan(configPath)}.
34+
35+
Let's try asking a question!
36+
37+
${chalk.bold('$ krinql email regex javascript')}
38+
39+
`);
40+
41+
process.exit(0);
42+
};

src/commands/login.ts

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import ora from 'ora';
2+
import * as outputs from './login.outputs';
3+
import { Builder, Handler } from './login.types';
4+
5+
6+
export const command = 'login';
7+
export const desc = 'Login with a new or existing account';
8+
9+
export const builder: Builder = (yargs) =>
10+
yargs
11+
.options({
12+
reauth: {
13+
type: 'boolean',
14+
desc: 're-authenticate using Krinql',
15+
alias: 'reauth'
16+
}
17+
})
18+
.example([
19+
['$0 login'],
20+
['$0 login --reauth'],
21+
]);
22+
23+
export const handler: Handler = async (argv) => {
24+
const spinner = ora()
25+
26+
const { reauth } = argv;
27+
28+
outputs.welcome();
29+
30+
31+
spinner.start('Logging in');
32+
// await api.login
33+
spinner.succeed();
34+
35+
36+
37+
38+
spinner.start('Fetching existing account configuration');
39+
40+
41+
spinner.succeed();
42+
43+
44+
// const configPath = await writeUserConfig({
45+
// });
46+
47+
// outputs.deviceConfigured(configPath);
48+
49+
50+
};

src/commands/login.types.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { Arguments, CommandBuilder } from 'yargs';
2+
3+
import type { BaseOptions } from '../shared';
4+
5+
export type Options = BaseOptions & {
6+
reauth: boolean | undefined;
7+
};
8+
9+
export type Builder = CommandBuilder<Options, Options>;
10+
11+
export type Handler = (argv: Arguments<Options>) => PromiseLike<void>;

src/handleError.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import chalk from 'chalk';
2+
import { EOL } from 'os';
3+
4+
const printMessage = (message: string) => {
5+
process.stderr.write(chalk.red(`Error: ${message}`) + EOL);
6+
process.stderr.write(
7+
`Hint: Use the ${chalk.green(
8+
'--help',
9+
)} option to get help about the usage` + EOL,
10+
);
11+
};
12+
13+
export default async (message: string, error: Error): Promise<never> => {
14+
if (message) {
15+
printMessage(message);
16+
process.exit(1);
17+
}
18+
19+
let errorMessage = 'Unknown error occurred';
20+
21+
if (error instanceof Response) {
22+
const { ErrorMessage } = await error.json();
23+
24+
if (ErrorMessage) {
25+
errorMessage = ErrorMessage;
26+
}
27+
} else {
28+
errorMessage = error.message;
29+
}
30+
31+
printMessage(errorMessage);
32+
process.exit(1);
33+
};

src/services/api.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
import axios from 'axios';
3+
import { API_BASE_PATH } from '../shared';
4+
5+
const api = axios.create({ baseURL: API_BASE_PATH });
6+
7+
export default api;

src/services/config/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export type UserConfig = {
2+
Account: {
3+
accessToken: string;
4+
refreshToken: string;
5+
name: string;
6+
};
7+
};

src/shared.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export type BaseOptions = {
2+
query: string;
3+
};
4+
5+
export const baseOptions = {
6+
query: { type: 'string'},
7+
} as const;
8+
9+
export const API_BASE_PATH = 'https://krinql.com/api';

tsconfig.json

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
{
2+
"compilerOptions": {
3+
/* Visit https://aka.ms/tsconfig.json to read more about this file */
4+
5+
/* Basic Options */
6+
// "incremental": true, /* Enable incremental compilation */
7+
"target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
8+
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
9+
// "lib": [], /* Specify library files to be included in the compilation. */
10+
// "allowJs": true, /* Allow javascript files to be compiled. */
11+
// "checkJs": true, /* Report errors in .js files. */
12+
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
13+
// "declaration": true, /* Generates corresponding '.d.ts' file. */
14+
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
15+
// "sourceMap": true, /* Generates corresponding '.map' file. */
16+
// "outFile": "./", /* Concatenate and emit output to single file. */
17+
"outDir": "./build" /* Redirect output structure to the directory. */,
18+
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
19+
// "composite": true, /* Enable project compilation */
20+
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
21+
// "removeComments": true, /* Do not emit comments to output. */
22+
// "noEmit": true, /* Do not emit outputs. */
23+
"importHelpers": false /* Import emit helpers from 'tslib'. */,
24+
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25+
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26+
27+
/* Strict Type-Checking Options */
28+
"strict": true /* Enable all strict type-checking options. */,
29+
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
30+
// "strictNullChecks": true, /* Enable strict null checks. */
31+
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
32+
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
33+
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
34+
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
35+
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
36+
37+
/* Additional Checks */
38+
// "noUnusedLocals": true, /* Report errors on unused locals. */
39+
// "noUnusedParameters": true, /* Report errors on unused parameters. */
40+
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
41+
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
42+
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
43+
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
44+
45+
/* Module Resolution Options */
46+
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
47+
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
48+
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
49+
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
50+
// "typeRoots": [], /* List of folders to include type definitions from. */
51+
// "types": [], /* Type declaration files to be included in compilation. */
52+
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
53+
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
54+
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
55+
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
56+
57+
/* Source Map Options */
58+
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
59+
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
60+
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
61+
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
62+
63+
/* Experimental Options */
64+
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
65+
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
66+
67+
/* Advanced Options */
68+
"skipLibCheck": true /* Skip type checking of declaration files. */,
69+
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
70+
},
71+
"exclude": ["test"]
72+
}

0 commit comments

Comments
 (0)