@webiny/api-form-builder-so-ddb-es 0.0.0-mt-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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +12 -0
  3. package/configurations.d.ts +9 -0
  4. package/configurations.js +28 -0
  5. package/definitions/elasticsearch.d.ts +8 -0
  6. package/definitions/elasticsearch.js +47 -0
  7. package/definitions/form.d.ts +8 -0
  8. package/definitions/form.js +104 -0
  9. package/definitions/settings.d.ts +8 -0
  10. package/definitions/settings.js +53 -0
  11. package/definitions/submission.d.ts +8 -0
  12. package/definitions/submission.js +74 -0
  13. package/definitions/system.d.ts +8 -0
  14. package/definitions/system.js +44 -0
  15. package/definitions/table.d.ts +7 -0
  16. package/definitions/table.js +23 -0
  17. package/definitions/tableElasticsearch.d.ts +7 -0
  18. package/definitions/tableElasticsearch.js +23 -0
  19. package/index.d.ts +2 -0
  20. package/index.js +188 -0
  21. package/operations/form/elasticsearchBody.d.ts +13 -0
  22. package/operations/form/elasticsearchBody.js +187 -0
  23. package/operations/form/elasticsearchFields.d.ts +3 -0
  24. package/operations/form/elasticsearchFields.js +33 -0
  25. package/operations/form/fields.d.ts +3 -0
  26. package/operations/form/fields.js +15 -0
  27. package/operations/form/index.d.ts +17 -0
  28. package/operations/form/index.js +903 -0
  29. package/operations/settings/index.d.ts +7 -0
  30. package/operations/settings/index.js +122 -0
  31. package/operations/submission/elasticsearchBody.d.ts +13 -0
  32. package/operations/submission/elasticsearchBody.js +197 -0
  33. package/operations/submission/elasticsearchFields.d.ts +3 -0
  34. package/operations/submission/elasticsearchFields.js +30 -0
  35. package/operations/submission/index.d.ts +12 -0
  36. package/operations/submission/index.js +340 -0
  37. package/operations/system/createElasticsearchIndex.d.ts +6 -0
  38. package/operations/system/createElasticsearchIndex.js +70 -0
  39. package/operations/system/index.d.ts +7 -0
  40. package/operations/system/index.js +105 -0
  41. package/package.json +67 -0
  42. package/plugins/FormDynamoDbFieldPlugin.d.ts +4 -0
  43. package/plugins/FormDynamoDbFieldPlugin.js +17 -0
  44. package/plugins/FormElasticsearchBodyModifierPlugin.d.ts +4 -0
  45. package/plugins/FormElasticsearchBodyModifierPlugin.js +17 -0
  46. package/plugins/FormElasticsearchFieldPlugin.d.ts +4 -0
  47. package/plugins/FormElasticsearchFieldPlugin.js +17 -0
  48. package/plugins/FormElasticsearchQueryModifierPlugin.d.ts +4 -0
  49. package/plugins/FormElasticsearchQueryModifierPlugin.js +17 -0
  50. package/plugins/FormElasticsearchSortModifierPlugin.d.ts +4 -0
  51. package/plugins/FormElasticsearchSortModifierPlugin.js +17 -0
  52. package/plugins/SubmissionElasticsearchBodyModifierPlugin.d.ts +4 -0
  53. package/plugins/SubmissionElasticsearchBodyModifierPlugin.js +17 -0
  54. package/plugins/SubmissionElasticsearchFieldPlugin.d.ts +4 -0
  55. package/plugins/SubmissionElasticsearchFieldPlugin.js +17 -0
  56. package/plugins/SubmissionElasticsearchQueryModifierPlugin.d.ts +4 -0
  57. package/plugins/SubmissionElasticsearchQueryModifierPlugin.js +17 -0
  58. package/plugins/SubmissionElasticsearchSortModifierPlugin.d.ts +4 -0
  59. package/plugins/SubmissionElasticsearchSortModifierPlugin.js +17 -0
  60. package/types.d.ts +66 -0
  61. package/types.js +17 -0
  62. package/upgrades/5.16.0/index.d.ts +8 -0
  63. package/upgrades/5.16.0/index.js +141 -0
