Skip to content

Commit c98aaec

Browse files
committed
feat(sdk): add cloud sdk package
1 parent 145268e commit c98aaec

10 files changed

+3458
-0
lines changed

packages/cloud-sdk/.npmignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
./node_modules
2+
.DS_Store
3+
src
4+
tests

packages/cloud-sdk/.prettierrc

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

packages/cloud-sdk/README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
3+
> cloud-sdk is used in cloud function, exposing resource objects to cloud function.
4+
5+
```ts
6+
import cloud from '@lafjs/cloud-sdk'
7+
8+
exports.main = async function (ctx) {
9+
10+
const db = cloud.database()
11+
const res = await db.collection('admins').get()
12+
13+
return res.data
14+
}
15+
```

packages/cloud-sdk/package-lock.json

+3,078
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cloud-sdk/package.json

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "@lafjs/cloud",
3+
"version": "0.0.1",
4+
"description": "The cloud sdk for laf cloud function",
5+
"main": "dist/index.js",
6+
"scripts": {
7+
"watch": "tsc -w",
8+
"test": "echo \"Error: no test specified\" && exit 1",
9+
"eslint": "eslint \"./**/*.ts\"",
10+
"fix": "eslint --fix \"./**/*.ts\"",
11+
"build": "tsc -p tsconfig.json",
12+
"prepublishOnly": "npm run build"
13+
},
14+
"repository": {
15+
"type": "git",
16+
"url": "git+https://github.com/labring/laf.git"
17+
},
18+
"bugs": {
19+
"url": "https://github.com/labring/laf/issues"
20+
},
21+
"homepage": "https://github.com/labring/laf#readme",
22+
"keywords": [
23+
"laf"
24+
],
25+
"author": "maslow ([email protected])",
26+
"license": "ISC",
27+
"devDependencies": {
28+
"typescript": "^4.9.4"
29+
},
30+
"dependencies": {
31+
"@types/express": "^4.17.15",
32+
"@types/ws": "^8.5.3",
33+
"axios": "^1.2.1",
34+
"database-proxy": "^0.8.2",
35+
"mongodb": "^4.12.1",
36+
"ws": "^8.11.0"
37+
}
38+
}
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { AxiosStatic } from 'axios'
2+
import * as mongodb from 'mongodb'
3+
import { Db } from 'database-proxy'
4+
import { WebSocket } from 'ws'
5+
import { FunctionContext } from './function.interface'
6+
7+
8+
9+
export type InvokeFunctionType = (
10+
name: string,
11+
param: FunctionContext,
12+
) => Promise<any>
13+
export type GetTokenFunctionType = (payload: any, secret?: string) => string
14+
export type ParseTokenFunctionType = (
15+
token: string,
16+
secret?: string,
17+
) => any | null
18+
19+
export interface MongoDriverObject {
20+
client: mongodb.MongoClient
21+
db: mongodb.Db
22+
}
23+
24+
export interface CloudSdkInterface {
25+
/**
26+
* Sending an HTTP request is actually an Axios instance. You can refer to the Axios documentation directly
27+
*/
28+
fetch: AxiosStatic
29+
30+
/**
31+
* Get a database-ql instance
32+
*/
33+
database(): Db
34+
35+
/**
36+
* Invoke cloud function
37+
*/
38+
invoke: InvokeFunctionType
39+
40+
/**
41+
* Cloud function global memory `shared` object, which can share data across multiple requests and different cloud functions
42+
* 1. Some global configurations can be initialized into `shared`, such as 3rd-party API configuration
43+
* 2. You can share some common methods, such as checkPermission(), to improve the performance of cloud functions
44+
* 3. It can cache hot data and is recommended to use it in a small amount (this object is allocated in the node VM heap because of the memory limit of the node VM heap)
45+
*/
46+
shared: Map<string, any>
47+
48+
/**
49+
* Generate a JWT Token, if don't provide `secret` fields, use current server secret key to do signature
50+
*/
51+
getToken: GetTokenFunctionType
52+
53+
/**
54+
* Parse a JWT Token, if don't provide `secret` fields, use current server secret key to verify signature
55+
*/
56+
parseToken: ParseTokenFunctionType
57+
58+
/**
59+
* The mongodb instance of MongoDB node.js native driver.
60+
*
61+
* Because the laf.js database-QL has only partial data manipulation capability,
62+
* expose this `mongo` object to the cloud function, so that the cloud function has full database manipulation capability:
63+
* 1. Transaction operations
64+
* ```js
65+
* const session = mongo.client.startSession()
66+
* try {
67+
* await session.withTransaction(async () => {
68+
* await mongo.db.collection('xxx').updateOne({}, { session })
69+
* await mongo.db.collection('yyy').deleteMany({}, { session })
70+
* })
71+
* } finally {
72+
* await session.endSession()
73+
* }
74+
* ```
75+
* 2. Indexes operations
76+
* ```js
77+
* await mongo.db.collection('users').createIndex('username', { unique: true })
78+
* ```
79+
* 3. Aggregation operations
80+
* ```js
81+
* await mongo.db.collection('users')
82+
* .aggregate([])
83+
* .toArray()
84+
* ```
85+
*/
86+
mongo: MongoDriverObject
87+
88+
/**
89+
* Websocket connection list
90+
*/
91+
sockets: Set<WebSocket>
92+
93+
/**
94+
* Current app id
95+
*/
96+
appid: string
97+
98+
env: {
99+
DB_URI?: string
100+
SERVER_SECRET?: string
101+
APP_ID?: string
102+
OSS_ACCESS_KEY?: string
103+
OSS_ACCESS_SECRET?: string
104+
OSS_REGION?: string
105+
OSS_INTERNAL_ENDPOINT?: string
106+
OSS_EXTERNAL_ENDPOINT?: string
107+
NPM_INSTALL_FLAGS?: string
108+
RUNTIME_IMAGE?: string
109+
}
110+
}

