@forge/sql 0.0.1-experimental-9332276
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 +8 -0
- package/out/__test__/fetch-wrapper.test.d.ts +2 -0
- package/out/__test__/fetch-wrapper.test.d.ts.map +1 -0
- package/out/__test__/fetch-wrapper.test.js +23 -0
- package/out/__test__/sql.test.d.ts +2 -0
- package/out/__test__/sql.test.d.ts.map +1 -0
- package/out/__test__/sql.test.js +58 -0
- package/out/index.d.ts +3 -0
- package/out/index.d.ts.map +1 -0
- package/out/index.js +4 -0
- package/out/sql.d.ts +10 -0
- package/out/sql.d.ts.map +1 -0
- package/out/sql.js +26 -0
- package/out/utils/fetch-wrapper.d.ts +3 -0
- package/out/utils/fetch-wrapper.d.ts.map +1 -0
- package/out/utils/fetch-wrapper.js +25 -0
- package/out/utils/reponse-handler.d.ts +9 -0
- package/out/utils/reponse-handler.d.ts.map +1 -0
- package/out/utils/reponse-handler.js +39 -0
- package/out/utils/types.d.ts +4 -0
- package/out/utils/types.d.ts.map +1 -0
- package/out/utils/types.js +2 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-wrapper.test.d.ts","sourceRoot":"","sources":["../../src/__test__/fetch-wrapper.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
5
|
+
const fetch_wrapper_1 = require("../utils/fetch-wrapper");
|
|
6
|
+
jest.mock('node-fetch');
|
|
7
|
+
const fetchMock = node_fetch_1.default;
|
|
8
|
+
describe('v2', () => {
|
|
9
|
+
it('chooses the v2 fetch based on runtime', async () => {
|
|
10
|
+
const fetch = (0, fetch_wrapper_1.runtimeV2FetchWrapper)();
|
|
11
|
+
fetchMock.mockResolvedValueOnce({
|
|
12
|
+
headers: {
|
|
13
|
+
has: jest.isMockFunction
|
|
14
|
+
},
|
|
15
|
+
ok: true,
|
|
16
|
+
json: async () => ({
|
|
17
|
+
values: []
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
await fetch('asdf');
|
|
21
|
+
expect(fetchMock).toHaveBeenCalled();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.test.d.ts","sourceRoot":"","sources":["../../src/__test__/sql.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
5
|
+
const sql_1 = require("../sql");
|
|
6
|
+
const reponse_handler_1 = require("../utils/reponse-handler");
|
|
7
|
+
jest.mock('node-fetch');
|
|
8
|
+
const fetchMock = node_fetch_1.default;
|
|
9
|
+
describe('sql', () => {
|
|
10
|
+
it('should pass', async () => {
|
|
11
|
+
fetchMock.mockResolvedValueOnce({
|
|
12
|
+
headers: {
|
|
13
|
+
has: jest.isMockFunction
|
|
14
|
+
},
|
|
15
|
+
ok: true,
|
|
16
|
+
text: async () => JSON.stringify({
|
|
17
|
+
values: []
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
await sql_1.sql.execute('asdf');
|
|
21
|
+
expect(fetchMock).toHaveBeenCalled();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('SqlClient', () => {
|
|
25
|
+
function buildSqlClient() {
|
|
26
|
+
const fetch = jest.fn();
|
|
27
|
+
const client = new sql_1.SqlClient(fetch);
|
|
28
|
+
return { client, fetch };
|
|
29
|
+
}
|
|
30
|
+
it('handles success', async () => {
|
|
31
|
+
const { client, fetch } = buildSqlClient();
|
|
32
|
+
fetch.mockResolvedValueOnce({
|
|
33
|
+
ok: true,
|
|
34
|
+
text: async () => JSON.stringify({ response: 'asdfasdf' }),
|
|
35
|
+
status: 200
|
|
36
|
+
});
|
|
37
|
+
const result = await client.execute('SELECT * FROM example');
|
|
38
|
+
expect(result).toEqual('asdfasdf');
|
|
39
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
40
|
+
});
|
|
41
|
+
it('handles success when no value is returned', async () => {
|
|
42
|
+
const { client, fetch } = buildSqlClient();
|
|
43
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
44
|
+
const result = await client.execute(`INSERT INTO x SET y='z'`);
|
|
45
|
+
expect(result).toBeNull();
|
|
46
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
47
|
+
});
|
|
48
|
+
it('handles failure', async () => {
|
|
49
|
+
const { client, fetch } = buildSqlClient();
|
|
50
|
+
fetch.mockResolvedValueOnce({
|
|
51
|
+
ok: false,
|
|
52
|
+
text: async () => JSON.stringify({ error: { code: 'SQL_SYNTAX_ERROR', title: 'SQL syntax error' } }),
|
|
53
|
+
status: 400
|
|
54
|
+
});
|
|
55
|
+
await expect(client.execute('DELECT * from example')).rejects.toThrow(new reponse_handler_1.ApiError(400, 'SQL_SYNTAX_ERROR', 'SQL syntax error'));
|
|
56
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
57
|
+
});
|
|
58
|
+
});
|
package/out/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,eAAe,GAAG,CAAC"}
|
package/out/index.js
ADDED
package/out/sql.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RequestInit } from 'node-fetch';
|
|
2
|
+
import { Result, Response } from './utils/types';
|
|
3
|
+
export declare class SqlClient {
|
|
4
|
+
private client;
|
|
5
|
+
constructor(client: (path: string, options?: RequestInit) => Promise<Response>);
|
|
6
|
+
private buildRequest;
|
|
7
|
+
execute(query: string): Promise<Result>;
|
|
8
|
+
}
|
|
9
|
+
export declare const sql: SqlClient;
|
|
10
|
+
//# sourceMappingURL=sql.d.ts.map
|
package/out/sql.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGjD,qBAAa,SAAS;IACR,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC;IAEtF,OAAO,CAAC,YAAY;IAUP,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAKrD;AAED,eAAO,MAAM,GAAG,WAAyC,CAAC"}
|
package/out/sql.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sql = exports.SqlClient = void 0;
|
|
4
|
+
const fetch_wrapper_1 = require("./utils/fetch-wrapper");
|
|
5
|
+
const reponse_handler_1 = require("./utils/reponse-handler");
|
|
6
|
+
class SqlClient {
|
|
7
|
+
client;
|
|
8
|
+
constructor(client) {
|
|
9
|
+
this.client = client;
|
|
10
|
+
}
|
|
11
|
+
buildRequest(requestBody) {
|
|
12
|
+
return {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
body: JSON.stringify(requestBody),
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json'
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async execute(query) {
|
|
21
|
+
const response = await this.client('sql/execute', this.buildRequest({ query }));
|
|
22
|
+
return await (0, reponse_handler_1.getResponseBody)(response);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.SqlClient = SqlClient;
|
|
26
|
+
exports.sql = new SqlClient((0, fetch_wrapper_1.runtimeV2FetchWrapper)());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-wrapper.d.ts","sourceRoot":"","sources":["../../src/utils/fetch-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAqB,MAAM,YAAY,CAAC;AAI5D,wBAAgB,qBAAqB,IAAI,WAAW,CAoBnD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runtimeV2FetchWrapper = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const api_1 = require("@forge/api");
|
|
6
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
7
|
+
const fetch_1 = require("@forge/api/out/api/fetch");
|
|
8
|
+
function runtimeV2FetchWrapper() {
|
|
9
|
+
return async (path, init) => {
|
|
10
|
+
const url = `https://sql/${path}`;
|
|
11
|
+
init = (0, fetch_1.addMagicAgent)(init);
|
|
12
|
+
init.redirect = 'follow';
|
|
13
|
+
init.headers = {
|
|
14
|
+
...init.headers,
|
|
15
|
+
redirect: 'follow',
|
|
16
|
+
'Content-Type': 'application/json'
|
|
17
|
+
};
|
|
18
|
+
const response = await (0, node_fetch_1.default)(url, init);
|
|
19
|
+
if (response.headers.has('forge-proxy-error')) {
|
|
20
|
+
throw new api_1.ProxyRequestError(response.status, response.headers.get('forge-proxy-error'));
|
|
21
|
+
}
|
|
22
|
+
return response;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
exports.runtimeV2FetchWrapper = runtimeV2FetchWrapper;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Response } from './types';
|
|
2
|
+
export declare class ApiError extends Error {
|
|
3
|
+
readonly status: number;
|
|
4
|
+
readonly code: string;
|
|
5
|
+
readonly data?: any;
|
|
6
|
+
constructor(status: number, code: string, message: string, data?: any);
|
|
7
|
+
}
|
|
8
|
+
export declare function getResponseBody(response: Response): Promise<any>;
|
|
9
|
+
//# sourceMappingURL=reponse-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reponse-handler.d.ts","sourceRoot":"","sources":["../../src/utils/reponse-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,qBAAa,QAAS,SAAQ,KAAK;IAE/B,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,IAAI,CAAC;gBAHL,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,IAAI,CAAC,KAAK;CAItB;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CA0BtE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getResponseBody = exports.ApiError = void 0;
|
|
4
|
+
class ApiError extends Error {
|
|
5
|
+
status;
|
|
6
|
+
code;
|
|
7
|
+
data;
|
|
8
|
+
constructor(status, code, message, data) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.data = data;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.ApiError = ApiError;
|
|
16
|
+
async function getResponseBody(response) {
|
|
17
|
+
const responseText = await response.text();
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
try {
|
|
20
|
+
const parsedError = JSON.parse(responseText);
|
|
21
|
+
throw new ApiError(response.status, parsedError?.error?.code, parsedError?.error?.title, parsedError?.error?.data);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
if (!(e instanceof ApiError)) {
|
|
25
|
+
throw new ApiError(response.status, 'UNKNOWN_ERROR', `${responseText}`);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(responseText).response;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new Error(`Unexpected error. Response was not valid JSON: ${responseText}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.getResponseBody = getResponseBody;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC3D,oBAAY,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC;AAEzE,oBAAY,MAAM,GAAG,GAAG,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@forge/sql",
|
|
3
|
+
"version": "0.0.1-experimental-9332276",
|
|
4
|
+
"description": "Forge SQL package",
|
|
5
|
+
"author": "Atlassian",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"main": "out/index.js",
|
|
8
|
+
"types": "out/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"out"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "yarn run clean && yarn run compile",
|
|
14
|
+
"clean": "rm -rf ./out && rm -f tsconfig.tsbuildinfo",
|
|
15
|
+
"compile": "tsc -b -v"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "14.18.63",
|
|
19
|
+
"@types/node-fetch": "^2.6.11",
|
|
20
|
+
"expect-type": "^0.17.3",
|
|
21
|
+
"node-fetch": "2.7.0"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@forge/api": "^3.9.0"
|
|
25
|
+
}
|
|
26
|
+
}
|