Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: docpage credits + @ulixee/client package
- Loading branch information
1 parent
0947862
commit 21c0175
Showing
40 changed files
with
1,383 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import * as url from 'url'; | ||
import * as fs from 'fs'; | ||
|
||
// Parse method copied from https://github.com/brianc/node-postgres | ||
// Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) | ||
// MIT License | ||
|
||
interface IConfig { | ||
host: string; | ||
database: string; | ||
client_encoding?: string; | ||
user?: string; | ||
password?: string; | ||
port?: string; | ||
sslcert?: string; | ||
sslkey?: string; | ||
sslrootcert?: string; | ||
sslmode?: string; | ||
ssl?: boolean | { | ||
cert?: string; | ||
key?: string; | ||
ca?: string; | ||
rejectUnauthorized?: boolean; | ||
}; | ||
} | ||
|
||
// parses a connection string | ||
export default class ConnectionString { | ||
public static parse(str: string): IConfig { | ||
// unix socket | ||
if (str.charAt(0) === '/') { | ||
const config = str.split(' '); | ||
return { host: config[0], database: config[1] }; | ||
} | ||
|
||
// url parse expects spaces encoded as %20 | ||
const result = url.parse( | ||
/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str) ? encodeURI(str).replace(/%25(\d\d)/g, '%$1') : str, | ||
true | ||
); | ||
const config = result.query as unknown as IConfig; | ||
for (const k in config) { | ||
if (Array.isArray(config[k])) { | ||
config[k] = config[k][config[k].length - 1]; | ||
} | ||
} | ||
|
||
const auth = (result.auth || ':').split(':'); | ||
config.user = auth[0]; | ||
config.password = auth.splice(1).join(':'); | ||
|
||
config.port = result.port || undefined; | ||
if (result.protocol === 'socket:') { | ||
if (result.pathname) config.host = decodeURI(result.pathname); | ||
config.database = result.query.db as string; | ||
config.client_encoding = result.query.encoding as string; | ||
return config; | ||
} | ||
if (!config.host) { | ||
// Only set the host if there is no equivalent query param. | ||
config.host = result.hostname || ''; | ||
} | ||
|
||
// If the host is missing it might be a URL-encoded path to a socket. | ||
let pathname = result.pathname; | ||
if (!config.host && pathname && /^%2f/i.test(pathname)) { | ||
const pathnameSplit = pathname.split('/'); | ||
config.host = decodeURIComponent(pathnameSplit[0]) | ||
pathname = pathnameSplit.splice(1).join('/'); | ||
} | ||
// result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) | ||
// only strip the slash if it is present. | ||
if (pathname && pathname.charAt(0) === '/') { | ||
pathname = pathname.slice(1) || null | ||
} | ||
config.database = pathname && decodeURI(pathname) || ''; | ||
|
||
if ((config.ssl as any) === 'true' || (config.ssl as any) === '1') { | ||
config.ssl = true | ||
} | ||
|
||
if ((config.ssl as any) === '0') { | ||
config.ssl = false | ||
} | ||
|
||
if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) { | ||
config.ssl = {} | ||
if (config.sslcert) { | ||
config.ssl.cert = fs.readFileSync(config.sslcert).toString() | ||
} | ||
|
||
if (config.sslkey) { | ||
config.ssl.key = fs.readFileSync(config.sslkey).toString() | ||
} | ||
|
||
if (config.sslrootcert) { | ||
config.ssl.ca = fs.readFileSync(config.sslrootcert).toString() | ||
} | ||
|
||
switch (config.sslmode) { | ||
case 'disable': { | ||
config.ssl = false | ||
break | ||
} | ||
case 'prefer': | ||
case 'require': | ||
case 'verify-ca': | ||
case 'verify-full': { | ||
break | ||
} | ||
case 'no-verify': { | ||
config.ssl.rejectUnauthorized = false | ||
break | ||
} | ||
} | ||
} | ||
|
||
return config | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "@ulixee/client-connection-string", | ||
"version": "2.0.0-alpha.18", | ||
"main": "index.js", | ||
"repository": "git@github.com:ulixee/platform.git", | ||
"license": "MIT", | ||
"scripts": {}, | ||
"dependencies": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
- title: Overview | ||
items: | ||
- Introduction | ||
|
||
- title: API | ||
items: | ||
- Client | ||
- ConnectionParameters | ||
|
||
- title: Features | ||
items: | ||
- Connecting | ||
- Queries | ||
- Data Types | ||
- SQL Spec | ||
|
||
- title: Help | ||
items: | ||
- Prerequisites | ||
- How to upgrade | ||
- Troubleshooting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { EventEmitter } from 'events'; | ||
import Log from '@ulixee/commons/lib/Logger'; | ||
import DatastoreApiClient from '@ulixee/datastore/lib/DatastoreApiClient'; | ||
import ConnectionParameters from './lib/ConnectionParameters'; | ||
|
||
// ulx://paymentHash@ip:port/versionHash | ||
|
||
const { log } = Log(module); | ||
|
||
interface IConfig { | ||
connectionString?: string; | ||
user?: string; | ||
password?: string; | ||
host?: string; | ||
port?: string | number; | ||
database?: string; | ||
} | ||
|
||
export default class Client extends EventEmitter { | ||
private connectionParameters; | ||
private user: string; | ||
private password: string; | ||
private host: string; | ||
private port: string; | ||
private database: string; | ||
|
||
#apiClient: DatastoreApiClient; | ||
|
||
constructor(config: string | IConfig = {}) { | ||
super(); | ||
|
||
this.connectionParameters = new ConnectionParameters(config) | ||
this.user = this.connectionParameters.user | ||
this.database = this.connectionParameters.database | ||
this.port = this.connectionParameters.port | ||
this.host = this.connectionParameters.host | ||
this.password = this.connectionParameters.password | ||
} | ||
|
||
public get apiClient(): DatastoreApiClient { | ||
if (!this.#apiClient) { | ||
const address = `${this.host}:${this.port}`; | ||
this.#apiClient = new DatastoreApiClient(address); | ||
// const onError = this.onConnectionError.bind(this); | ||
} | ||
return this.#apiClient; | ||
} | ||
|
||
public async run(functionOrTableName: string, filter?: Record<string, any>): Promise<any[]> { | ||
return await this.fetch(functionOrTableName, filter); | ||
} | ||
|
||
public async fetch(functionOrTableName: string, filter?: Record<string, any>): Promise<any[]> { | ||
const options = { | ||
payment: this.user ? { | ||
credits: { | ||
id: this.user, | ||
secret: this.password, | ||
} | ||
} : undefined, | ||
}; | ||
|
||
return await this.apiClient.stream(this.database, functionOrTableName, filter, options); | ||
} | ||
|
||
public async query<TResultType = any>( | ||
sql: string, | ||
boundValues: any[] = [], | ||
): Promise<TResultType> { | ||
const options = { | ||
boundValues, | ||
payment: this.user ? { | ||
credits: { | ||
id: this.user, | ||
secret: this.password, | ||
} | ||
} : undefined, | ||
}; | ||
const response = await this.apiClient.query(this.database, sql, options); | ||
|
||
return response.outputs as any; | ||
} | ||
|
||
private onConnectionError(error: Error): void { | ||
if (error) { | ||
log.error('Error connecting to core', { | ||
error, | ||
sessionId: null, | ||
}); | ||
this.emit('error', error); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import ConnectionString from '@ulixee/client-connection-string'; | ||
import defaults from './defaults'; | ||
|
||
export default class ConnectionParameters { | ||
user: string; | ||
database: string; | ||
port: number; | ||
host: string; | ||
binary: string; | ||
options: any; | ||
query_timeout: string | number; | ||
connect_timeout: string | number; | ||
|
||
constructor(config) { | ||
// if a string is passed, it is a raw connection string so we parse it into a config | ||
config = typeof config === 'string' ? ConnectionString.parse(config) : config || {} | ||
|
||
// if the config has a connectionString defined, parse IT into the config we use | ||
// this will override other default values with what is stored in connectionString | ||
if (config.connectionString) { | ||
config = { ...config, ...ConnectionString.parse(config.connectionString) }; | ||
} | ||
|
||
this.user = val('user', config) | ||
this.database = val('database', config) | ||
|
||
if (this.database === undefined) { | ||
this.database = null; | ||
} | ||
|
||
this.port = parseInt(val('port', config), 10) | ||
this.host = val('host', config) | ||
|
||
// "hiding" the password so it doesn't show up in stack traces | ||
// or if the client is console.logged | ||
Object.defineProperty(this, 'password', { | ||
configurable: true, | ||
enumerable: false, | ||
writable: true, | ||
value: val('password', config), | ||
}) | ||
|
||
this.binary = val('binary', config) | ||
this.options = val('options', config) | ||
|
||
this.query_timeout = val('query_timeout', config, false) | ||
|
||
if (config.connectionTimeoutMillis === undefined) { | ||
this.connect_timeout = process.env.ULX_CONNECT_TIMEOUT || 0 | ||
} else { | ||
this.connect_timeout = Math.floor(config.connectionTimeoutMillis / 1000) | ||
} | ||
} | ||
} | ||
|
||
|
||
function val(key: string, config: any, envVar?: string | boolean): string { | ||
if (envVar === undefined) { | ||
envVar = process.env[`ULX_${key.toUpperCase()}`]; | ||
} else if (envVar === false) { | ||
// do nothing ... use false | ||
} else { | ||
envVar = process.env[envVar as string] | ||
} | ||
|
||
return config[key] || envVar || defaults[key] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
export default { | ||
// database host. defaults to localhost | ||
host: 'localhost', | ||
|
||
// database user's name | ||
user: undefined, | ||
|
||
// name of database to connect | ||
database: undefined, | ||
|
||
// database user's password | ||
password: undefined, | ||
|
||
// a Ulixee connection string to be used instead of setting individual connection items | ||
// NOTE: Setting this value will cause it to override any other value (such as database or user) defined | ||
// in the defaults object. | ||
connectionString: undefined, | ||
|
||
// database port | ||
port: 1818, | ||
|
||
// number of rows to return at a time from a prepared statement's | ||
// portal. 0 will return all rows at once | ||
rows: 0, | ||
|
||
options: undefined, | ||
|
||
parseInputDatesAsUTC: false, | ||
|
||
// max milliseconds any query using this connection will execute for before timing out in error. | ||
// false=unlimited | ||
statement_timeout: false, | ||
|
||
// max milliseconds to wait for query to complete (client side) | ||
query_timeout: false, | ||
|
||
connect_timeout: 0, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "@ulixee/sql", | ||
"version": "2.0.0-alpha.18", | ||
"main": "index.js", | ||
"repository": "git@github.com:ulixee/platform.git", | ||
"license": "MIT", | ||
"scripts": {}, | ||
"dependencies": { | ||
"@ulixee/client-connection-string": "2.0.0-alpha.18", | ||
"@ulixee/net": "2.0.0-alpha.18", | ||
"@ulixee/datastore": "2.0.0-alpha.18", | ||
"@ulixee/commons": "2.0.0-alpha.18" | ||
}, | ||
"devDependencies": { | ||
"@ulixee/schema": "2.0.0-alpha.18", | ||
"@ulixee/sql-ast": "2.0.0-alpha.18", | ||
"@ulixee/sql-engine": "2.0.0-alpha.18", | ||
"@ulixee/specification": "2.0.0-alpha.18", | ||
"@ulixee/datastore-packager": "2.0.0-alpha.18", | ||
"@ulixee/miner": "2.0.0-alpha.18", | ||
"@ulixee/crypto": "2.0.0-alpha.18" | ||
} | ||
} |
Oops, something went wrong.