@qmuse/appwrite-runtime-sdk 1.0.1 → 1.0.3-dev.1
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 +15 -0
- package/dist/index.d.ts +1 -1
- package/dist/runtime/AppwriteSessionCoordinator.d.ts +29 -0
- package/dist/runtime/AppwriteSessionCoordinator.js +647 -0
- package/dist/runtime/MutationAuditReporter.d.ts +18 -0
- package/dist/runtime/MutationAuditReporter.js +110 -0
- package/dist/runtime/QmuseAppwriteRuntime.d.ts +22 -0
- package/dist/runtime/QmuseAppwriteRuntime.js +321 -0
- package/dist/runtime/rowData.d.ts +3 -0
- package/dist/runtime/rowData.js +60 -0
- package/dist/runtime/utils.d.ts +11 -0
- package/dist/runtime/utils.js +68 -0
- package/dist/runtime.d.ts +2 -31
- package/dist/runtime.js +2 -937
- package/dist/types.d.ts +32 -0
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
3
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
4
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
5
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
6
|
+
import { getErrorCode } from "./utils";
|
|
7
|
+
export var MutationAuditReporter = /*#__PURE__*/function () {
|
|
8
|
+
function MutationAuditReporter(request, getMuseRuntime) {
|
|
9
|
+
_classCallCheck(this, MutationAuditReporter);
|
|
10
|
+
this.request = request;
|
|
11
|
+
this.getMuseRuntime = getMuseRuntime;
|
|
12
|
+
}
|
|
13
|
+
_createClass(MutationAuditReporter, [{
|
|
14
|
+
key: "observe",
|
|
15
|
+
value: function () {
|
|
16
|
+
var _observe = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
|
|
17
|
+
var operation, tableId, rowId, mutationData, task, startedAt, result, _getErrorCode;
|
|
18
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
19
|
+
while (1) switch (_context.prev = _context.next) {
|
|
20
|
+
case 0:
|
|
21
|
+
operation = _ref.operation, tableId = _ref.tableId, rowId = _ref.rowId, mutationData = _ref.mutationData, task = _ref.task;
|
|
22
|
+
startedAt = Date.now();
|
|
23
|
+
_context.prev = 2;
|
|
24
|
+
_context.next = 5;
|
|
25
|
+
return task();
|
|
26
|
+
case 5:
|
|
27
|
+
result = _context.sent;
|
|
28
|
+
this.schedule({
|
|
29
|
+
operation: operation,
|
|
30
|
+
tableId: tableId,
|
|
31
|
+
rowId: rowId,
|
|
32
|
+
outcome: 'success',
|
|
33
|
+
durationMs: Date.now() - startedAt,
|
|
34
|
+
mutationData: mutationData
|
|
35
|
+
});
|
|
36
|
+
return _context.abrupt("return", result);
|
|
37
|
+
case 10:
|
|
38
|
+
_context.prev = 10;
|
|
39
|
+
_context.t0 = _context["catch"](2);
|
|
40
|
+
this.schedule({
|
|
41
|
+
operation: operation,
|
|
42
|
+
tableId: tableId,
|
|
43
|
+
rowId: rowId,
|
|
44
|
+
outcome: 'failure',
|
|
45
|
+
durationMs: Date.now() - startedAt,
|
|
46
|
+
errorCode: (_getErrorCode = getErrorCode(_context.t0)) !== null && _getErrorCode !== void 0 ? _getErrorCode : undefined,
|
|
47
|
+
mutationData: mutationData
|
|
48
|
+
});
|
|
49
|
+
throw _context.t0;
|
|
50
|
+
case 14:
|
|
51
|
+
case "end":
|
|
52
|
+
return _context.stop();
|
|
53
|
+
}
|
|
54
|
+
}, _callee, this, [[2, 10]]);
|
|
55
|
+
}));
|
|
56
|
+
function observe(_x) {
|
|
57
|
+
return _observe.apply(this, arguments);
|
|
58
|
+
}
|
|
59
|
+
return observe;
|
|
60
|
+
}()
|
|
61
|
+
}, {
|
|
62
|
+
key: "schedule",
|
|
63
|
+
value: function schedule(_ref2) {
|
|
64
|
+
var _this = this;
|
|
65
|
+
var operation = _ref2.operation,
|
|
66
|
+
tableId = _ref2.tableId,
|
|
67
|
+
rowId = _ref2.rowId,
|
|
68
|
+
outcome = _ref2.outcome,
|
|
69
|
+
durationMs = _ref2.durationMs,
|
|
70
|
+
errorCode = _ref2.errorCode,
|
|
71
|
+
mutationData = _ref2.mutationData;
|
|
72
|
+
try {
|
|
73
|
+
var runtime = this.getMuseRuntime();
|
|
74
|
+
globalThis.setTimeout(function () {
|
|
75
|
+
try {
|
|
76
|
+
void Promise.resolve(_this.request(new URL('/api/runtime/appwrite/mutation-events', runtime.domain).toString(), {
|
|
77
|
+
method: 'POST',
|
|
78
|
+
credentials: 'include',
|
|
79
|
+
keepalive: true,
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json'
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify(_objectSpread(_objectSpread({
|
|
84
|
+
schemaVersion: 1,
|
|
85
|
+
operation: operation,
|
|
86
|
+
outcome: outcome,
|
|
87
|
+
appId: runtime.appId,
|
|
88
|
+
env: runtime.env,
|
|
89
|
+
tableId: tableId,
|
|
90
|
+
rowId: rowId,
|
|
91
|
+
durationMs: durationMs
|
|
92
|
+
}, errorCode === undefined ? {} : {
|
|
93
|
+
errorCode: errorCode
|
|
94
|
+
}), mutationData === undefined ? {} : {
|
|
95
|
+
mutationData: mutationData
|
|
96
|
+
}))
|
|
97
|
+
})).catch(function () {
|
|
98
|
+
return undefined;
|
|
99
|
+
});
|
|
100
|
+
} catch (_unused) {
|
|
101
|
+
// Security telemetry is best-effort and cannot alter mutation semantics.
|
|
102
|
+
}
|
|
103
|
+
}, 0);
|
|
104
|
+
} catch (_unused2) {
|
|
105
|
+
// Security telemetry is best-effort and cannot alter mutation semantics.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}]);
|
|
109
|
+
return MutationAuditReporter;
|
|
110
|
+
}();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { QmuseAppwriteRuntimeApi, QmuseAppwriteRuntimeOptions } from '../types';
|
|
2
|
+
export declare class QmuseAppwriteRuntime implements QmuseAppwriteRuntimeApi {
|
|
3
|
+
private readonly options;
|
|
4
|
+
readonly init: QmuseAppwriteRuntimeApi['init'];
|
|
5
|
+
readonly getClients: QmuseAppwriteRuntimeApi['getClients'];
|
|
6
|
+
readonly getCurrentUser: QmuseAppwriteRuntimeApi['getCurrentUser'];
|
|
7
|
+
readonly refreshSession: QmuseAppwriteRuntimeApi['refreshSession'];
|
|
8
|
+
readonly listRows: QmuseAppwriteRuntimeApi['listRows'];
|
|
9
|
+
readonly getRow: QmuseAppwriteRuntimeApi['getRow'];
|
|
10
|
+
readonly createRow: QmuseAppwriteRuntimeApi['createRow'];
|
|
11
|
+
readonly updateRow: QmuseAppwriteRuntimeApi['updateRow'];
|
|
12
|
+
readonly deleteRow: QmuseAppwriteRuntimeApi['deleteRow'];
|
|
13
|
+
private readonly session;
|
|
14
|
+
private readonly auditReporter;
|
|
15
|
+
constructor(options: QmuseAppwriteRuntimeOptions);
|
|
16
|
+
private getClientsInternal;
|
|
17
|
+
private listRowsInternal;
|
|
18
|
+
private getRowInternal;
|
|
19
|
+
private createRowInternal;
|
|
20
|
+
private updateRowInternal;
|
|
21
|
+
private deleteRowInternal;
|
|
22
|
+
}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
|
3
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
4
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
5
|
+
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
|
|
6
|
+
import _createClass from "@babel/runtime/helpers/esm/createClass";
|
|
7
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
8
|
+
import { ID, Permission, Query, Role } from 'appwrite';
|
|
9
|
+
import { AppwriteSessionCoordinator } from "./AppwriteSessionCoordinator";
|
|
10
|
+
import { MutationAuditReporter } from "./MutationAuditReporter";
|
|
11
|
+
import { sanitizeBusinessRowData, sanitizeMutationAuditData } from "./rowData";
|
|
12
|
+
import { createFetchRequest, isRecord, observePublicPromise } from "./utils";
|
|
13
|
+
export var QmuseAppwriteRuntime = /*#__PURE__*/function () {
|
|
14
|
+
function QmuseAppwriteRuntime(options) {
|
|
15
|
+
var _this = this;
|
|
16
|
+
_classCallCheck(this, QmuseAppwriteRuntime);
|
|
17
|
+
_defineProperty(this, "init", void 0);
|
|
18
|
+
_defineProperty(this, "getClients", void 0);
|
|
19
|
+
_defineProperty(this, "getCurrentUser", void 0);
|
|
20
|
+
_defineProperty(this, "refreshSession", void 0);
|
|
21
|
+
_defineProperty(this, "listRows", void 0);
|
|
22
|
+
_defineProperty(this, "getRow", void 0);
|
|
23
|
+
_defineProperty(this, "createRow", void 0);
|
|
24
|
+
_defineProperty(this, "updateRow", void 0);
|
|
25
|
+
_defineProperty(this, "deleteRow", void 0);
|
|
26
|
+
_defineProperty(this, "session", void 0);
|
|
27
|
+
_defineProperty(this, "auditReporter", void 0);
|
|
28
|
+
this.options = options;
|
|
29
|
+
var request = createFetchRequest(options.fetch);
|
|
30
|
+
this.session = new AppwriteSessionCoordinator(options, request);
|
|
31
|
+
this.auditReporter = new MutationAuditReporter(request, function () {
|
|
32
|
+
return options.getMuseRuntime();
|
|
33
|
+
});
|
|
34
|
+
this.init = observePublicPromise(function () {
|
|
35
|
+
return _this.session.init();
|
|
36
|
+
});
|
|
37
|
+
this.getClients = observePublicPromise(function () {
|
|
38
|
+
return _this.getClientsInternal();
|
|
39
|
+
});
|
|
40
|
+
this.getCurrentUser = observePublicPromise(function () {
|
|
41
|
+
return _this.session.getCurrentUser();
|
|
42
|
+
});
|
|
43
|
+
this.refreshSession = observePublicPromise(function () {
|
|
44
|
+
return _this.session.refreshSession();
|
|
45
|
+
});
|
|
46
|
+
this.listRows = observePublicPromise(function (input) {
|
|
47
|
+
return _this.listRowsInternal(input);
|
|
48
|
+
});
|
|
49
|
+
this.getRow = observePublicPromise(function (input) {
|
|
50
|
+
return _this.getRowInternal(input);
|
|
51
|
+
});
|
|
52
|
+
this.createRow = observePublicPromise(function (input) {
|
|
53
|
+
return _this.createRowInternal(input);
|
|
54
|
+
});
|
|
55
|
+
this.updateRow = observePublicPromise(function (input) {
|
|
56
|
+
return _this.updateRowInternal(input);
|
|
57
|
+
});
|
|
58
|
+
this.deleteRow = observePublicPromise(function (input) {
|
|
59
|
+
return _this.deleteRowInternal(input);
|
|
60
|
+
});
|
|
61
|
+
void this.init();
|
|
62
|
+
}
|
|
63
|
+
_createClass(QmuseAppwriteRuntime, [{
|
|
64
|
+
key: "getClientsInternal",
|
|
65
|
+
value: function () {
|
|
66
|
+
var _getClientsInternal = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
67
|
+
var databaseId;
|
|
68
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
69
|
+
while (1) switch (_context.prev = _context.next) {
|
|
70
|
+
case 0:
|
|
71
|
+
_context.next = 2;
|
|
72
|
+
return this.session.getDatabaseId();
|
|
73
|
+
case 2:
|
|
74
|
+
databaseId = _context.sent;
|
|
75
|
+
return _context.abrupt("return", {
|
|
76
|
+
client: this.options.client,
|
|
77
|
+
account: this.options.account,
|
|
78
|
+
tablesDB: this.options.tablesDB,
|
|
79
|
+
databaseId: databaseId
|
|
80
|
+
});
|
|
81
|
+
case 4:
|
|
82
|
+
case "end":
|
|
83
|
+
return _context.stop();
|
|
84
|
+
}
|
|
85
|
+
}, _callee, this);
|
|
86
|
+
}));
|
|
87
|
+
function getClientsInternal() {
|
|
88
|
+
return _getClientsInternal.apply(this, arguments);
|
|
89
|
+
}
|
|
90
|
+
return getClientsInternal;
|
|
91
|
+
}()
|
|
92
|
+
}, {
|
|
93
|
+
key: "listRowsInternal",
|
|
94
|
+
value: function () {
|
|
95
|
+
var _listRowsInternal = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(_ref) {
|
|
96
|
+
var _this2 = this;
|
|
97
|
+
var tableId, _ref$queries, queries, _ref$limit, limit, cursor, _yield$this$getClient, databaseId;
|
|
98
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
99
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
100
|
+
case 0:
|
|
101
|
+
tableId = _ref.tableId, _ref$queries = _ref.queries, queries = _ref$queries === void 0 ? [] : _ref$queries, _ref$limit = _ref.limit, limit = _ref$limit === void 0 ? 20 : _ref$limit, cursor = _ref.cursor;
|
|
102
|
+
if (!(!Number.isInteger(limit) || limit < 1 || limit > 20)) {
|
|
103
|
+
_context2.next = 3;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
throw new RangeError('listRows limit must be an integer from 1 to 20');
|
|
107
|
+
case 3:
|
|
108
|
+
_context2.next = 5;
|
|
109
|
+
return this.getClientsInternal();
|
|
110
|
+
case 5:
|
|
111
|
+
_yield$this$getClient = _context2.sent;
|
|
112
|
+
databaseId = _yield$this$getClient.databaseId;
|
|
113
|
+
return _context2.abrupt("return", this.session.withSessionRetry(function () {
|
|
114
|
+
return _this2.options.tablesDB.listRows({
|
|
115
|
+
databaseId: databaseId,
|
|
116
|
+
tableId: tableId,
|
|
117
|
+
queries: [Query.orderDesc('$createdAt')].concat(_toConsumableArray(queries), [Query.limit(limit)], _toConsumableArray(cursor ? [Query.cursorAfter(cursor)] : []))
|
|
118
|
+
});
|
|
119
|
+
}));
|
|
120
|
+
case 8:
|
|
121
|
+
case "end":
|
|
122
|
+
return _context2.stop();
|
|
123
|
+
}
|
|
124
|
+
}, _callee2, this);
|
|
125
|
+
}));
|
|
126
|
+
function listRowsInternal(_x) {
|
|
127
|
+
return _listRowsInternal.apply(this, arguments);
|
|
128
|
+
}
|
|
129
|
+
return listRowsInternal;
|
|
130
|
+
}()
|
|
131
|
+
}, {
|
|
132
|
+
key: "getRowInternal",
|
|
133
|
+
value: function () {
|
|
134
|
+
var _getRowInternal = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_ref2) {
|
|
135
|
+
var _this3 = this;
|
|
136
|
+
var tableId, rowId, _yield$this$getClient2, databaseId;
|
|
137
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
138
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
139
|
+
case 0:
|
|
140
|
+
tableId = _ref2.tableId, rowId = _ref2.rowId;
|
|
141
|
+
_context3.next = 3;
|
|
142
|
+
return this.getClientsInternal();
|
|
143
|
+
case 3:
|
|
144
|
+
_yield$this$getClient2 = _context3.sent;
|
|
145
|
+
databaseId = _yield$this$getClient2.databaseId;
|
|
146
|
+
return _context3.abrupt("return", this.session.withSessionRetry(function () {
|
|
147
|
+
return _this3.options.tablesDB.getRow({
|
|
148
|
+
databaseId: databaseId,
|
|
149
|
+
tableId: tableId,
|
|
150
|
+
rowId: rowId
|
|
151
|
+
});
|
|
152
|
+
}));
|
|
153
|
+
case 6:
|
|
154
|
+
case "end":
|
|
155
|
+
return _context3.stop();
|
|
156
|
+
}
|
|
157
|
+
}, _callee3, this);
|
|
158
|
+
}));
|
|
159
|
+
function getRowInternal(_x2) {
|
|
160
|
+
return _getRowInternal.apply(this, arguments);
|
|
161
|
+
}
|
|
162
|
+
return getRowInternal;
|
|
163
|
+
}()
|
|
164
|
+
}, {
|
|
165
|
+
key: "createRowInternal",
|
|
166
|
+
value: function () {
|
|
167
|
+
var _createRowInternal = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(_ref3) {
|
|
168
|
+
var _this4 = this;
|
|
169
|
+
var tableId, data, _ref3$rowId, rowId, _yield$this$getClient3, databaseId, mutationData;
|
|
170
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
171
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
172
|
+
case 0:
|
|
173
|
+
tableId = _ref3.tableId, data = _ref3.data, _ref3$rowId = _ref3.rowId, rowId = _ref3$rowId === void 0 ? ID.unique() : _ref3$rowId;
|
|
174
|
+
_context4.next = 3;
|
|
175
|
+
return this.getClientsInternal();
|
|
176
|
+
case 3:
|
|
177
|
+
_yield$this$getClient3 = _context4.sent;
|
|
178
|
+
databaseId = _yield$this$getClient3.databaseId;
|
|
179
|
+
mutationData = sanitizeBusinessRowData(data);
|
|
180
|
+
return _context4.abrupt("return", this.auditReporter.observe({
|
|
181
|
+
operation: 'create',
|
|
182
|
+
tableId: tableId,
|
|
183
|
+
rowId: rowId,
|
|
184
|
+
mutationData: sanitizeMutationAuditData(mutationData),
|
|
185
|
+
task: function task() {
|
|
186
|
+
return _this4.session.withSessionRetry(function () {
|
|
187
|
+
var currentUserId = _this4.session.requireCurrentUser().$id;
|
|
188
|
+
var owner = Role.user(currentUserId);
|
|
189
|
+
return _this4.options.tablesDB.createRow({
|
|
190
|
+
databaseId: databaseId,
|
|
191
|
+
tableId: tableId,
|
|
192
|
+
rowId: rowId,
|
|
193
|
+
data: _objectSpread(_objectSpread({}, mutationData), {}, {
|
|
194
|
+
creatorId: currentUserId,
|
|
195
|
+
modifierId: currentUserId
|
|
196
|
+
}),
|
|
197
|
+
permissions: [Permission.read(owner), Permission.update(owner), Permission.delete(owner)]
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}));
|
|
202
|
+
case 7:
|
|
203
|
+
case "end":
|
|
204
|
+
return _context4.stop();
|
|
205
|
+
}
|
|
206
|
+
}, _callee4, this);
|
|
207
|
+
}));
|
|
208
|
+
function createRowInternal(_x3) {
|
|
209
|
+
return _createRowInternal.apply(this, arguments);
|
|
210
|
+
}
|
|
211
|
+
return createRowInternal;
|
|
212
|
+
}()
|
|
213
|
+
}, {
|
|
214
|
+
key: "updateRowInternal",
|
|
215
|
+
value: function () {
|
|
216
|
+
var _updateRowInternal = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(_ref4) {
|
|
217
|
+
var _this5 = this;
|
|
218
|
+
var tableId, rowId, data, _yield$this$getClient4, databaseId, mutationData;
|
|
219
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
220
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
221
|
+
case 0:
|
|
222
|
+
tableId = _ref4.tableId, rowId = _ref4.rowId, data = _ref4.data;
|
|
223
|
+
_context5.next = 3;
|
|
224
|
+
return this.getClientsInternal();
|
|
225
|
+
case 3:
|
|
226
|
+
_yield$this$getClient4 = _context5.sent;
|
|
227
|
+
databaseId = _yield$this$getClient4.databaseId;
|
|
228
|
+
mutationData = sanitizeBusinessRowData(data);
|
|
229
|
+
return _context5.abrupt("return", this.auditReporter.observe({
|
|
230
|
+
operation: 'update',
|
|
231
|
+
tableId: tableId,
|
|
232
|
+
rowId: rowId,
|
|
233
|
+
mutationData: sanitizeMutationAuditData(mutationData),
|
|
234
|
+
task: function task() {
|
|
235
|
+
return _this5.session.withSessionRetry(function () {
|
|
236
|
+
return _this5.options.tablesDB.updateRow({
|
|
237
|
+
databaseId: databaseId,
|
|
238
|
+
tableId: tableId,
|
|
239
|
+
rowId: rowId,
|
|
240
|
+
data: _objectSpread(_objectSpread({}, mutationData), {}, {
|
|
241
|
+
modifierId: _this5.session.requireCurrentUser().$id
|
|
242
|
+
})
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}));
|
|
247
|
+
case 7:
|
|
248
|
+
case "end":
|
|
249
|
+
return _context5.stop();
|
|
250
|
+
}
|
|
251
|
+
}, _callee5, this);
|
|
252
|
+
}));
|
|
253
|
+
function updateRowInternal(_x4) {
|
|
254
|
+
return _updateRowInternal.apply(this, arguments);
|
|
255
|
+
}
|
|
256
|
+
return updateRowInternal;
|
|
257
|
+
}()
|
|
258
|
+
}, {
|
|
259
|
+
key: "deleteRowInternal",
|
|
260
|
+
value: function () {
|
|
261
|
+
var _deleteRowInternal = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(_ref5) {
|
|
262
|
+
var _this6 = this;
|
|
263
|
+
var tableId, rowId, _yield$this$getClient5, databaseId, mutationData, existingRow;
|
|
264
|
+
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
|
|
265
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
266
|
+
case 0:
|
|
267
|
+
tableId = _ref5.tableId, rowId = _ref5.rowId;
|
|
268
|
+
_context6.next = 3;
|
|
269
|
+
return this.getClientsInternal();
|
|
270
|
+
case 3:
|
|
271
|
+
_yield$this$getClient5 = _context6.sent;
|
|
272
|
+
databaseId = _yield$this$getClient5.databaseId;
|
|
273
|
+
_context6.prev = 5;
|
|
274
|
+
_context6.next = 8;
|
|
275
|
+
return this.session.withSessionRetry(function () {
|
|
276
|
+
return _this6.options.tablesDB.getRow({
|
|
277
|
+
databaseId: databaseId,
|
|
278
|
+
tableId: tableId,
|
|
279
|
+
rowId: rowId
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
case 8:
|
|
283
|
+
existingRow = _context6.sent;
|
|
284
|
+
if (isRecord(existingRow)) {
|
|
285
|
+
mutationData = sanitizeMutationAuditData(sanitizeBusinessRowData(existingRow));
|
|
286
|
+
}
|
|
287
|
+
_context6.next = 14;
|
|
288
|
+
break;
|
|
289
|
+
case 12:
|
|
290
|
+
_context6.prev = 12;
|
|
291
|
+
_context6.t0 = _context6["catch"](5);
|
|
292
|
+
case 14:
|
|
293
|
+
return _context6.abrupt("return", this.auditReporter.observe({
|
|
294
|
+
operation: 'delete',
|
|
295
|
+
tableId: tableId,
|
|
296
|
+
rowId: rowId,
|
|
297
|
+
mutationData: mutationData,
|
|
298
|
+
task: function task() {
|
|
299
|
+
return _this6.session.withSessionRetry(function () {
|
|
300
|
+
return _this6.options.tablesDB.deleteRow({
|
|
301
|
+
databaseId: databaseId,
|
|
302
|
+
tableId: tableId,
|
|
303
|
+
rowId: rowId
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}));
|
|
308
|
+
case 15:
|
|
309
|
+
case "end":
|
|
310
|
+
return _context6.stop();
|
|
311
|
+
}
|
|
312
|
+
}, _callee6, this, [[5, 12]]);
|
|
313
|
+
}));
|
|
314
|
+
function deleteRowInternal(_x5) {
|
|
315
|
+
return _deleteRowInternal.apply(this, arguments);
|
|
316
|
+
}
|
|
317
|
+
return deleteRowInternal;
|
|
318
|
+
}()
|
|
319
|
+
}]);
|
|
320
|
+
return QmuseAppwriteRuntime;
|
|
321
|
+
}();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import { isRecord } from "./utils";
|
|
3
|
+
var BLOCKED_MUTATION_FIELDS = new Set(['code', 'creatorId', 'modifierId', 'gmtCreate', 'gmtModified']);
|
|
4
|
+
var SENSITIVE_AUDIT_FIELD_PATTERN = /(?:password|passwd|secret|token|authorization|cookie|api[-_]?key|access[-_]?key|private[-_]?key)/i;
|
|
5
|
+
var REDACTED_AUDIT_VALUE = '[REDACTED]';
|
|
6
|
+
var MAX_AUDIT_DEPTH = 5;
|
|
7
|
+
var MAX_AUDIT_KEYS = 100;
|
|
8
|
+
var MAX_AUDIT_ARRAY_ITEMS = 100;
|
|
9
|
+
var MAX_AUDIT_STRING_LENGTH = 2048;
|
|
10
|
+
export function sanitizeBusinessRowData(data) {
|
|
11
|
+
return Object.fromEntries(Object.entries(data).filter(function (_ref) {
|
|
12
|
+
var _ref2 = _slicedToArray(_ref, 1),
|
|
13
|
+
key = _ref2[0];
|
|
14
|
+
return !key.startsWith('$') && !BLOCKED_MUTATION_FIELDS.has(key);
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
function sanitizeAuditValue(value, depth, ancestors) {
|
|
18
|
+
if (typeof value === 'string') {
|
|
19
|
+
return value.length > MAX_AUDIT_STRING_LENGTH ? "".concat(value.slice(0, MAX_AUDIT_STRING_LENGTH), "[TRUNCATED]") : value;
|
|
20
|
+
}
|
|
21
|
+
if (depth >= MAX_AUDIT_DEPTH && (Array.isArray(value) || isRecord(value))) {
|
|
22
|
+
return '[MAX_DEPTH]';
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
if (ancestors.has(value)) {
|
|
26
|
+
return '[CIRCULAR]';
|
|
27
|
+
}
|
|
28
|
+
ancestors.add(value);
|
|
29
|
+
var _result = value.slice(0, MAX_AUDIT_ARRAY_ITEMS).map(function (item) {
|
|
30
|
+
return sanitizeAuditValue(item, depth + 1, ancestors);
|
|
31
|
+
});
|
|
32
|
+
ancestors.delete(value);
|
|
33
|
+
if (value.length > MAX_AUDIT_ARRAY_ITEMS) {
|
|
34
|
+
_result.push('[TRUNCATED]');
|
|
35
|
+
}
|
|
36
|
+
return _result;
|
|
37
|
+
}
|
|
38
|
+
if (!isRecord(value)) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
if (ancestors.has(value)) {
|
|
42
|
+
return '[CIRCULAR]';
|
|
43
|
+
}
|
|
44
|
+
ancestors.add(value);
|
|
45
|
+
var entries = Object.entries(value).slice(0, MAX_AUDIT_KEYS);
|
|
46
|
+
var result = Object.fromEntries(entries.map(function (_ref3) {
|
|
47
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
48
|
+
key = _ref4[0],
|
|
49
|
+
childValue = _ref4[1];
|
|
50
|
+
return [key, SENSITIVE_AUDIT_FIELD_PATTERN.test(key) ? REDACTED_AUDIT_VALUE : sanitizeAuditValue(childValue, depth + 1, ancestors)];
|
|
51
|
+
}));
|
|
52
|
+
ancestors.delete(value);
|
|
53
|
+
if (Object.keys(value).length > MAX_AUDIT_KEYS) {
|
|
54
|
+
result.__auditTruncated = true;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
export function sanitizeMutationAuditData(data) {
|
|
59
|
+
return sanitizeAuditValue(data, 0, new WeakSet());
|
|
60
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
2
|
+
export declare function getErrorCode(error: unknown): number | null;
|
|
3
|
+
export declare function createResponseError({ payload, status, fallbackMessage, fallbackType, }: {
|
|
4
|
+
payload: Record<string, unknown> | null;
|
|
5
|
+
status: number;
|
|
6
|
+
fallbackMessage: string;
|
|
7
|
+
fallbackType: string;
|
|
8
|
+
}): Error;
|
|
9
|
+
export declare function readResponsePayload(response: Response): Promise<Record<string, unknown> | null>;
|
|
10
|
+
export declare function createFetchRequest(configuredFetch?: typeof globalThis.fetch): typeof globalThis.fetch;
|
|
11
|
+
export declare function observePublicPromise<TArgs extends unknown[], TResult>(operation: (...args: TArgs) => Promise<TResult>): (...args: TArgs) => Promise<TResult>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
+
import _typeof from "@babel/runtime/helpers/esm/typeof";
|
|
4
|
+
export function isRecord(value) {
|
|
5
|
+
return Boolean(value) && _typeof(value) === 'object' && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
export function getErrorCode(error) {
|
|
8
|
+
if (!isRecord(error)) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
var code = Number(error.code);
|
|
12
|
+
return Number.isFinite(code) ? code : null;
|
|
13
|
+
}
|
|
14
|
+
export function createResponseError(_ref) {
|
|
15
|
+
var _payload$code, _payload$type;
|
|
16
|
+
var payload = _ref.payload,
|
|
17
|
+
status = _ref.status,
|
|
18
|
+
fallbackMessage = _ref.fallbackMessage,
|
|
19
|
+
fallbackType = _ref.fallbackType;
|
|
20
|
+
var error = new Error(typeof (payload === null || payload === void 0 ? void 0 : payload.message) === 'string' && payload.message ? payload.message : fallbackMessage);
|
|
21
|
+
Object.assign(error, {
|
|
22
|
+
code: (_payload$code = payload === null || payload === void 0 ? void 0 : payload.code) !== null && _payload$code !== void 0 ? _payload$code : status,
|
|
23
|
+
type: (_payload$type = payload === null || payload === void 0 ? void 0 : payload.type) !== null && _payload$type !== void 0 ? _payload$type : fallbackType
|
|
24
|
+
});
|
|
25
|
+
return error;
|
|
26
|
+
}
|
|
27
|
+
export function readResponsePayload(_x) {
|
|
28
|
+
return _readResponsePayload.apply(this, arguments);
|
|
29
|
+
}
|
|
30
|
+
function _readResponsePayload() {
|
|
31
|
+
_readResponsePayload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(response) {
|
|
32
|
+
var payload;
|
|
33
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
34
|
+
while (1) switch (_context.prev = _context.next) {
|
|
35
|
+
case 0:
|
|
36
|
+
_context.next = 2;
|
|
37
|
+
return response.json().catch(function () {
|
|
38
|
+
return null;
|
|
39
|
+
});
|
|
40
|
+
case 2:
|
|
41
|
+
payload = _context.sent;
|
|
42
|
+
return _context.abrupt("return", isRecord(payload) ? payload : null);
|
|
43
|
+
case 4:
|
|
44
|
+
case "end":
|
|
45
|
+
return _context.stop();
|
|
46
|
+
}
|
|
47
|
+
}, _callee);
|
|
48
|
+
}));
|
|
49
|
+
return _readResponsePayload.apply(this, arguments);
|
|
50
|
+
}
|
|
51
|
+
export function createFetchRequest(configuredFetch) {
|
|
52
|
+
return function (input, init) {
|
|
53
|
+
var fetchImplementation = configuredFetch !== null && configuredFetch !== void 0 ? configuredFetch : globalThis.fetch;
|
|
54
|
+
if (!fetchImplementation) {
|
|
55
|
+
return Promise.reject(new Error('A fetch implementation is required'));
|
|
56
|
+
}
|
|
57
|
+
return fetchImplementation(input, init);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function observePublicPromise(operation) {
|
|
61
|
+
return function () {
|
|
62
|
+
var promise = operation.apply(void 0, arguments);
|
|
63
|
+
void promise.catch(function () {
|
|
64
|
+
return undefined;
|
|
65
|
+
});
|
|
66
|
+
return promise;
|
|
67
|
+
};
|
|
68
|
+
}
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,31 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function createQmuseAppwriteRuntime(options: QmuseAppwriteRuntimeOptions):
|
|
3
|
-
init: () => Promise<void>;
|
|
4
|
-
getClients: () => Promise<QmuseAppwriteClients>;
|
|
5
|
-
getCurrentUser: () => AppwriteUser;
|
|
6
|
-
refreshSession: () => Promise<void>;
|
|
7
|
-
listRows: ({ tableId, queries, limit, cursor, }: {
|
|
8
|
-
tableId: string;
|
|
9
|
-
queries?: string[] | undefined;
|
|
10
|
-
limit?: number | undefined;
|
|
11
|
-
cursor?: string | undefined;
|
|
12
|
-
}) => Promise<unknown>;
|
|
13
|
-
getRow: ({ tableId, rowId, }: {
|
|
14
|
-
tableId: string;
|
|
15
|
-
rowId: string;
|
|
16
|
-
}) => Promise<unknown>;
|
|
17
|
-
createRow: ({ tableId, data, rowId, }: {
|
|
18
|
-
tableId: string;
|
|
19
|
-
data: BusinessRowData;
|
|
20
|
-
rowId?: string | undefined;
|
|
21
|
-
}) => Promise<unknown>;
|
|
22
|
-
updateRow: ({ tableId, rowId, data, }: {
|
|
23
|
-
tableId: string;
|
|
24
|
-
rowId: string;
|
|
25
|
-
data: BusinessRowData;
|
|
26
|
-
}) => Promise<unknown>;
|
|
27
|
-
deleteRow: ({ tableId, rowId, }: {
|
|
28
|
-
tableId: string;
|
|
29
|
-
rowId: string;
|
|
30
|
-
}) => Promise<unknown>;
|
|
31
|
-
};
|
|
1
|
+
import type { QmuseAppwriteRuntimeApi, QmuseAppwriteRuntimeOptions } from './types';
|
|
2
|
+
export declare function createQmuseAppwriteRuntime(options: QmuseAppwriteRuntimeOptions): QmuseAppwriteRuntimeApi;
|