remult 0.14.7 → 0.14.8

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 (152) hide show
  1. package/LICENSE +21 -0
  2. package/esm/assign.d.ts +1 -0
  3. package/esm/assign.js +5 -0
  4. package/esm/classType.d.ts +3 -0
  5. package/esm/classType.js +1 -0
  6. package/esm/graphql.d.ts +5 -0
  7. package/esm/graphql.js +102 -0
  8. package/esm/index.d.ts +36 -0
  9. package/esm/index.js +30 -0
  10. package/esm/inputTypes.d.ts +9 -0
  11. package/esm/inputTypes.js +9 -0
  12. package/esm/postgres/index.d.ts +2 -0
  13. package/esm/postgres/index.js +2 -0
  14. package/esm/postgres/postgres-data-provider.d.ts +28 -0
  15. package/esm/postgres/postgres-data-provider.js +97 -0
  16. package/esm/postgres/schema-builder.d.ts +15 -0
  17. package/esm/postgres/schema-builder.js +128 -0
  18. package/esm/remult-express.d.ts +5 -0
  19. package/esm/remult-express.js +16 -0
  20. package/esm/remult-knex/index.d.ts +51 -0
  21. package/esm/remult-knex/index.js +381 -0
  22. package/esm/remult-middleware.d.ts +2 -0
  23. package/esm/remult-middleware.js +63 -0
  24. package/esm/remult-mongo.d.ts +9 -0
  25. package/esm/remult-mongo.js +220 -0
  26. package/esm/server/JsonEntityFileStorage.d.ts +7 -0
  27. package/esm/server/JsonEntityFileStorage.js +20 -0
  28. package/esm/server/expressBridge.d.ts +140 -0
  29. package/esm/server/expressBridge.js +668 -0
  30. package/esm/server/index.d.ts +4 -0
  31. package/esm/server/index.js +4 -0
  32. package/esm/server/register-actions-on-server.d.ts +3 -0
  33. package/esm/server/register-actions-on-server.js +24 -0
  34. package/esm/server/register-entities-on-server.d.ts +3 -0
  35. package/esm/server/register-entities-on-server.js +15 -0
  36. package/esm/src/__EntityValueProvider.d.ts +10 -0
  37. package/esm/src/__EntityValueProvider.js +1 -0
  38. package/esm/src/__RowsOfDataForTesting.d.ts +3 -0
  39. package/esm/src/__RowsOfDataForTesting.js +1 -0
  40. package/esm/src/backend-tests/backend-database-test-setup.backend-spec.d.ts +5 -0
  41. package/esm/src/backend-tests/backend-database-test-setup.backend-spec.js +113 -0
  42. package/esm/src/backend-tests/my-test.backend-spec.d.ts +1 -0
  43. package/esm/src/backend-tests/my-test.backend-spec.js +49 -0
  44. package/esm/src/column-interfaces.d.ts +95 -0
  45. package/esm/src/column-interfaces.js +7 -0
  46. package/esm/src/column.d.ts +49 -0
  47. package/esm/src/column.js +133 -0
  48. package/esm/src/context.d.ts +124 -0
  49. package/esm/src/context.js +285 -0
  50. package/esm/src/data-api.d.ts +33 -0
  51. package/esm/src/data-api.js +204 -0
  52. package/esm/src/data-interfaces.d.ts +37 -0
  53. package/esm/src/data-interfaces.js +12 -0
  54. package/esm/src/data-providers/array-entity-data-provider.d.ts +22 -0
  55. package/esm/src/data-providers/array-entity-data-provider.js +264 -0
  56. package/esm/src/data-providers/in-memory-database.d.ts +9 -0
  57. package/esm/src/data-providers/in-memory-database.js +16 -0
  58. package/esm/src/data-providers/json-data-provider.d.ts +12 -0
  59. package/esm/src/data-providers/json-data-provider.js +52 -0
  60. package/esm/src/data-providers/rest-data-provider.d.ts +35 -0
  61. package/esm/src/data-providers/rest-data-provider.js +188 -0
  62. package/esm/src/data-providers/sql-database.d.ts +16 -0
  63. package/esm/src/data-providers/sql-database.js +261 -0
  64. package/esm/src/data-providers/web-sql-data-provider.d.ts +18 -0
  65. package/esm/src/data-providers/web-sql-data-provider.js +121 -0
  66. package/esm/src/entity.d.ts +82 -0
  67. package/esm/src/entity.js +1 -0
  68. package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +50 -0
  69. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +139 -0
  70. package/esm/src/filter/filter-consumer-bridge-to-url-builder.d.ts +1 -0
  71. package/esm/src/filter/filter-consumer-bridge-to-url-builder.js +1 -0
  72. package/esm/src/filter/filter-interfaces.d.ts +85 -0
  73. package/esm/src/filter/filter-interfaces.js +467 -0
  74. package/esm/src/id-entity.d.ts +4 -0
  75. package/esm/src/id-entity.js +8 -0
  76. package/esm/src/remult3/RepositoryImplementation.d.ts +326 -0
  77. package/esm/src/remult3/RepositoryImplementation.js +1806 -0
  78. package/esm/src/remult3/index.d.ts +2 -0
  79. package/esm/src/remult3/index.js +2 -0
  80. package/esm/src/remult3/remult3.d.ts +312 -0
  81. package/esm/src/remult3/remult3.js +1 -0
  82. package/esm/src/server-action.d.ts +70 -0
  83. package/esm/src/server-action.js +365 -0
  84. package/esm/src/shared-tests/db-tests-setup.d.ts +23 -0
  85. package/esm/src/shared-tests/db-tests-setup.js +66 -0
  86. package/esm/src/shared-tests/db-tests.db-tests.d.ts +26 -0
  87. package/esm/src/shared-tests/db-tests.db-tests.js +723 -0
  88. package/esm/src/shared-tests/deleteAll.d.ts +2 -0
  89. package/esm/src/shared-tests/deleteAll.js +4 -0
  90. package/esm/src/shared-tests/entityWithValidations.d.ts +14 -0
  91. package/esm/src/shared-tests/entityWithValidations.js +53 -0
  92. package/esm/src/shared-tests/index.d.ts +4 -0
  93. package/esm/src/shared-tests/index.js +4 -0
  94. package/esm/src/shared-tests/test-custom-id-column.spec.d.ts +1 -0
  95. package/esm/src/shared-tests/test-custom-id-column.spec.js +62 -0
  96. package/esm/src/shared-tests/test-special-value.spec.d.ts +10 -0
  97. package/esm/src/shared-tests/test-special-value.spec.js +88 -0
  98. package/esm/src/shared-tests/test-update-with-null.spec.d.ts +1 -0
  99. package/esm/src/shared-tests/test-update-with-null.spec.js +47 -0
  100. package/esm/src/sort.d.ts +15 -0
  101. package/esm/src/sort.js +82 -0
  102. package/esm/src/sql-command.d.ts +15 -0
  103. package/esm/src/sql-command.js +1 -0
  104. package/esm/src/tests/Done.d.ts +5 -0
  105. package/esm/src/tests/Done.js +11 -0
  106. package/esm/src/tests/TestDataApiResponse.d.ts +10 -0
  107. package/esm/src/tests/TestDataApiResponse.js +22 -0
  108. package/esm/src/tests/c.d.ts +8 -0
  109. package/esm/src/tests/c.js +22 -0
  110. package/esm/src/tests/createData.d.ts +7 -0
  111. package/esm/src/tests/createData.js +22 -0
  112. package/esm/src/tests/d.d.ts +6 -0
  113. package/esm/src/tests/d.js +19 -0
  114. package/esm/src/tests/dWithPrefilter.d.ts +7 -0
  115. package/esm/src/tests/dWithPrefilter.js +32 -0
  116. package/esm/src/tests/entityForCustomFilter.d.ts +16 -0
  117. package/esm/src/tests/entityForCustomFilter.js +44 -0
  118. package/esm/src/tests/entityWithValidationsOnColumn.d.ts +5 -0
  119. package/esm/src/tests/entityWithValidationsOnColumn.js +21 -0
  120. package/esm/src/tests/frontend-database-tests-setup.spec.d.ts +4 -0
  121. package/esm/src/tests/frontend-database-tests-setup.spec.js +38 -0
  122. package/esm/src/tests/h.d.ts +6 -0
  123. package/esm/src/tests/h.js +35 -0
  124. package/esm/src/tests/remult-3-entities.d.ts +23 -0
  125. package/esm/src/tests/remult-3-entities.js +72 -0
  126. package/esm/src/tests/tasks.d.ts +6 -0
  127. package/esm/src/tests/tasks.js +24 -0
  128. package/esm/src/tests/testHelper.spec.d.ts +34 -0
  129. package/esm/src/tests/testHelper.spec.js +217 -0
  130. package/esm/src/tests/testModel/models.d.ts +16 -0
  131. package/esm/src/tests/testModel/models.js +31 -0
  132. package/esm/src/validators.d.ts +14 -0
  133. package/esm/src/validators.js +33 -0
  134. package/esm/urlBuilder.d.ts +6 -0
  135. package/esm/urlBuilder.js +19 -0
  136. package/esm/valueConverters.d.ts +12 -0
  137. package/esm/valueConverters.js +169 -0
  138. package/index.d.ts +1 -0
  139. package/index.js +1 -0
  140. package/package.json +22 -1
  141. package/postgres/index.d.ts +1 -0
  142. package/postgres/index.js +1 -0
  143. package/postgres/postgres-data-provider.d.ts +1 -13
  144. package/postgres/postgres-data-provider.js +28 -262
  145. package/postgres/schema-builder.d.ts +15 -0
  146. package/postgres/schema-builder.js +270 -0
  147. package/readme.md +68 -30
  148. package/src/data-providers/web-sql-data-provider.js +4 -3
  149. package/src/entity.d.ts +9 -2
  150. package/src/remult3/RepositoryImplementation.js +11 -3
  151. package/src/shared-tests/test-update-with-null.spec.js +38 -0
  152. package/valueConverters.js +4 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Noam Honig, Yoni Rapoport and contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ export declare function assign<T>(item: T, valuesToSet: Partial<T>): T;