package/index.js ADDED
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.createFormBuilderStorageOperations = void 0;
9
+
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+
12
+ var _types = require("./types");
13
+
14
+ var _error = _interopRequireDefault(require("@webiny/error"));
15
+
16
+ var _table = require("./definitions/table");
17
+
18
+ var _form = require("./definitions/form");
19
+
20
+ var _submission = require("./definitions/submission");
21
+
22
+ var _system = require("./definitions/system");
23
+
24
+ var _settings = require("./definitions/settings");
25
+
26
+ var _system2 = require("./operations/system");
27
+
28
+ var _submission2 = require("./operations/submission");
29
+
30
+ var _settings2 = require("./operations/settings");
31
+
32
+ var _form2 = require("./operations/form");
33
+
34
+ var _createElasticsearchIndex = require("./operations/system/createElasticsearchIndex");
35
+
36
+ var _tableElasticsearch = require("./definitions/tableElasticsearch");
37
+
38
+ var _plugins = require("@webiny/plugins");
39
+
40
+ var _elasticsearch = require("./definitions/elasticsearch");
41
+
42
+ var _elasticsearchFields = _interopRequireDefault(require("./operations/submission/elasticsearchFields"));
43
+
44
+ var _elasticsearchFields2 = _interopRequireDefault(require("./operations/form/elasticsearchFields"));
45
+
46
+ var _filters = _interopRequireDefault(require("@webiny/db-dynamodb/plugins/filters"));
47
+
48
+ var _operators = require("@webiny/api-elasticsearch/operators");
49
+
50
+ var _ = _interopRequireDefault(require("./upgrades/5.16.0"));
51
+
52
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
53
+
54
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
55
+
56
+ const reservedFields = ["PK", "SK", "index", "data", "TYPE", "__type", "GSI1_PK", "GSI1_SK"];
57
+
58
+ const isReserved = name => {
59
+ if (reservedFields.includes(name) === false) {
60
+ return;
61
+ }
62
+
63
+ throw new _error.default(`Attribute name "${name}" is not allowed.`, "ATTRIBUTE_NOT_ALLOWED", {
64
+ name
65
+ });
66
+ };
67
+
68
+ const createFormBuilderStorageOperations = params => {
69
+ const {
70
+ attributes = {},
71
+ table: tableName,
72
+ esTable: esTableName,
73
+ documentClient,
74
+ elasticsearch,
75
+ plugins: pluginsInput
76
+ } = params;
77
+
78
+ if (attributes) {
79
+ Object.values(attributes).forEach(attrs => {
80
+ Object.keys(attrs).forEach(isReserved);
81
+ });
82
+ }
83
+
84
+ const plugins = new _plugins.PluginsContainer([
85
+ /**
86
+ * User defined plugins.
87
+ */
88
+ pluginsInput || [],
89
+ /**
90
+ * Elasticsearch field definitions for the submission record.
91
+ */
92
+ (0, _elasticsearchFields.default)(),
93
+ /**
94
+ * Elasticsearch field definitions for the form record.
95
+ */
96
+ (0, _elasticsearchFields2.default)(),
97
+ /**
98
+ * DynamoDB filter plugins for the where conditions.
99
+ */
100
+ (0, _filters.default)(),
101
+ /**
102
+ * Elasticsearch operators.
103
+ */
104
+ (0, _operators.getElasticsearchOperators)()]);
105
+ const table = (0, _table.createTable)({
106
+ tableName,
107
+ documentClient
108
+ });
109
+ const esTable = (0, _tableElasticsearch.createElasticsearchTable)({
110
+ tableName: esTableName,
111
+ documentClient
112
+ });
113
+ const entities = {
114
+ /**
115
+ * Regular entities.
116
+ */
117
+ form: (0, _form.createFormEntity)({
118
+ entityName: _types.ENTITIES.FORM,
119
+ table,
120
+ attributes: attributes[_types.ENTITIES.FORM]
121
+ }),
122
+ submission: (0, _submission.createSubmissionEntity)({
123
+ entityName: _types.ENTITIES.SUBMISSION,
124
+ table,
125
+ attributes: attributes[_types.ENTITIES.SUBMISSION]
126
+ }),
127
+ system: (0, _system.createSystemEntity)({
128
+ entityName: _types.ENTITIES.SYSTEM,
129
+ table,
130
+ attributes: attributes[_types.ENTITIES.SYSTEM]
131
+ }),
132
+ settings: (0, _settings.createSettingsEntity)({
133
+ entityName: _types.ENTITIES.SETTINGS,
134
+ table,
135
+ attributes: attributes[_types.ENTITIES.SETTINGS]
136
+ }),
137
+
138
+ /**
139
+ * Elasticsearch entities.
140
+ */
141
+ esForm: (0, _elasticsearch.createElasticsearchEntity)({
142
+ entityName: _types.ENTITIES.ES_FORM,
143
+ table: esTable,
144
+ attributes: attributes[_types.ENTITIES.ES_FORM]
145
+ }),
146
+ esSubmission: (0, _elasticsearch.createElasticsearchEntity)({
147
+ entityName: _types.ENTITIES.ES_SUBMISSION,
148
+ table: esTable,
149
+ attributes: attributes[_types.ENTITIES.ES_SUBMISSION]
150
+ })
151
+ };
152
+ return _objectSpread(_objectSpread(_objectSpread(_objectSpread({
153
+ init: async formBuilder => {
154
+ formBuilder.onAfterInstall.subscribe(async ({
155
+ tenant
156
+ }) => {
157
+ await (0, _createElasticsearchIndex.createElasticsearchIndex)({
158
+ elasticsearch,
159
+ tenant
160
+ });
161
+ });
162
+ },
163
+ upgrade: (0, _.default)(),
164
+ getTable: () => table,
165
+ getEsTable: () => esTable,
166
+ getEntities: () => entities
167
+ }, (0, _system2.createSystemStorageOperations)({
168
+ table,
169
+ entity: entities.system
170
+ })), (0, _settings2.createSettingsStorageOperations)({
171
+ table,
172
+ entity: entities.settings
173
+ })), (0, _form2.createFormStorageOperations)({
174
+ elasticsearch,
175
+ table,
176
+ entity: entities.form,
177
+ esEntity: entities.esForm,
178
+ plugins
179
+ })), (0, _submission2.createSubmissionStorageOperations)({
180
+ elasticsearch,
181
+ table,
182
+ entity: entities.submission,
183
+ esEntity: entities.esSubmission,
184
+ plugins
185
+ }));
186
+ };
187
+
188
+ exports.createFormBuilderStorageOperations = createFormBuilderStorageOperations;
@@ -0,0 +1,13 @@
1
+ import { SearchBody as esSearchBody } from "elastic-ts";
2
+ import { FormBuilderStorageOperationsListFormsParams } from "@webiny/api-form-builder/types";
3
+ import { PluginsContainer } from "@webiny/plugins";
4
+ export declare const createFormElasticType: () => string;
5
+ interface CreateElasticsearchBodyParams {
6
+ plugins: PluginsContainer;
7
+ where: FormBuilderStorageOperationsListFormsParams["where"];
8
+ limit: number;
9
+ after?: string;
10
+ sort: string[];
11
+ }
12
+ export declare const createElasticsearchBody: (params: CreateElasticsearchBodyParams) => esSearchBody;
13
+ export {};
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.createFormElasticType = exports.createElasticsearchBody = void 0;
9
+
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+
12
+ var _cursors = require("@webiny/api-elasticsearch/cursors");
13
+
14
+ var _sort = require("@webiny/api-elasticsearch/sort");
15
+
16
+ var _limit = require("@webiny/api-elasticsearch/limit");
17
+
18
+ var _ElasticsearchQueryBuilderOperatorPlugin = require("@webiny/api-elasticsearch/plugins/definition/ElasticsearchQueryBuilderOperatorPlugin");
19
+
20
+ var _FormElasticsearchFieldPlugin = require("../../plugins/FormElasticsearchFieldPlugin");
21
+
22
+ var _FormElasticsearchSortModifierPlugin = require("../../plugins/FormElasticsearchSortModifierPlugin");
23
+
24
+ var _FormElasticsearchBodyModifierPlugin = require("../../plugins/FormElasticsearchBodyModifierPlugin");
25
+
26
+ var _FormElasticsearchQueryModifierPlugin = require("../../plugins/FormElasticsearchQueryModifierPlugin");
27
+
28
+ var _where = require("@webiny/api-elasticsearch/where");
29
+
30
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
31
+
32
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
33
+
34
+ const createFormElasticType = () => {
35
+ return "fb.form";
36
+ };
37
+
38
+ exports.createFormElasticType = createFormElasticType;
39
+
40
+ const createInitialQueryValue = () => {
41
+ return {
42
+ must: [
43
+ /**
44
+ * We add the __type filtering in the initial query because it must be applied.
45
+ */
46
+ {
47
+ term: {
48
+ "__type.keyword": createFormElasticType()
49
+ }
50
+ }],
51
+ must_not: [],
52
+ should: [],
53
+ filter: []
54
+ };
55
+ };
56
+
57
+ const createElasticsearchQuery = params => {
58
+ const {
59
+ plugins,
60
+ where: initialWhere,
61
+ fieldPlugins
62
+ } = params;
63
+ const query = createInitialQueryValue();
64
+ /**
65
+ * Be aware that, if having more registered operator plugins of same type, the last one will be used.
66
+ */
67
+
68
+ const operatorPlugins = plugins.byType(_ElasticsearchQueryBuilderOperatorPlugin.ElasticsearchQueryBuilderOperatorPlugin.type).reduce((acc, plugin) => {
69
+ acc[plugin.getOperator()] = plugin;
70
+ return acc;
71
+ }, {});
72
+
73
+ const where = _objectSpread({}, initialWhere);
74
+ /**
75
+ * !!! IMPORTANT !!! There are few specific cases where we hardcode the query conditions.
76
+ *
77
+ * When ES index is shared between tenants, we need to filter records by tenant ID.
78
+ * No need for the tenant filtering otherwise as each index is for single tenant.
79
+ */
80
+
81
+
82
+ const sharedIndex = process.env.ELASTICSEARCH_SHARED_INDEXES === "true";
83
+
84
+ if (sharedIndex) {
85
+ query.must.push({
86
+ term: {
87
+ "tenant.keyword": where.tenant
88
+ }
89
+ });
90
+ }
91
+ /**
92
+ * Remove tenant so it is not applied again later.
93
+ * Possibly tenant is not defined, but just in case, remove it.
94
+ */
95
+
96
+
97
+ delete where.tenant;
98
+ /**
99
+ * Add the locale to filtering.
100
+ */
101
+
102
+ query.must.push({
103
+ term: {
104
+ "locale.keyword": where.locale
105
+ }
106
+ });
107
+ delete where.locale;
108
+ /**
109
+ * We apply other conditions as they are passed via the where value.
110
+ */
111
+
112
+ (0, _where.applyWhere)({
113
+ query,
114
+ where,
115
+ fields: fieldPlugins,
116
+ operators: operatorPlugins
117
+ });
118
+ return query;
119
+ };
120
+
121
+ const createElasticsearchBody = params => {
122
+ const {
123
+ plugins,
124
+ where,
125
+ limit: initialLimit,
126
+ sort: initialSort,
127
+ after
128
+ } = params;
129
+ const fieldPlugins = plugins.byType(_FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin.type).reduce((acc, plugin) => {
130
+ acc[plugin.field] = plugin;
131
+ return acc;
132
+ }, {});
133
+ const limit = (0, _limit.createLimit)(initialLimit, 100);
134
+ const query = createElasticsearchQuery(_objectSpread(_objectSpread({}, params), {}, {
135
+ fieldPlugins
136
+ }));
137
+ const sort = (0, _sort.createSort)({
138
+ sort: initialSort,
139
+ fieldPlugins
140
+ });
141
+ const queryModifiers = plugins.byType(_FormElasticsearchQueryModifierPlugin.FormElasticsearchQueryModifierPlugin.type);
142
+
143
+ for (const plugin of queryModifiers) {
144
+ plugin.modifyQuery({
145
+ query,
146
+ where
147
+ });
148
+ }
149
+
150
+ const sortModifiers = plugins.byType(_FormElasticsearchSortModifierPlugin.FormElasticsearchSortModifierPlugin.type);
151
+
152
+ for (const plugin of sortModifiers) {
153
+ plugin.modifySort({
154
+ sort
155
+ });
156
+ }
157
+
158
+ const body = {
159
+ query: {
160
+ constant_score: {
161
+ filter: {
162
+ bool: _objectSpread({}, query)
163
+ }
164
+ }
165
+ },
166
+ size: limit + 1,
167
+
168
+ /**
169
+ * Casting as any is required due to search_after is accepting an array of values.
170
+ * Which is correct in some cases. In our case, it is not.
171
+ * https://www.elastic.co/guide/en/elasticsearch/reference/7.13/paginate-search-results.html
172
+ */
173
+ search_after: (0, _cursors.decodeCursor)(after),
174
+ sort
175
+ };
176
+ const bodyModifiers = plugins.byType(_FormElasticsearchBodyModifierPlugin.FormElasticsearchBodyModifierPlugin.type);
177
+
178
+ for (const plugin of bodyModifiers) {
179
+ plugin.modifyBody({
180
+ body
181
+ });
182
+ }
183
+
184
+ return body;
185
+ };
186
+
187
+ exports.createElasticsearchBody = createElasticsearchBody;
@@ -0,0 +1,3 @@
1
+ import { FormElasticsearchFieldPlugin } from "../../plugins/FormElasticsearchFieldPlugin";
2
+ declare const _default: () => FormElasticsearchFieldPlugin[];
3
+ export default _default;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _FormElasticsearchFieldPlugin = require("../../plugins/FormElasticsearchFieldPlugin");
9
+
10
+ var _default = () => [new _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin({
11
+ field: "createdOn",
12
+ unmappedType: "date"
13
+ }), new _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin({
14
+ field: "savedOn",
15
+ unmappedType: "date"
16
+ }), new _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin({
17
+ field: "publishedOn",
18
+ unmappedType: "date"
19
+ }), new _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin({
20
+ field: "ownedBy",
21
+ path: "ownedBy.id"
22
+ }), new _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin({
23
+ field: "createdBy",
24
+ path: "createdBy.id"
25
+ }),
26
+ /**
27
+ * Always add the ALL fields plugin because of the keyword/path build.
28
+ */
29
+ new _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin({
30
+ field: _FormElasticsearchFieldPlugin.FormElasticsearchFieldPlugin.ALL
31
+ })];
32
+
33
+ exports.default = _default;
@@ -0,0 +1,3 @@
1
+ import { FormDynamoDbFieldPlugin } from "../../plugins/FormDynamoDbFieldPlugin";
2
+ declare const _default: () => FormDynamoDbFieldPlugin[];
3
+ export default _default;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _FormDynamoDbFieldPlugin = require("../../plugins/FormDynamoDbFieldPlugin");
9
+
10
+ var _default = () => [new _FormDynamoDbFieldPlugin.FormDynamoDbFieldPlugin({
11
+ field: "publishedOn",
12
+ type: "date"
13
+ })];
14
+
15
+ exports.default = _default;
@@ -0,0 +1,17 @@
1
+ import { Entity, Table } from "dynamodb-toolbox";
2
+ import { Client } from "@elastic/elasticsearch";
3
+ import { PluginsContainer } from "@webiny/plugins";
4
+ import { FormBuilderFormStorageOperations } from "../../types";
5
+ export declare type DbRecord<T = any> = T & {
6
+ PK: string;
7
+ SK: string;
8
+ TYPE: string;
9
+ };
10
+ export interface Params {
11
+ entity: Entity<any>;
12
+ esEntity: Entity<any>;
13
+ table: Table;
14
+ elasticsearch: Client;
15
+ plugins: PluginsContainer;
16
+ }
17
+ export declare const createFormStorageOperations: (params: Params) => FormBuilderFormStorageOperations;