packages/cloud-sdk/src/cloud.ts

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Db } from "database-proxy";
2+
import request, { AxiosStatic } from "axios";
3+
import {
4+
CloudSdkInterface,
5+
GetTokenFunctionType,
6+
InvokeFunctionType,
7+
MongoDriverObject,
8+
ParseTokenFunctionType,
9+
} from "./cloud.interface";
10+
import { WebSocket } from "ws";
11+
12+
export default class Cloud implements CloudSdkInterface {
13+
/**
14+
* This method should be overwrite
15+
* @returns
16+
*/
17+
static create: () => CloudSdkInterface;
18+
19+
private _cloud: CloudSdkInterface;
20+
21+
private get cloud(): CloudSdkInterface {
22+
if (!this._cloud) {
23+
this._cloud = Cloud.create();
24+
}
25+
return this._cloud;
26+
}
27+
28+
fetch: AxiosStatic = request;
29+
30+
database(): Db {
31+
return this.cloud.database();
32+
}
33+
34+
invoke: InvokeFunctionType = (name: string, param: any) => {
35+
return this.cloud.invoke(name, param);
36+
};
37+
38+
getToken: GetTokenFunctionType = (param: any) => {
39+
return this.cloud.getToken(param);
40+
};
41+
42+
parseToken: ParseTokenFunctionType = (token: string) => {
43+
return this.cloud.parseToken(token);
44+
};
45+
46+
get shared(): Map<string, any> {
47+
return this.cloud.shared;
48+
}
49+
50+
get mongo(): MongoDriverObject {
51+
return this.cloud.mongo;
52+
}
53+
54+
get sockets(): Set<WebSocket> {
55+
return this.cloud.sockets;
56+
}
57+
58+
get appid(): string {
59+
return this.cloud.appid;
60+
}
61+
62+
get env() {
63+
return this.cloud.env;
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { IncomingHttpHeaders } from 'http'
2+
import { Request, Response } from 'express'
3+
import WebSocket = require('ws')
4+
5+
export type RequireFuncType = (module: string) => any
6+
7+
/**
8+
* ctx passed to function
9+
*/
10+
export interface FunctionContext {
11+
files?: File[]
12+
headers?: IncomingHttpHeaders
13+
query?: any
14+
body?: any
15+
params?: any
16+
/**
17+
* @deprecated use user instead
18+
*/
19+
auth?: any
20+
user?: any
21+
requestId: string
22+
method?: string
23+
socket?: WebSocket
24+
request?: Request
25+
response?: Response
26+
__function_name: string
27+
}
28+
29+
/**
30+
* Result object returned by the running function
31+
*/
32+
export interface FunctionResult {
33+
data?: any
34+
error?: Error
35+
time_usage: number
36+
}
37+
38+
export enum FunctionStatus {
39+
DISABLED = 0,
40+
ENABLED = 1,
41+
}
42+
43+
/**
44+
* Model CloudFunctionSource
45+
*
46+
*/
47+
export type CloudFunctionSource = {
48+
code: string
49+
compiled: string | null
50+
uri: string | null
51+
version: number
52+
hash: string | null
53+
lang: string | null
54+
}
55+
56+
/**
57+
* cloud function data structure
58+
*/
59+
export interface ICloudFunctionData {
60+
id: string
61+
appid: string
62+
name: string
63+
source: CloudFunctionSource
64+
desc: string
65+
tags: string[]
66+
websocket: boolean
67+
methods: string[]
68+
createdAt: Date
69+
updatedAt: Date
70+
createdBy: string
71+
}
72+
73+
/** Object containing file metadata and access information. */
74+
interface File {
75+
/** Name of the form field associated with this file. */
76+
fieldname: string
77+
/** Name of the file on the uploader's computer. */
78+
originalname: string
79+
/**
80+
* Value of the `Content-Transfer-Encoding` header for this file.
81+
* @deprecated since July 2015
82+
* @see RFC 7578, Section 4.7
83+
*/
84+
encoding: string
85+
/** Value of the `Content-Type` header for this file. */
86+
mimetype: string
87+
/** Size of the file in bytes. */
88+
size: number
89+
/** `DiskStorage` only: Directory to which this file has been uploaded. */
90+
destination: string
91+
/** `DiskStorage` only: Name of this file within `destination`. */
92+
filename: string
93+
/** `DiskStorage` only: Full path to the uploaded file. */
94+
path: string
95+
}

packages/cloud-sdk/src/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Cloud from './cloud'
2+
3+
export * from './cloud.interface'
4+
export * from './function.interface'
5+
export * from './cloud'
6+
7+
const cloud = new Cloud()
8+
9+
export default cloud

packages/cloud-sdk/tsconfig.json

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"compileOnSave": true,
3+
"compilerOptions": {
4+
"allowJs": false,
5+
"allowUnreachableCode": false,
6+
"allowUnusedLabels": false,
7+
"charset": "utf8",
8+
"declaration": true,
9+
"experimentalDecorators": true,
10+
"emitDecoratorMetadata": true,
11+
"importHelpers": false,
12+
"module": "commonjs",
13+
"declarationMap": true,
14+
// "declarationDir": "types",
15+
"noEmitOnError": false,
16+
"noFallthroughCasesInSwitch": true,
17+
"noImplicitAny": false,
18+
"noUnusedLocals": true,
19+
"noUnusedParameters": true,
20+
"outDir": "dist",
21+
"pretty": true,
22+
"removeComments": false,
23+
"stripInternal": true,
24+
"skipDefaultLibCheck": true,
25+
"skipLibCheck": true,
26+
"target": "es2017",
27+
"alwaysStrict": true,
28+
"lib": [
29+
"es2015",
30+
"es6"
31+
]
32+
},
33+
"include": [
34+
"src/**/*",
35+
],
36+
"exclude": [
37+
"tests",
38+
]
39+
}

0 commit comments

Comments
 (0)