@niledatabase/server 4.0.0-alpha.10 → 4.0.0-alpha.12
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 +65 -15
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +59 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +59 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,39 +1,83 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img width="1434" alt="Screen Shot 2024-09-18 at 9 20 04 AM" src="https://github.com/user-attachments/assets/20585883-5cdc-4f15-93d3-dc150e87bc11">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
---
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
# Nile's Server-Side SDK
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
This package (`@niledatabase/server`) is part of [Nile's Javascript SDK](https://github.com/niledatabase/nile-js/tree/main).
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
import Nile from '@niledatabase/server';
|
|
11
|
+
Nile's server-side Javascript package provides:
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
13
|
+
- 🔐 Methods for working with Nile's user and tenant APIs
|
|
14
|
+
- 🔑 Generated routes for authentication
|
|
15
|
+
- 🔍 SQL query execution with tenant and user context management
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
**Nile is a Postgres platform that decouples storage from compute, virtualizes tenants, and supports vertical and horizontal scaling globally to ship B2B applications fast while being safe with limitless scale.** All B2B applications are multi-tenant. A tenant/customer is primarily a company, an organization, or a workspace in your product that contains a group of users. A B2B application provides services to multiple tenants. Tenant is the basic building block of all B2B applications.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Installation
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
npm install @niledatabase/server
|
|
20
25
|
```
|
|
21
26
|
|
|
22
|
-
###
|
|
27
|
+
### Initialize SDK with env vars
|
|
28
|
+
|
|
29
|
+
The recommended way to initialize Nile SDK is with `.env` file. You can copy the environment variables from [Nile console](https://console.thenile.dev). It should look similar to this:
|
|
23
30
|
|
|
24
31
|
```bash
|
|
25
32
|
NILEDB_USER=username
|
|
26
33
|
NILEDB_PASSWORD=password
|
|
34
|
+
NILEDB_API_URL=https://us-west-2.api.thenile.dev/v2/databases/DBID
|
|
35
|
+
NILEDB_POSTGRES_URL=postgres://us-west-2.db.thenile.dev:5432/dbname
|
|
27
36
|
```
|
|
28
37
|
|
|
29
38
|
```ts
|
|
30
39
|
import Nile from '@niledatabase/server';
|
|
31
40
|
|
|
32
41
|
const nile = await Nile();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Initialize SDK with configuration object
|
|
33
45
|
|
|
34
|
-
|
|
46
|
+
```ts
|
|
47
|
+
import Nile from '@niledatabase/server';
|
|
48
|
+
|
|
49
|
+
const nile = await Nile({
|
|
50
|
+
user: 'username',
|
|
51
|
+
password: 'password',
|
|
52
|
+
debug: true
|
|
53
|
+
});
|
|
54
|
+
```
|
|
35
55
|
|
|
36
|
-
|
|
56
|
+
### Call Nile APIs
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
const tenant = await nile.api.tenants.createTenant(tenantName);
|
|
60
|
+
if (tenant instanceof Response) {
|
|
61
|
+
const err = await tenant.text()
|
|
62
|
+
console.log("ERROR creating tenant: ", tenant, err);
|
|
63
|
+
return { message: "Error creating tenant" };
|
|
64
|
+
}
|
|
65
|
+
nile.tenant_id = tenant.id // set context
|
|
66
|
+
// Get tenant name doesn't need any input parameters
|
|
67
|
+
// because it uses the tenant ID and user token from the context
|
|
68
|
+
const checkTenant = await tenantNile.api.tenants.getTenant();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Query the database
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
nile.tenant_id = tenant.id // set context
|
|
75
|
+
|
|
76
|
+
const todos = await nile.db
|
|
77
|
+
.query("select * from todos order by title")
|
|
78
|
+
.catch((e: Error) => {
|
|
79
|
+
console.error(e);
|
|
80
|
+
}); // no need for where clause if you previously set Nile context
|
|
37
81
|
```
|
|
38
82
|
|
|
39
83
|
## Initialization
|
|
@@ -59,3 +103,9 @@ Configuration passed to `Server` takes precedence over `.env` vars.
|
|
|
59
103
|
| api.cookieKey | `string` | | Key for API cookie. Default is `token`. |
|
|
60
104
|
| api.token | `string` | NILEDB_TOKEN | Token for API authentication. Mostly for debugging. |
|
|
61
105
|
| debug | `boolean` | | Flag for enabling debug logging. |
|
|
106
|
+
|
|
107
|
+
## Learn more
|
|
108
|
+
|
|
109
|
+
- You can learn more about Nile and the SDK in [https://thenile.dev/docs]
|
|
110
|
+
- You can find detailed code examples in [our main repo](https://github.com/niledatabase/niledatabase)
|
|
111
|
+
- Nile SDK interacts with APIs in Nile Auth service. You can learn more about it in the [repository](https://github.com/niledatabase/nile-auth) and the [docs](https://thenile.dev/docs/auth)
|
package/dist/index.d.mts
CHANGED
|
@@ -145,6 +145,13 @@ type Tenant = {
|
|
|
145
145
|
name: string;
|
|
146
146
|
};
|
|
147
147
|
|
|
148
|
+
type Provider = {
|
|
149
|
+
id: string;
|
|
150
|
+
name: string;
|
|
151
|
+
type: string;
|
|
152
|
+
signinUrl: string;
|
|
153
|
+
callbackUr: string;
|
|
154
|
+
};
|
|
148
155
|
type JWT = {
|
|
149
156
|
email: string;
|
|
150
157
|
sub: string;
|
|
@@ -212,6 +219,16 @@ declare class Auth extends Config {
|
|
|
212
219
|
handleHeaders(init?: RequestInit): RequestInit | undefined;
|
|
213
220
|
get sessionUrl(): string;
|
|
214
221
|
getSession: (req: NileRequest<void> | Headers, init?: RequestInit) => Promise<JWT | ActiveSession | Response | undefined>;
|
|
222
|
+
get getCsrfUrl(): string;
|
|
223
|
+
getCsrf(req: NileRequest<void> | Headers, init?: RequestInit): Promise<JSON | Response>;
|
|
224
|
+
get listProvidersUrl(): string;
|
|
225
|
+
listProviders: (req: NileRequest<void> | Headers, init?: RequestInit) => Promise<Response | {
|
|
226
|
+
[key: string]: Provider;
|
|
227
|
+
}>;
|
|
228
|
+
get signOutUrl(): string;
|
|
229
|
+
signOut: (req: NileRequest<void | {
|
|
230
|
+
callbackUrl?: string;
|
|
231
|
+
}> | Headers, init?: RequestInit) => Promise<Response | JSON>;
|
|
215
232
|
}
|
|
216
233
|
|
|
217
234
|
declare class Tenants extends Config {
|
package/dist/index.d.ts
CHANGED
|
@@ -145,6 +145,13 @@ type Tenant = {
|
|
|
145
145
|
name: string;
|
|
146
146
|
};
|
|
147
147
|
|
|
148
|
+
type Provider = {
|
|
149
|
+
id: string;
|
|
150
|
+
name: string;
|
|
151
|
+
type: string;
|
|
152
|
+
signinUrl: string;
|
|
153
|
+
callbackUr: string;
|
|
154
|
+
};
|
|
148
155
|
type JWT = {
|
|
149
156
|
email: string;
|
|
150
157
|
sub: string;
|
|
@@ -212,6 +219,16 @@ declare class Auth extends Config {
|
|
|
212
219
|
handleHeaders(init?: RequestInit): RequestInit | undefined;
|
|
213
220
|
get sessionUrl(): string;
|
|
214
221
|
getSession: (req: NileRequest<void> | Headers, init?: RequestInit) => Promise<JWT | ActiveSession | Response | undefined>;
|
|
222
|
+
get getCsrfUrl(): string;
|
|
223
|
+
getCsrf(req: NileRequest<void> | Headers, init?: RequestInit): Promise<JSON | Response>;
|
|
224
|
+
get listProvidersUrl(): string;
|
|
225
|
+
listProviders: (req: NileRequest<void> | Headers, init?: RequestInit) => Promise<Response | {
|
|
226
|
+
[key: string]: Provider;
|
|
227
|
+
}>;
|
|
228
|
+
get signOutUrl(): string;
|
|
229
|
+
signOut: (req: NileRequest<void | {
|
|
230
|
+
callbackUrl?: string;
|
|
231
|
+
}> | Headers, init?: RequestInit) => Promise<Response | JSON>;
|
|
215
232
|
}
|
|
216
233
|
|
|
217
234
|
declare class Tenants extends Config {
|
package/dist/index.js
CHANGED
|
@@ -1077,7 +1077,8 @@ async function _fetch(config, path, opts) {
|
|
|
1077
1077
|
const errorHandler = typeof response?.clone === "function" ? response.clone() : null;
|
|
1078
1078
|
let msg = "";
|
|
1079
1079
|
try {
|
|
1080
|
-
res = await response?.json()
|
|
1080
|
+
res = await response?.json().catch(() => {
|
|
1081
|
+
});
|
|
1081
1082
|
} catch (e) {
|
|
1082
1083
|
if (errorHandler) {
|
|
1083
1084
|
msg = await errorHandler.text();
|
|
@@ -1110,7 +1111,8 @@ async function _fetch(config, path, opts) {
|
|
|
1110
1111
|
error(
|
|
1111
1112
|
`[fetch][response][status: ${errorHandler?.status}] UNHANDLED ERROR`,
|
|
1112
1113
|
{
|
|
1113
|
-
|
|
1114
|
+
response,
|
|
1115
|
+
message: await response.text()
|
|
1114
1116
|
}
|
|
1115
1117
|
);
|
|
1116
1118
|
return new ResponseError(null, {
|
|
@@ -1773,7 +1775,7 @@ var appRoutes = (prefix = "/api") => ({
|
|
|
1773
1775
|
TENANT_USER: `${prefix}/tenants/{tenantId}/users/{userId}`,
|
|
1774
1776
|
TENANT_USERS: `${prefix}/tenants/{tenantId}/users`,
|
|
1775
1777
|
SIGNUP: `${prefix}/signup`,
|
|
1776
|
-
LOG: `${prefix}/
|
|
1778
|
+
LOG: `${prefix}/_log`
|
|
1777
1779
|
});
|
|
1778
1780
|
|
|
1779
1781
|
// src/utils/Requester/index.ts
|
|
@@ -1783,9 +1785,9 @@ var Requester = class extends Config {
|
|
|
1783
1785
|
}
|
|
1784
1786
|
async rawRequest(method, url, init, body) {
|
|
1785
1787
|
const _init = {
|
|
1786
|
-
...init,
|
|
1787
1788
|
body,
|
|
1788
|
-
method
|
|
1789
|
+
method,
|
|
1790
|
+
...init
|
|
1789
1791
|
};
|
|
1790
1792
|
const res = await _fetch(this, url, _init);
|
|
1791
1793
|
if (res instanceof ResponseError) {
|
|
@@ -1986,6 +1988,8 @@ var Auth = class extends Config {
|
|
|
1986
1988
|
}
|
|
1987
1989
|
handleHeaders(init) {
|
|
1988
1990
|
if (this.headers) {
|
|
1991
|
+
const cburl = getCallbackUrl2(this.headers);
|
|
1992
|
+
this.headers.set(X_NILE_ORIGIN, new URL(cburl).origin);
|
|
1989
1993
|
if (init) {
|
|
1990
1994
|
init.headers = new Headers({ ...this.headers, ...init?.headers });
|
|
1991
1995
|
return init;
|
|
@@ -2010,7 +2014,57 @@ var Auth = class extends Config {
|
|
|
2010
2014
|
}
|
|
2011
2015
|
return session;
|
|
2012
2016
|
};
|
|
2017
|
+
get getCsrfUrl() {
|
|
2018
|
+
return "/auth/csrf";
|
|
2019
|
+
}
|
|
2020
|
+
async getCsrf(req, init) {
|
|
2021
|
+
const _requester = new Requester(this);
|
|
2022
|
+
const _init = this.handleHeaders(init);
|
|
2023
|
+
return await _requester.get(req, this.getCsrfUrl, _init);
|
|
2024
|
+
}
|
|
2025
|
+
get listProvidersUrl() {
|
|
2026
|
+
return "/auth/providers";
|
|
2027
|
+
}
|
|
2028
|
+
listProviders = async (req, init) => {
|
|
2029
|
+
const _requester = new Requester(this);
|
|
2030
|
+
const _init = this.handleHeaders(init);
|
|
2031
|
+
return await _requester.get(req, this.listProvidersUrl, _init);
|
|
2032
|
+
};
|
|
2033
|
+
get signOutUrl() {
|
|
2034
|
+
return "/auth/signout";
|
|
2035
|
+
}
|
|
2036
|
+
signOut = async (req, init) => {
|
|
2037
|
+
const _requester = new Requester(this);
|
|
2038
|
+
const _init = this.handleHeaders(init);
|
|
2039
|
+
const csrf = await this.getCsrf(req);
|
|
2040
|
+
const callbackUrl = req && "callbackUrl" in req ? String(req.callbackUrl) : "/";
|
|
2041
|
+
if (csrf instanceof Request) {
|
|
2042
|
+
return csrf;
|
|
2043
|
+
}
|
|
2044
|
+
const csrfToken = "csrfToken" in csrf ? String(csrf.csrfToken) : "";
|
|
2045
|
+
if (!csrfToken) {
|
|
2046
|
+
return new Response("Request blocked", { status: 400 });
|
|
2047
|
+
}
|
|
2048
|
+
return await _requester.post(req, this.signOutUrl, {
|
|
2049
|
+
method: "post",
|
|
2050
|
+
body: JSON.stringify({
|
|
2051
|
+
csrfToken,
|
|
2052
|
+
callbackUrl,
|
|
2053
|
+
json: String(true)
|
|
2054
|
+
}),
|
|
2055
|
+
..._init
|
|
2056
|
+
});
|
|
2057
|
+
};
|
|
2013
2058
|
};
|
|
2059
|
+
function getCallbackUrl2(headers) {
|
|
2060
|
+
if (headers) {
|
|
2061
|
+
const cookieHeader = headers.get("cookie") || "";
|
|
2062
|
+
const cookies = Object.fromEntries(
|
|
2063
|
+
cookieHeader.split("; ").map((cookie) => cookie.split("=").map(decodeURIComponent))
|
|
2064
|
+
);
|
|
2065
|
+
return cookies["__Secure-nile.callback-url"] || cookies["nile.callback-url"];
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2014
2068
|
|
|
2015
2069
|
// src/tenants/index.ts
|
|
2016
2070
|
var Tenants = class extends Config {
|