@tinacms/datalayer 1.2.28 → 1.2.30
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/dist/backend/index.d.ts +46 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +129 -0
- package/dist/index.mjs +127 -2
- package/package.json +14 -6
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
declare type DatabaseClient = any;
|
|
4
|
+
export interface BackendAuthProvider {
|
|
5
|
+
initialize?: () => Promise<void>;
|
|
6
|
+
isAuthorized: (req: IncomingMessage, res: ServerResponse) => Promise<{
|
|
7
|
+
isAuthorized: true;
|
|
8
|
+
} | {
|
|
9
|
+
isAuthorized: false;
|
|
10
|
+
errorMessage: string;
|
|
11
|
+
errorCode: number;
|
|
12
|
+
}>;
|
|
13
|
+
extraRoutes?: {
|
|
14
|
+
[key: string]: {
|
|
15
|
+
secure?: boolean;
|
|
16
|
+
handler: NodeRouteHandler;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare const LocalBackendAuthProvider: () => BackendAuthProvider;
|
|
21
|
+
export interface TinaBackendOptions {
|
|
22
|
+
/**
|
|
23
|
+
* The database client to use. Imported from tina/__generated__/databaseClient
|
|
24
|
+
*/
|
|
25
|
+
databaseClient: DatabaseClient;
|
|
26
|
+
/**
|
|
27
|
+
* The auth provider to use
|
|
28
|
+
*/
|
|
29
|
+
authProvider: BackendAuthProvider;
|
|
30
|
+
/**
|
|
31
|
+
* Options to configure the backend
|
|
32
|
+
*/
|
|
33
|
+
options?: {
|
|
34
|
+
/**
|
|
35
|
+
* The base path for the api routes (defaults to /api/tina)
|
|
36
|
+
*
|
|
37
|
+
* @default /api/tina
|
|
38
|
+
*/
|
|
39
|
+
basePath?: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export declare type NodeApiHandler = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
43
|
+
declare type NodeRouteHandlerOptions = Required<TinaBackendOptions['options']>;
|
|
44
|
+
declare type NodeRouteHandler = (req: IncomingMessage, res: ServerResponse, opts: NodeRouteHandlerOptions) => Promise<void>;
|
|
45
|
+
export declare function TinaNodeBackend({ authProvider, databaseClient, options, }: TinaBackendOptions): NodeApiHandler;
|
|
46
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export type { Bridge,
|
|
2
|
-
export { FilesystemBridge, AuditFileSystemBridge, IsomorphicBridge,
|
|
1
|
+
export type { Bridge, OnPutCallback, OnDeleteCallback, Database, GitProvider, } from '@tinacms/graphql';
|
|
2
|
+
export { FilesystemBridge, AuditFileSystemBridge, IsomorphicBridge, TinaLevelClient, resolve, createDatabase, createLocalDatabase, } from '@tinacms/graphql';
|
|
3
|
+
export * from './backend';
|
package/dist/index.js
CHANGED
|
@@ -22,18 +22,147 @@ __export(src_exports, {
|
|
|
22
22
|
AuditFileSystemBridge: () => import_graphql.AuditFileSystemBridge,
|
|
23
23
|
FilesystemBridge: () => import_graphql.FilesystemBridge,
|
|
24
24
|
IsomorphicBridge: () => import_graphql.IsomorphicBridge,
|
|
25
|
+
LocalBackendAuthProvider: () => LocalBackendAuthProvider,
|
|
25
26
|
TinaLevelClient: () => import_graphql.TinaLevelClient,
|
|
27
|
+
TinaNodeBackend: () => TinaNodeBackend,
|
|
26
28
|
createDatabase: () => import_graphql.createDatabase,
|
|
29
|
+
createLocalDatabase: () => import_graphql.createLocalDatabase,
|
|
27
30
|
resolve: () => import_graphql.resolve
|
|
28
31
|
});
|
|
29
32
|
module.exports = __toCommonJS(src_exports);
|
|
30
33
|
var import_graphql = require("@tinacms/graphql");
|
|
34
|
+
|
|
35
|
+
// src/backend/index.ts
|
|
36
|
+
var LocalBackendAuthProvider = () => ({
|
|
37
|
+
isAuthorized: async () => ({ isAuthorized: true })
|
|
38
|
+
});
|
|
39
|
+
function TinaNodeBackend({
|
|
40
|
+
authProvider,
|
|
41
|
+
databaseClient,
|
|
42
|
+
options
|
|
43
|
+
}) {
|
|
44
|
+
const { initialize, isAuthorized, extraRoutes } = authProvider;
|
|
45
|
+
initialize == null ? void 0 : initialize().catch((e) => {
|
|
46
|
+
console.error(e);
|
|
47
|
+
});
|
|
48
|
+
const basePath = (options == null ? void 0 : options.basePath) ? `/${options.basePath.replace(/^\/?/, "").replace(/\/?$/, "")}/` : "/api/tina/";
|
|
49
|
+
const opts = {
|
|
50
|
+
basePath
|
|
51
|
+
};
|
|
52
|
+
const handler = MakeNodeApiHandler({
|
|
53
|
+
isAuthorized,
|
|
54
|
+
extraRoutes,
|
|
55
|
+
databaseClient,
|
|
56
|
+
opts
|
|
57
|
+
});
|
|
58
|
+
return handler;
|
|
59
|
+
}
|
|
60
|
+
function MakeNodeApiHandler({
|
|
61
|
+
isAuthorized,
|
|
62
|
+
extraRoutes,
|
|
63
|
+
databaseClient,
|
|
64
|
+
opts
|
|
65
|
+
}) {
|
|
66
|
+
const tinaBackendHandler = async (req, res) => {
|
|
67
|
+
var _a, _b, _c, _d;
|
|
68
|
+
const path = ((_a = req.url) == null ? void 0 : _a.startsWith("/")) ? req.url.slice(1) : req.url;
|
|
69
|
+
const url = new URL(path, `http://${((_b = req.headers) == null ? void 0 : _b.host) || "localhost"}`);
|
|
70
|
+
const routes = (_d = (_c = url.pathname) == null ? void 0 : _c.replace(opts.basePath, "")) == null ? void 0 : _d.split("/");
|
|
71
|
+
if (typeof routes === "string") {
|
|
72
|
+
throw new Error("Please name your next api route [...routes] not [route]");
|
|
73
|
+
}
|
|
74
|
+
if (!(routes == null ? void 0 : routes.length)) {
|
|
75
|
+
console.error(
|
|
76
|
+
`A request was made to ${opts.basePath} but no route was found`
|
|
77
|
+
);
|
|
78
|
+
res.statusCode = 404;
|
|
79
|
+
res.write(JSON.stringify({ error: "not found" }));
|
|
80
|
+
res.end();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const allRoutes = {
|
|
84
|
+
gql: {
|
|
85
|
+
handler: async (req2, res2, _opts) => {
|
|
86
|
+
var _a2;
|
|
87
|
+
if (req2.method !== "POST") {
|
|
88
|
+
res2.statusCode = 405;
|
|
89
|
+
res2.write(
|
|
90
|
+
JSON.stringify({
|
|
91
|
+
error: "Method not allowed. Only POST requests are supported by /gql"
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
res2.end();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (!req2.body) {
|
|
98
|
+
console.error(
|
|
99
|
+
"Please make sure that you have a body parser set up for your server and req.body is defined"
|
|
100
|
+
);
|
|
101
|
+
res2.statusCode = 400;
|
|
102
|
+
res2.write(JSON.stringify({ error: "no body" }));
|
|
103
|
+
res2.end();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!req2.body.query) {
|
|
107
|
+
res2.statusCode = 400;
|
|
108
|
+
res2.write(JSON.stringify({ error: "no query" }));
|
|
109
|
+
res2.end();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!req2.body.variables) {
|
|
113
|
+
res2.statusCode = 400;
|
|
114
|
+
res2.write(JSON.stringify({ error: "no variables" }));
|
|
115
|
+
res2.end();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const { query, variables } = req2.body;
|
|
119
|
+
const result = await databaseClient.request({
|
|
120
|
+
query,
|
|
121
|
+
variables,
|
|
122
|
+
user: (_a2 = req2 == null ? void 0 : req2.session) == null ? void 0 : _a2.user
|
|
123
|
+
});
|
|
124
|
+
res2.statusCode = 200;
|
|
125
|
+
res2.write(JSON.stringify(result));
|
|
126
|
+
res2.end();
|
|
127
|
+
return;
|
|
128
|
+
},
|
|
129
|
+
secure: true
|
|
130
|
+
},
|
|
131
|
+
...extraRoutes || {}
|
|
132
|
+
};
|
|
133
|
+
const [action] = routes;
|
|
134
|
+
const currentRoute = allRoutes[action];
|
|
135
|
+
if (!currentRoute) {
|
|
136
|
+
res.statusCode = 404;
|
|
137
|
+
const errorMessage = `Error: ${action} not found in routes`;
|
|
138
|
+
console.error(errorMessage);
|
|
139
|
+
res.write(JSON.stringify({ error: errorMessage }));
|
|
140
|
+
res.end();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const { handler, secure } = currentRoute;
|
|
144
|
+
if (secure) {
|
|
145
|
+
const isAuth = await isAuthorized(req, res);
|
|
146
|
+
if (isAuth.isAuthorized === false) {
|
|
147
|
+
res.statusCode = isAuth.errorCode;
|
|
148
|
+
res.write(JSON.stringify({ error: isAuth.errorMessage || "not found" }));
|
|
149
|
+
res.end();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return handler(req, res, opts);
|
|
154
|
+
};
|
|
155
|
+
return tinaBackendHandler;
|
|
156
|
+
}
|
|
31
157
|
// Annotate the CommonJS export names for ESM import in node:
|
|
32
158
|
0 && (module.exports = {
|
|
33
159
|
AuditFileSystemBridge,
|
|
34
160
|
FilesystemBridge,
|
|
35
161
|
IsomorphicBridge,
|
|
162
|
+
LocalBackendAuthProvider,
|
|
36
163
|
TinaLevelClient,
|
|
164
|
+
TinaNodeBackend,
|
|
37
165
|
createDatabase,
|
|
166
|
+
createLocalDatabase,
|
|
38
167
|
resolve
|
|
39
168
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -3,15 +3,140 @@ import {
|
|
|
3
3
|
FilesystemBridge,
|
|
4
4
|
AuditFileSystemBridge,
|
|
5
5
|
IsomorphicBridge,
|
|
6
|
-
createDatabase,
|
|
7
6
|
TinaLevelClient,
|
|
8
|
-
resolve
|
|
7
|
+
resolve,
|
|
8
|
+
createDatabase,
|
|
9
|
+
createLocalDatabase
|
|
9
10
|
} from "@tinacms/graphql";
|
|
11
|
+
|
|
12
|
+
// src/backend/index.ts
|
|
13
|
+
var LocalBackendAuthProvider = () => ({
|
|
14
|
+
isAuthorized: async () => ({ isAuthorized: true })
|
|
15
|
+
});
|
|
16
|
+
function TinaNodeBackend({
|
|
17
|
+
authProvider,
|
|
18
|
+
databaseClient,
|
|
19
|
+
options
|
|
20
|
+
}) {
|
|
21
|
+
const { initialize, isAuthorized, extraRoutes } = authProvider;
|
|
22
|
+
initialize?.().catch((e) => {
|
|
23
|
+
console.error(e);
|
|
24
|
+
});
|
|
25
|
+
const basePath = options?.basePath ? `/${options.basePath.replace(/^\/?/, "").replace(/\/?$/, "")}/` : "/api/tina/";
|
|
26
|
+
const opts = {
|
|
27
|
+
basePath
|
|
28
|
+
};
|
|
29
|
+
const handler = MakeNodeApiHandler({
|
|
30
|
+
isAuthorized,
|
|
31
|
+
extraRoutes,
|
|
32
|
+
databaseClient,
|
|
33
|
+
opts
|
|
34
|
+
});
|
|
35
|
+
return handler;
|
|
36
|
+
}
|
|
37
|
+
function MakeNodeApiHandler({
|
|
38
|
+
isAuthorized,
|
|
39
|
+
extraRoutes,
|
|
40
|
+
databaseClient,
|
|
41
|
+
opts
|
|
42
|
+
}) {
|
|
43
|
+
const tinaBackendHandler = async (req, res) => {
|
|
44
|
+
const path = req.url?.startsWith("/") ? req.url.slice(1) : req.url;
|
|
45
|
+
const url = new URL(path, `http://${req.headers?.host || "localhost"}`);
|
|
46
|
+
const routes = url.pathname?.replace(opts.basePath, "")?.split("/");
|
|
47
|
+
if (typeof routes === "string") {
|
|
48
|
+
throw new Error("Please name your next api route [...routes] not [route]");
|
|
49
|
+
}
|
|
50
|
+
if (!routes?.length) {
|
|
51
|
+
console.error(
|
|
52
|
+
`A request was made to ${opts.basePath} but no route was found`
|
|
53
|
+
);
|
|
54
|
+
res.statusCode = 404;
|
|
55
|
+
res.write(JSON.stringify({ error: "not found" }));
|
|
56
|
+
res.end();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const allRoutes = {
|
|
60
|
+
gql: {
|
|
61
|
+
handler: async (req2, res2, _opts) => {
|
|
62
|
+
if (req2.method !== "POST") {
|
|
63
|
+
res2.statusCode = 405;
|
|
64
|
+
res2.write(
|
|
65
|
+
JSON.stringify({
|
|
66
|
+
error: "Method not allowed. Only POST requests are supported by /gql"
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
res2.end();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!req2.body) {
|
|
73
|
+
console.error(
|
|
74
|
+
"Please make sure that you have a body parser set up for your server and req.body is defined"
|
|
75
|
+
);
|
|
76
|
+
res2.statusCode = 400;
|
|
77
|
+
res2.write(JSON.stringify({ error: "no body" }));
|
|
78
|
+
res2.end();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!req2.body.query) {
|
|
82
|
+
res2.statusCode = 400;
|
|
83
|
+
res2.write(JSON.stringify({ error: "no query" }));
|
|
84
|
+
res2.end();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!req2.body.variables) {
|
|
88
|
+
res2.statusCode = 400;
|
|
89
|
+
res2.write(JSON.stringify({ error: "no variables" }));
|
|
90
|
+
res2.end();
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const { query, variables } = req2.body;
|
|
94
|
+
const result = await databaseClient.request({
|
|
95
|
+
query,
|
|
96
|
+
variables,
|
|
97
|
+
user: req2?.session?.user
|
|
98
|
+
});
|
|
99
|
+
res2.statusCode = 200;
|
|
100
|
+
res2.write(JSON.stringify(result));
|
|
101
|
+
res2.end();
|
|
102
|
+
return;
|
|
103
|
+
},
|
|
104
|
+
secure: true
|
|
105
|
+
},
|
|
106
|
+
...extraRoutes || {}
|
|
107
|
+
};
|
|
108
|
+
const [action] = routes;
|
|
109
|
+
const currentRoute = allRoutes[action];
|
|
110
|
+
if (!currentRoute) {
|
|
111
|
+
res.statusCode = 404;
|
|
112
|
+
const errorMessage = `Error: ${action} not found in routes`;
|
|
113
|
+
console.error(errorMessage);
|
|
114
|
+
res.write(JSON.stringify({ error: errorMessage }));
|
|
115
|
+
res.end();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const { handler, secure } = currentRoute;
|
|
119
|
+
if (secure) {
|
|
120
|
+
const isAuth = await isAuthorized(req, res);
|
|
121
|
+
if (isAuth.isAuthorized === false) {
|
|
122
|
+
res.statusCode = isAuth.errorCode;
|
|
123
|
+
res.write(JSON.stringify({ error: isAuth.errorMessage || "not found" }));
|
|
124
|
+
res.end();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return handler(req, res, opts);
|
|
129
|
+
};
|
|
130
|
+
return tinaBackendHandler;
|
|
131
|
+
}
|
|
10
132
|
export {
|
|
11
133
|
AuditFileSystemBridge,
|
|
12
134
|
FilesystemBridge,
|
|
13
135
|
IsomorphicBridge,
|
|
136
|
+
LocalBackendAuthProvider,
|
|
14
137
|
TinaLevelClient,
|
|
138
|
+
TinaNodeBackend,
|
|
15
139
|
createDatabase,
|
|
140
|
+
createLocalDatabase,
|
|
16
141
|
resolve
|
|
17
142
|
};
|
package/package.json
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/datalayer",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.30",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
|
-
"typings": "dist/index
|
|
6
|
+
"typings": "dist/index",
|
|
7
7
|
"files": [
|
|
8
8
|
"package.json",
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"exports": {
|
|
12
|
-
"
|
|
13
|
-
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./dist/*": {
|
|
18
|
+
"import": "./dist/*.mjs",
|
|
19
|
+
"require": "./dist/*.js",
|
|
20
|
+
"types": "./dist/*.d.ts"
|
|
21
|
+
}
|
|
14
22
|
},
|
|
15
23
|
"license": "SEE LICENSE IN LICENSE",
|
|
16
24
|
"buildConfig": {
|
|
@@ -23,7 +31,7 @@
|
|
|
23
31
|
]
|
|
24
32
|
},
|
|
25
33
|
"dependencies": {
|
|
26
|
-
"@tinacms/graphql": "1.4.
|
|
34
|
+
"@tinacms/graphql": "1.4.30"
|
|
27
35
|
},
|
|
28
36
|
"publishConfig": {
|
|
29
37
|
"registry": "https://registry.npmjs.org"
|
|
@@ -33,7 +41,7 @@
|
|
|
33
41
|
"directory": "packages/@tinacms/datalayer"
|
|
34
42
|
},
|
|
35
43
|
"devDependencies": {
|
|
36
|
-
"@tinacms/scripts": "1.1.
|
|
44
|
+
"@tinacms/scripts": "1.1.3",
|
|
37
45
|
"@types/fs-extra": "^9.0.2",
|
|
38
46
|
"@types/jest": "^27.4.1",
|
|
39
47
|
"@types/js-yaml": "^3.12.5",
|