package/esm/assign.js ADDED
@@ -0,0 +1,5 @@
1
+ export function assign(item, valuesToSet) {
2
+ if (valuesToSet)
3
+ Object.assign(item, valuesToSet);
4
+ return item;
5
+ }
@@ -0,0 +1,3 @@
1
+ export declare type ClassType<T> = {
2
+ new (...args: any[]): T;
3
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { RemultExpressBridge } from "./server/expressBridge";
2
+ export declare function remultGraphql(api: RemultExpressBridge): {
3
+ rootValue: {};
4
+ schema: string;
5
+ };
package/esm/graphql.js ADDED
@@ -0,0 +1,102 @@
1
+ import { Remult } from ".";
2
+ import { allEntities } from "./src/context";
3
+ import { getEntityKey } from "./src/remult3";
4
+ import { DataApi } from "./src/data-api";
5
+ export function remultGraphql(api) {
6
+ let r = new Remult();
7
+ let types = '';
8
+ let query = '';
9
+ let root = {};
10
+ for (const e of allEntities) {
11
+ let meta = r.repo(e).metadata;
12
+ let fields = '';
13
+ let filterFields = '';
14
+ let key = getEntityKey(e);
15
+ if (key) {
16
+ for (const f of meta.fields) {
17
+ {
18
+ let type = "String";
19
+ switch (f.valueType) {
20
+ case Boolean:
21
+ type = "Boolean";
22
+ case Number:
23
+ {
24
+ if (f.valueConverter?.fieldTypeInDb == 'integer')
25
+ type = "Int";
26
+ else
27
+ type = "Float";
28
+ }
29
+ }
30
+ fields += "\n\t" + f.key + ":" + type;
31
+ for (const operator of ["", "_ne"]) {
32
+ filterFields += "\n\t" + f.key + operator + ":" + type;
33
+ }
34
+ if (f.valueType === String || f.valueType === Number)
35
+ for (const operator of ["_gt", "_gte", "_lt", "_lte"]) {
36
+ filterFields += "\n\t" + f.key + operator + ":" + type;
37
+ }
38
+ if (f.valueType === String)
39
+ for (const operator of ["_st", "_contains"]) {
40
+ filterFields += "\n\t" + f.key + operator + ":" + type;
41
+ }
42
+ if (f.allowNull)
43
+ filterFields += "\n\t" + f.key + "_null:Boolean";
44
+ filterFields += "\n\t" + f.key + "_in:[" + type + "]";
45
+ }
46
+ }
47
+ types += "type " + key + "{" + fields + "\n}\n";
48
+ types += "input " + key + "Filter{" + filterFields + "\n\tOR:[" + key + "Filter]\n}\n";
49
+ query += "\n\t" + key + "(options: options, filter:" + key + "Filter): [" + key + "]";
50
+ root[key] = async ({ options, filter }, req) => {
51
+ let remult = await api.getRemult(req);
52
+ let repo = remult.repo(e);
53
+ let dApi = new DataApi(repo, remult);
54
+ let result;
55
+ let err;
56
+ await dApi.getArray({
57
+ success: x => result = x,
58
+ created: undefined,
59
+ deleted: undefined,
60
+ error: x => err = x,
61
+ forbidden: () => err = 'forbidden',
62
+ notFound: () => err = 'not found',
63
+ progress: undefined
64
+ }, {
65
+ get: key => {
66
+ if (options)
67
+ switch (key) {
68
+ case "_limit":
69
+ return options.limit;
70
+ case "_page":
71
+ return options.page;
72
+ case "_sort":
73
+ return options.sort;
74
+ case "_order":
75
+ return options.order;
76
+ }
77
+ }
78
+ }, filter);
79
+ if (err)
80
+ throw err;
81
+ return result;
82
+ };
83
+ }
84
+ }
85
+ if (query.length > 0) {
86
+ query = `type Query {${query}
87
+ }`;
88
+ }
89
+ return {
90
+ rootValue: root,
91
+ schema: `
92
+ input options{
93
+ limit:Int
94
+ page:Int
95
+ sort:String
96
+ order:String
97
+ }
98
+ ${types}
99
+ ${query}
100
+ `
101
+ };
102
+ }
package/esm/index.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ export { Field, Fields, StringFieldOptions, FieldsMetadata, Entity, BuildEntity, EntityBase, ControllerBase, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FieldType, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, getFields, EntityRef, getEntityRef, SortSegments, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, OmitEB, Paginator, CaptionTransformer } from './src/remult3';
2
+ export { EntityOptions } from './src/entity';
3
+ export { DataProvider, EntityDataProvider, EntityDataProviderFindOptions, ErrorInfo, RestDataProviderHttpProvider } from './src/data-interfaces';
4
+ export { SqlCommand, SqlImplementation, SqlResult } from './src/sql-command';
5
+ export { FieldMetadata, FieldOptions, FieldValidator, ValueConverter, ValueListItem, // reconsider, maybe it should go to remult angular as the abstraction ?
6
+ ValueOrExpression } from './src/column-interfaces';
7
+ export { RestDataProvider } from './src/data-providers/rest-data-provider';
8
+ export { InMemoryDataProvider } from './src/data-providers/in-memory-database';
9
+ export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider';
10
+ export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider';
11
+ export { SqlDatabase } from './src/data-providers/sql-database';
12
+ export { JsonDataProvider, JsonEntityStorage } from './src/data-providers/json-data-provider';
13
+ export { Controller, BackendMethodOptions, BackendMethod, ProgressListener } from './src/server-action';
14
+ export { Allowed, Allow, Remult, isBackend, AllowedForInstance, EventDispatcher, EventSource, HttpProvider, Unobserve, UserInfo } from './src/context';
15
+ export { IdEntity } from './src/id-entity';
16
+ export { SortSegment, Sort } from './src/sort';
17
+ export { OneToMany, CompoundIdField } from './src/column';
18
+ export { Filter } from './src/filter/filter-interfaces';
19
+ export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-bridge-to-sql-request';
20
+ export { UrlBuilder } from './urlBuilder';
21
+ export { Validators } from './src/validators';
22
+ export { ValueConverters } from './valueConverters';
23
+ export { ClassType } from "./classType";
24
+ export { allEntities } from "./src/context";
25
+ export { serializeError } from "./src/data-api";
26
+ export { DataApiRequest } from "./src/data-api";
27
+ export { DataApiResponse } from "./src/data-api";
28
+ export { DataApi } from "./src/data-api";
29
+ export { getEntityKey } from "./src/remult3/index";
30
+ export { jobWasQueuedResult } from "./src/server-action";
31
+ export { queuedJobInfoResponse } from "./src/server-action";
32
+ export { Action, classBackendMethodsArray, serverActionField } from "./src/server-action";
33
+ export { actionInfo } from "./src/server-action";
34
+ export { registerActionsOnServer } from './server/register-actions-on-server';
35
+ export { registerEntitiesOnServer } from './server/register-entities-on-server';
36
+ /** db implementation required */
package/esm/index.js ADDED
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Public API Surface of remult
3
+ */
4
+ export { Field, Fields, Entity, BuildEntity, EntityBase, ControllerBase, FieldType, getFields, getEntityRef, ValueListFieldType, getValueList, ValueListInfo, CaptionTransformer } from './src/remult3';
5
+ export { RestDataProvider } from './src/data-providers/rest-data-provider'; //V
6
+ export { InMemoryDataProvider } from './src/data-providers/in-memory-database'; //V
7
+ export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider'; //V
8
+ export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider'; //V
9
+ export { SqlDatabase } from './src/data-providers/sql-database'; //V
10
+ export { JsonDataProvider } from './src/data-providers/json-data-provider'; //V
11
+ //export * from './src/data-api'; //reconsider if to make internal
12
+ export { Controller, BackendMethod, ProgressListener } from './src/server-action';
13
+ export { Allow, Remult, isBackend, EventSource } from './src/context';
14
+ export { IdEntity } from './src/id-entity';
15
+ export { Sort } from './src/sort';
16
+ export { OneToMany, CompoundIdField } from './src/column';
17
+ export { Filter } from './src/filter/filter-interfaces';
18
+ export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-bridge-to-sql-request';
19
+ export { UrlBuilder } from './urlBuilder';
20
+ export { Validators } from './src/validators';
21
+ export { ValueConverters } from './valueConverters';
22
+ export { allEntities } from "./src/context";
23
+ export { serializeError } from "./src/data-api";
24
+ export { DataApi } from "./src/data-api";
25
+ export { getEntityKey } from "./src/remult3/index";
26
+ export { Action, classBackendMethodsArray, serverActionField } from "./src/server-action";
27
+ export { actionInfo } from "./src/server-action";
28
+ export { registerActionsOnServer } from './server/register-actions-on-server';
29
+ export { registerEntitiesOnServer } from './server/register-entities-on-server';
30
+ /** db implementation required */
@@ -0,0 +1,9 @@
1
+ export declare class InputTypes {
2
+ static number: string;
3
+ static date: string;
4
+ static checkbox: string;
5
+ static password: string;
6
+ static email: string;
7
+ static tel: string;
8
+ static time: string;
9
+ }
@@ -0,0 +1,9 @@
1
+ export class InputTypes {
2
+ }
3
+ InputTypes.number = 'number';
4
+ InputTypes.date = 'date';
5
+ InputTypes.checkbox = 'checkbox';
6
+ InputTypes.password = 'password';
7
+ InputTypes.email = 'email';
8
+ InputTypes.tel = 'tel';
9
+ InputTypes.time = "time";
@@ -0,0 +1,2 @@
1
+ export * from './postgres-data-provider';
2
+ export * from './schema-builder';
@@ -0,0 +1,2 @@
1
+ export * from './postgres-data-provider';
2
+ export * from './schema-builder';
@@ -0,0 +1,28 @@
1
+ import { PoolConfig, QueryResult } from 'pg';
2
+ import { EntityMetadata } from '../src/remult3';
3
+ import { SqlCommand, SqlImplementation } from '../src/sql-command';
4
+ import { SqlDatabase } from '../src/data-providers/sql-database';
5
+ export interface PostgresPool extends PostgresCommandSource {
6
+ connect(): Promise<PostgresClient>;
7
+ }
8
+ export interface PostgresClient extends PostgresCommandSource {
9
+ release(): void;
10
+ }
11
+ export declare class PostgresDataProvider implements SqlImplementation {
12
+ private pool;
13
+ entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
14
+ getLimitSqlSyntax(limit: number, offset: number): string;
15
+ createCommand(): SqlCommand;
16
+ constructor(pool: PostgresPool);
17
+ transaction(action: (dataProvider: SqlImplementation) => Promise<void>): Promise<void>;
18
+ }
19
+ export interface PostgresCommandSource {
20
+ query(queryText: string, values?: any[]): Promise<QueryResult>;
21
+ }
22
+ export declare function createPostgresConnection(options?: {
23
+ connectionString?: string;
24
+ sslInDev?: boolean;
25
+ configuration?: "heroku" | PoolConfig;
26
+ autoCreateTables?: boolean;
27
+ }): Promise<SqlDatabase>;
28
+ export declare function preparePostgresQueueStorage(sql: SqlDatabase): Promise<import("../server/expressBridge").EntityQueueStorage>;
@@ -0,0 +1,97 @@
1
+ import { Pool } from 'pg';
2
+ import { Remult } from '../src/context';
3
+ import { PostgresSchemaBuilder, verifyStructureOfAllEntities } from './schema-builder';
4
+ import { SqlDatabase } from '../src/data-providers/sql-database';
5
+ export class PostgresDataProvider {
6
+ constructor(pool) {
7
+ this.pool = pool;
8
+ }
9
+ async entityIsUsedForTheFirstTime(entity) {
10
+ }
11
+ getLimitSqlSyntax(limit, offset) {
12
+ return ' limit ' + limit + ' offset ' + offset;
13
+ }
14
+ createCommand() {
15
+ return new PostgresBridgeToSQLCommand(this.pool);
16
+ }
17
+ async transaction(action) {
18
+ let client = await this.pool.connect();
19
+ try {
20
+ await client.query('BEGIN');
21
+ await action({
22
+ createCommand: () => new PostgresBridgeToSQLCommand(client),
23
+ entityIsUsedForTheFirstTime: this.entityIsUsedForTheFirstTime,
24
+ transaction: () => { throw "nested transactions not allowed"; },
25
+ getLimitSqlSyntax: this.getLimitSqlSyntax
26
+ });
27
+ await client.query('COMMIT');
28
+ }
29
+ catch (err) {
30
+ await client.query('ROLLBACK');
31
+ throw err;
32
+ }
33
+ finally {
34
+ await client.release();
35
+ }
36
+ }
37
+ }
38
+ class PostgresBridgeToSQLCommand {
39
+ constructor(source) {
40
+ this.source = source;
41
+ this.values = [];
42
+ }
43
+ addParameterAndReturnSqlToken(val) {
44
+ this.values.push(val);
45
+ return '$' + this.values.length;
46
+ }
47
+ execute(sql) {
48
+ return this.source.query(sql, this.values).then(r => new PostgresBridgeToSQLQueryResult(r));
49
+ }
50
+ }
51
+ class PostgresBridgeToSQLQueryResult {
52
+ constructor(r) {
53
+ this.r = r;
54
+ this.rows = r.rows;
55
+ }
56
+ getColumnKeyInResultForIndexInSelect(index) {
57
+ return this.r.fields[index].name;
58
+ }
59
+ }
60
+ export async function createPostgresConnection(options) {
61
+ if (!options)
62
+ options = {};
63
+ let config = {};
64
+ if (options.configuration)
65
+ if (options.configuration == "heroku") {
66
+ config = {
67
+ connectionString: process.env.DATABASE_URL,
68
+ ssl: process.env.NODE_ENV !== "production" && !options.sslInDev ? false : {
69
+ rejectUnauthorized: false
70
+ }
71
+ };
72
+ }
73
+ else
74
+ config = options.configuration;
75
+ else {
76
+ if (!options.connectionString)
77
+ options.connectionString = process.env.DATABASE_URL;
78
+ }
79
+ if (!config.connectionString && options.connectionString) {
80
+ config.connectionString = options.connectionString;
81
+ }
82
+ const db = new SqlDatabase(new PostgresDataProvider(new Pool(config)));
83
+ let remult = new Remult();
84
+ remult.setDataProvider(db);
85
+ if (options.autoCreateTables === undefined || options.autoCreateTables)
86
+ await verifyStructureOfAllEntities(db, remult);
87
+ return db;
88
+ }
89
+ export async function preparePostgresQueueStorage(sql) {
90
+ let c = new Remult();
91
+ c.setDataProvider(sql);
92
+ let JobsInQueueEntity = (await import('../server/expressBridge')).JobsInQueueEntity;
93
+ let e = c.repo(JobsInQueueEntity);
94
+ await new PostgresSchemaBuilder(sql).createIfNotExist(e.metadata);
95
+ await new PostgresSchemaBuilder(sql).verifyAllColumns(e.metadata);
96
+ return new (await import('../server/expressBridge')).EntityQueueStorage(c.repo(JobsInQueueEntity));
97
+ }
@@ -0,0 +1,15 @@
1
+ import { FieldMetadata } from '../src/column-interfaces';
2
+ import { Remult } from '../src/context';
3
+ import { SqlDatabase } from '../src/data-providers/sql-database';
4
+ import { EntityMetadata } from '../src/remult3';
5
+ export declare function postgresColumnSyntax(x: FieldMetadata, dbName: string): string;
6
+ export declare function verifyStructureOfAllEntities(db: SqlDatabase, remult: Remult): Promise<void>;
7
+ export declare class PostgresSchemaBuilder {
8
+ private pool;
9
+ verifyStructureOfAllEntities(remult: Remult): Promise<void>;
10
+ createIfNotExist(entity: EntityMetadata): Promise<void>;
11
+ addColumnIfNotExist<T extends EntityMetadata>(entity: T, c: ((e: T) => FieldMetadata)): Promise<void>;
12
+ verifyAllColumns<T extends EntityMetadata>(entity: T): Promise<void>;
13
+ additionalWhere: string;
14
+ constructor(pool: SqlDatabase, schema?: string);
15
+ }
@@ -0,0 +1,128 @@
1
+ import { allEntities } from '../src/context';
2
+ import { getDbNameProvider } from '../src/filter/filter-consumer-bridge-to-sql-request';
3
+ import { isAutoIncrement } from '../src/remult3';
4
+ import { ValueConverters } from '../valueConverters';
5
+ export function postgresColumnSyntax(x, dbName) {
6
+ let result = dbName;
7
+ if (x.valueType == Number) {
8
+ if (!x.valueConverter.fieldTypeInDb)
9
+ result += " numeric" + (x.allowNull ? "" : " default 0 not null");
10
+ else
11
+ result += " " + x.valueConverter.fieldTypeInDb + (x.allowNull ? "" : " default 0 not null");
12
+ }
13
+ else if (x.valueType == Date) {
14
+ if (!x.valueConverter.fieldTypeInDb)
15
+ if (x.valueConverter == ValueConverters.DateOnly)
16
+ result += " date";
17
+ else
18
+ result += " timestamp";
19
+ else
20
+ result += " " + x.valueConverter.fieldTypeInDb;
21
+ }
22
+ else if (x.valueType == Boolean)
23
+ result += " boolean" + (x.allowNull ? "" : " default false not null");
24
+ else if (x.valueConverter.fieldTypeInDb) {
25
+ result += " " + x.valueConverter.fieldTypeInDb;
26
+ if (!x.allowNull && x.valueConverter.fieldTypeInDb == 'integer') {
27
+ result += " default 0 not null";
28
+ }
29
+ }
30
+ else
31
+ result += " varchar" + (x.allowNull ? "" : " default '' not null");
32
+ return result;
33
+ }
34
+ export async function verifyStructureOfAllEntities(db, remult) {
35
+ return await new PostgresSchemaBuilder(db).verifyStructureOfAllEntities(remult);
36
+ }
37
+ export class PostgresSchemaBuilder {
38
+ constructor(pool, schema) {
39
+ this.pool = pool;
40
+ this.additionalWhere = '';
41
+ if (schema) {
42
+ this.additionalWhere = ' and table_schema=\'' + schema + '\'';
43
+ }
44
+ }
45
+ async verifyStructureOfAllEntities(remult) {
46
+ console.log("start verify structure");
47
+ for (const entityClass of allEntities) {
48
+ let entity = remult.repo(entityClass).metadata;
49
+ let e = await getDbNameProvider(entity);
50
+ try {
51
+ if (!entity.options.sqlExpression) {
52
+ if ((await e.entityName).toLowerCase().indexOf('from ') < 0) {
53
+ await this.createIfNotExist(entity);
54
+ await this.verifyAllColumns(entity);
55
+ }
56
+ }
57
+ }
58
+ catch (err) {
59
+ console.log("failed verify structure of " + e.entityName + " ", err);
60
+ }
61
+ }
62
+ }
63
+ async createIfNotExist(entity) {
64
+ var c = this.pool.createCommand();
65
+ let e = await getDbNameProvider(entity);
66
+ await c.execute("select 1 from information_Schema.tables where table_name=" + c.addParameterAndReturnSqlToken((e.entityName).toLowerCase()) + this.additionalWhere).then(async (r) => {
67
+ if (r.rows.length == 0) {
68
+ let result = '';
69
+ for (const x of entity.fields) {
70
+ if (!e.isDbReadonly(x) || isAutoIncrement(x)) {
71
+ if (result.length != 0)
72
+ result += ',';
73
+ result += '\r\n ';
74
+ if (isAutoIncrement(x))
75
+ result += e.nameOf(x) + ' serial';
76
+ else {
77
+ result += postgresColumnSyntax(x, e.nameOf(x));
78
+ if (x == entity.idMetadata.field)
79
+ result += ' primary key';
80
+ }
81
+ }
82
+ }
83
+ let sql = 'create table ' + e.entityName + ' (' + result + '\r\n)';
84
+ //console.log(sql);
85
+ await this.pool.execute(sql);
86
+ }
87
+ });
88
+ }
89
+ async addColumnIfNotExist(entity, c) {
90
+ let e = await getDbNameProvider(entity);
91
+ if (e.isDbReadonly(c(entity)))
92
+ return;
93
+ try {
94
+ let cmd = this.pool.createCommand();
95
+ const colName = e.nameOf(c(entity));
96
+ if ((await cmd.execute(`select 1
97
+ FROM information_schema.columns
98
+ WHERE table_name=${cmd.addParameterAndReturnSqlToken((e.entityName).toLocaleLowerCase())} and column_name=${cmd.addParameterAndReturnSqlToken((colName).toLocaleLowerCase())}` + this.additionalWhere)).rows.length == 0) {
99
+ let sql = `alter table ${e.entityName} add column ${postgresColumnSyntax(c(entity), colName)}`;
100
+ //console.log(sql);
101
+ await this.pool.execute(sql);
102
+ }
103
+ }
104
+ catch (err) {
105
+ console.log(err);
106
+ }
107
+ }
108
+ async verifyAllColumns(entity) {
109
+ try {
110
+ let cmd = this.pool.createCommand();
111
+ let e = await getDbNameProvider(entity);
112
+ let cols = (await cmd.execute(`select column_name
113
+ FROM information_schema.columns
114
+ WHERE table_name=${cmd.addParameterAndReturnSqlToken((e.entityName).toLocaleLowerCase())} ` + this.additionalWhere)).rows.map(x => x.column_name);
115
+ for (const col of entity.fields) {
116
+ if (!e.isDbReadonly(col))
117
+ if (!cols.includes(e.nameOf(col).toLocaleLowerCase())) {
118
+ let sql = `alter table ${e.entityName} add column ${postgresColumnSyntax(col, e.nameOf(col))}`;
119
+ //console.log(sql);
120
+ await this.pool.execute(sql);
121
+ }
122
+ }
123
+ }
124
+ catch (err) {
125
+ console.log(err);
126
+ }
127
+ }
128
+ }
@@ -0,0 +1,5 @@
1
+ import { RemultMiddlewareOptions } from './server/expressBridge';
2
+ export declare function remultExpress(options?: RemultMiddlewareOptions & {
3
+ bodyParser?: boolean;
4
+ bodySizeLimit?: string;
5
+ }): import("./server/expressBridge").RemultExpressBridge;
@@ -0,0 +1,16 @@
1
+ import * as express from 'express';
2
+ import { remultMiddlewareBase } from './server/expressBridge';
3
+ export function remultExpress(options) {
4
+ let app = express.Router();
5
+ if (!options) {
6
+ options = {};
7
+ }
8
+ if (options.bodySizeLimit === undefined) {
9
+ options.bodySizeLimit = '10mb';
10
+ }
11
+ if (options?.bodyParser !== false) {
12
+ app.use(express.json({ limit: options.bodySizeLimit }));
13
+ app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
14
+ }
15
+ return remultMiddlewareBase(app, options);
16
+ }
@@ -0,0 +1,51 @@
1
+ import { Knex } from 'knex';
2
+ import { Filter, FilterConsumer } from "../src/filter/filter-interfaces";
3
+ import { dbNameProvider } from "../src/filter/filter-consumer-bridge-to-sql-request";
4
+ import { Remult } from "../src/context";
5
+ import { EntityFilter, EntityMetadata } from "../src/remult3";
6
+ import { DataProvider, EntityDataProvider } from '../src/data-interfaces';
7
+ import { FieldMetadata } from '../src/column-interfaces';
8
+ export declare class KnexDataProvider implements DataProvider {
9
+ knex: Knex;
10
+ constructor(knex: Knex);
11
+ getEntityDataProvider(entity: EntityMetadata<any>): EntityDataProvider;
12
+ transaction(action: (dataProvider: DataProvider) => Promise<void>): Promise<void>;
13
+ static customFilter(build: CustomKnexFilterBuilderFunction): EntityFilter<any>;
14
+ supportsCustomFilter?: boolean;
15
+ }
16
+ export declare type CustomKnexFilterBuilderFunction = () => Promise<(builder: Knex.QueryBuilder) => void>;
17
+ export declare class FilterConsumerBridgeToKnexRequest implements FilterConsumer {
18
+ private nameProvider;
19
+ _addWhere: boolean;
20
+ promises: Promise<void>[];
21
+ result: ((builder: Knex.QueryBuilder) => void)[];
22
+ resolveWhere(): Promise<((builder: Knex.QueryBuilder<any, any>) => void)[]>;
23
+ constructor(nameProvider: dbNameProvider);
24
+ custom(key: string, customItem: any): void;
25
+ or(orElements: Filter[]): void;
26
+ isNull(col: FieldMetadata): void;
27
+ isNotNull(col: FieldMetadata): void;
28
+ isIn(col: FieldMetadata, val: any[]): void;
29
+ isEqualTo(col: FieldMetadata, val: any): void;
30
+ isDifferentFrom(col: FieldMetadata, val: any): void;
31
+ isGreaterOrEqualTo(col: FieldMetadata, val: any): void;
32
+ isGreaterThan(col: FieldMetadata, val: any): void;
33
+ isLessOrEqualTo(col: FieldMetadata, val: any): void;
34
+ isLessThan(col: FieldMetadata, val: any): void;
35
+ containsCaseInsensitive(col: FieldMetadata, val: any): void;
36
+ private add;
37
+ databaseCustom(databaseCustom: {
38
+ buildKnex: CustomKnexFilterBuilderFunction;
39
+ }): void;
40
+ }
41
+ export declare class KnexSchemaBuilder {
42
+ private knex;
43
+ verifyStructureOfAllEntities(remult: Remult): Promise<void>;
44
+ createIfNotExist(entity: EntityMetadata): Promise<void>;
45
+ addColumnIfNotExist<T extends EntityMetadata>(entity: T, c: ((e: T) => FieldMetadata)): Promise<void>;
46
+ verifyAllColumns<T extends EntityMetadata>(entity: T): Promise<void>;
47
+ additionalWhere: string;
48
+ constructor(knex: Knex);
49
+ }
50
+ export declare function buildColumn(x: FieldMetadata, dbName: string, b: Knex.CreateTableBuilder): void;
51
+ export declare function createKnexDataProvider(config: Knex.Config, autoCreateTables?: boolean): Promise<KnexDataProvider>;