@mondomob/gae-node-nestjs 12.0.0-alpha-2 → 12.0.0-alpha1

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 (213) hide show
  1. package/.claude/settings.local.json +5 -1
  2. package/CHANGELOG.md +51 -0
  3. package/dist/_test/mocks.d.ts +9 -0
  4. package/dist/_test/mocks.js +27 -0
  5. package/dist/_test/mocks.js.map +1 -0
  6. package/dist/_test/request-scope-test-utils.d.ts +3 -0
  7. package/dist/_test/request-scope-test-utils.js +18 -0
  8. package/dist/_test/request-scope-test-utils.js.map +1 -0
  9. package/dist/auth/auth-user.model.d.ts +9 -0
  10. package/dist/auth/auth-user.model.js +33 -0
  11. package/dist/auth/auth-user.model.js.map +1 -0
  12. package/dist/auth/auth.callbacks.d.ts +8 -0
  13. package/dist/auth/auth.callbacks.js +5 -0
  14. package/dist/auth/auth.callbacks.js.map +1 -0
  15. package/dist/auth/auth.configurer.d.ts +35 -0
  16. package/dist/auth/auth.configurer.js +212 -0
  17. package/dist/auth/auth.configurer.js.map +1 -0
  18. package/dist/auth/auth.controller.d.ts +27 -0
  19. package/dist/auth/auth.controller.js +312 -0
  20. package/dist/auth/auth.controller.js.map +1 -0
  21. package/dist/auth/auth.guard.d.ts +16 -0
  22. package/dist/auth/auth.guard.js +127 -0
  23. package/dist/auth/auth.guard.js.map +1 -0
  24. package/dist/auth/auth.listener.d.ts +5 -0
  25. package/dist/auth/auth.listener.js +5 -0
  26. package/dist/auth/auth.listener.js.map +1 -0
  27. package/dist/auth/auth.repository.d.ts +52 -0
  28. package/dist/auth/auth.repository.js +79 -0
  29. package/dist/auth/auth.repository.js.map +1 -0
  30. package/dist/auth/auth.resolver.d.ts +13 -0
  31. package/dist/auth/auth.resolver.js +86 -0
  32. package/dist/auth/auth.resolver.js.map +1 -0
  33. package/dist/auth/auth.service.d.ts +35 -0
  34. package/dist/auth/auth.service.js +299 -0
  35. package/dist/auth/auth.service.js.map +1 -0
  36. package/dist/auth/auth.task.controller.d.ts +13 -0
  37. package/dist/auth/auth.task.controller.js +76 -0
  38. package/dist/auth/auth.task.controller.js.map +1 -0
  39. package/dist/auth/auth.task.service.d.ts +8 -0
  40. package/dist/auth/auth.task.service.js +26 -0
  41. package/dist/auth/auth.task.service.js.map +1 -0
  42. package/dist/auth/csrf.interceptor.d.ts +11 -0
  43. package/dist/auth/csrf.interceptor.js +38 -0
  44. package/dist/auth/csrf.interceptor.js.map +1 -0
  45. package/dist/auth/invite-user.service.d.ts +45 -0
  46. package/dist/auth/invite-user.service.js +215 -0
  47. package/dist/auth/invite-user.service.js.map +1 -0
  48. package/dist/auth/invite.callbacks.d.ts +6 -0
  49. package/dist/auth/invite.callbacks.js +5 -0
  50. package/dist/auth/invite.callbacks.js.map +1 -0
  51. package/dist/auth/login-identifier.repository.d.ts +13 -0
  52. package/dist/auth/login-identifier.repository.js +28 -0
  53. package/dist/auth/login-identifier.repository.js.map +1 -0
  54. package/dist/auth/password-reset.service.d.ts +15 -0
  55. package/dist/auth/password-reset.service.js +81 -0
  56. package/dist/auth/password-reset.service.js.map +1 -0
  57. package/dist/auth/user.service.d.ts +27 -0
  58. package/dist/auth/user.service.js +94 -0
  59. package/dist/auth/user.service.js.map +1 -0
  60. package/dist/configuration.d.ts +84 -0
  61. package/dist/configuration.js +5 -0
  62. package/dist/configuration.js.map +1 -0
  63. package/dist/configure.d.ts +40 -0
  64. package/dist/configure.js +85 -0
  65. package/dist/configure.js.map +1 -0
  66. package/dist/context/context-middleware.d.ts +15 -0
  67. package/dist/context/context-middleware.js +37 -0
  68. package/dist/context/context-middleware.js.map +1 -0
  69. package/dist/context/context-request-scope.d.ts +8 -0
  70. package/dist/context/context-request-scope.js +29 -0
  71. package/dist/context/context-request-scope.js.map +1 -0
  72. package/dist/context/index.d.ts +2 -0
  73. package/dist/context/index.js +9 -0
  74. package/dist/context/index.js.map +1 -0
  75. package/dist/datastore/context.d.ts +36 -0
  76. package/dist/datastore/context.js +27 -0
  77. package/dist/datastore/context.js.map +1 -0
  78. package/dist/datastore/datastore.provider.d.ts +8 -0
  79. package/dist/datastore/datastore.provider.js +30 -0
  80. package/dist/datastore/datastore.provider.js.map +1 -0
  81. package/dist/datastore/filters.d.ts +19 -0
  82. package/dist/datastore/filters.js +27 -0
  83. package/dist/datastore/filters.js.map +1 -0
  84. package/dist/datastore/loader.d.ts +50 -0
  85. package/dist/datastore/loader.js +147 -0
  86. package/dist/datastore/loader.js.map +1 -0
  87. package/dist/datastore/node-datastore-session.d.ts +17 -0
  88. package/dist/datastore/node-datastore-session.js +87 -0
  89. package/dist/datastore/node-datastore-session.js.map +1 -0
  90. package/dist/datastore/repository.d.ts +45 -0
  91. package/dist/datastore/repository.js +150 -0
  92. package/dist/datastore/repository.js.map +1 -0
  93. package/dist/datastore/transactional.d.ts +4 -0
  94. package/dist/datastore/transactional.js +13 -0
  95. package/dist/datastore/transactional.js.map +1 -0
  96. package/dist/error/NonFatalError.d.ts +3 -0
  97. package/dist/error/NonFatalError.js +11 -0
  98. package/dist/error/NonFatalError.js.map +1 -0
  99. package/dist/filter.d.ts +5 -0
  100. package/dist/filter.js +40 -0
  101. package/dist/filter.js.map +1 -0
  102. package/dist/gcloud/logging.d.ts +1 -0
  103. package/dist/gcloud/logging.js +5 -0
  104. package/dist/gcloud/logging.js.map +1 -0
  105. package/dist/gcloud/storage.provider.d.ts +12 -0
  106. package/dist/gcloud/storage.provider.js +41 -0
  107. package/dist/gcloud/storage.provider.js.map +1 -0
  108. package/dist/gcloud/tasks.d.ts +10 -0
  109. package/dist/gcloud/tasks.js +68 -0
  110. package/dist/gcloud/tasks.js.map +1 -0
  111. package/dist/graphql/GraphQLMiddleware.d.ts +0 -0
  112. package/dist/graphql/GraphQLMiddleware.js +2 -0
  113. package/dist/graphql/GraphQLMiddleware.js.map +1 -0
  114. package/dist/index.d.ts +28 -0
  115. package/dist/index.js +65 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/logging/index.d.ts +1 -0
  118. package/dist/logging/index.js +8 -0
  119. package/dist/logging/index.js.map +1 -0
  120. package/dist/logging/logging-internal.d.ts +2 -0
  121. package/dist/logging/logging-internal.js +20 -0
  122. package/dist/logging/logging-internal.js.map +1 -0
  123. package/dist/logging/logging-request-scope.d.ts +15 -0
  124. package/dist/logging/logging-request-scope.js +39 -0
  125. package/dist/logging/logging-request-scope.js.map +1 -0
  126. package/dist/logging/logging.d.ts +34 -0
  127. package/dist/logging/logging.js +55 -0
  128. package/dist/logging/logging.js.map +1 -0
  129. package/dist/mail/gmail/gmail.configurer.d.ts +15 -0
  130. package/dist/mail/gmail/gmail.configurer.js +59 -0
  131. package/dist/mail/gmail/gmail.configurer.js.map +1 -0
  132. package/dist/mail/gmail/gmail.controller.d.ts +9 -0
  133. package/dist/mail/gmail/gmail.controller.js +62 -0
  134. package/dist/mail/gmail/gmail.controller.js.map +1 -0
  135. package/dist/mail/gmail/gmail.sender.d.ts +12 -0
  136. package/dist/mail/gmail/gmail.sender.js +62 -0
  137. package/dist/mail/gmail/gmail.sender.js.map +1 -0
  138. package/dist/mail/gmail/stored.credentials.repository.d.ts +12 -0
  139. package/dist/mail/gmail/stored.credentials.repository.js +23 -0
  140. package/dist/mail/gmail/stored.credentials.repository.js.map +1 -0
  141. package/dist/mail/mail-logging.sender.d.ts +9 -0
  142. package/dist/mail/mail-logging.sender.js +42 -0
  143. package/dist/mail/mail-logging.sender.js.map +1 -0
  144. package/dist/mail/mail-subject.sender.d.ts +12 -0
  145. package/dist/mail/mail-subject.sender.js +33 -0
  146. package/dist/mail/mail-subject.sender.js.map +1 -0
  147. package/dist/mail/mail-whitelist.sender.d.ts +14 -0
  148. package/dist/mail/mail-whitelist.sender.js +59 -0
  149. package/dist/mail/mail-whitelist.sender.js.map +1 -0
  150. package/dist/mail/mail.diverter.d.ts +13 -0
  151. package/dist/mail/mail.diverter.js +62 -0
  152. package/dist/mail/mail.diverter.js.map +1 -0
  153. package/dist/mail/mail.sender.d.ts +6 -0
  154. package/dist/mail/mail.sender.js +5 -0
  155. package/dist/mail/mail.sender.js.map +1 -0
  156. package/dist/mail/smtp/smtp.sender.d.ts +10 -0
  157. package/dist/mail/smtp/smtp.sender.js +65 -0
  158. package/dist/mail/smtp/smtp.sender.js.map +1 -0
  159. package/dist/mail-templates/base.d.ts +2 -0
  160. package/dist/mail-templates/base.js +328 -0
  161. package/dist/mail-templates/base.js.map +1 -0
  162. package/dist/mail-templates/invite.d.ts +1 -0
  163. package/dist/mail-templates/invite.js +19 -0
  164. package/dist/mail-templates/invite.js.map +1 -0
  165. package/dist/module.d.ts +16 -0
  166. package/dist/module.js +136 -0
  167. package/dist/module.js.map +1 -0
  168. package/dist/request-scope/index.d.ts +2 -0
  169. package/dist/request-scope/index.js +9 -0
  170. package/dist/request-scope/index.js.map +1 -0
  171. package/dist/request-scope/request-scope-interceptor.d.ts +5 -0
  172. package/dist/request-scope/request-scope-interceptor.js +3 -0
  173. package/dist/request-scope/request-scope-interceptor.js.map +1 -0
  174. package/dist/request-scope/request-scope.d.ts +12 -0
  175. package/dist/request-scope/request-scope.js +79 -0
  176. package/dist/request-scope/request-scope.js.map +1 -0
  177. package/dist/request-scope/request-scope.middleware.d.ts +15 -0
  178. package/dist/request-scope/request-scope.middleware.js +53 -0
  179. package/dist/request-scope/request-scope.middleware.js.map +1 -0
  180. package/dist/search/search.service.d.ts +52 -0
  181. package/dist/search/search.service.js +90 -0
  182. package/dist/search/search.service.js.map +1 -0
  183. package/dist/search/searchable.repository.d.ts +36 -0
  184. package/dist/search/searchable.repository.js +95 -0
  185. package/dist/search/searchable.repository.js.map +1 -0
  186. package/dist/types.d.ts +3 -0
  187. package/dist/types.js +9 -0
  188. package/dist/types.js.map +1 -0
  189. package/dist/util/arrays.d.ts +1 -0
  190. package/dist/util/arrays.js +10 -0
  191. package/dist/util/arrays.js.map +1 -0
  192. package/dist/util/guards.d.ts +1 -0
  193. package/dist/util/guards.js +7 -0
  194. package/dist/util/guards.js.map +1 -0
  195. package/dist/util/index.d.ts +1 -0
  196. package/dist/util/index.js +5 -0
  197. package/dist/util/index.js.map +1 -0
  198. package/dist/util/nestjs.d.ts +9 -0
  199. package/dist/util/nestjs.js +9 -0
  200. package/dist/util/nestjs.js.map +1 -0
  201. package/dist/util/types.d.ts +4 -0
  202. package/dist/util/types.js +8 -0
  203. package/dist/util/types.js.map +1 -0
  204. package/dist/validator.d.ts +1 -0
  205. package/dist/validator.js +5 -0
  206. package/dist/validator.js.map +1 -0
  207. package/package.json +8 -6
  208. package/server-start.js +1 -72
  209. package/bitbucket-pipelines.yml +0 -15
  210. package/gae-node-nestjs.code-workspace +0 -7
  211. package/gae-node-nestjs.iml +0 -9
  212. package/mondomob-gae-node-nestjs-12.0.0-alpha-1.tgz +0 -0
  213. package/mondomob-gae-node-nestjs-12.0.0-alpha-2.tgz +0 -0
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var RequestScopeMiddleware_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.RequestScopeMiddleware = exports.REQUEST_SCOPE_INTERCEPTORS = exports._REQUEST_STORAGE_NAMESPACE_KEY = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const cls_hooked_1 = require("cls-hooked");
7
+ const common_1 = require("@nestjs/common");
8
+ const logging_internal_1 = require("../logging/logging-internal");
9
+ const configuration_1 = require("../configuration");
10
+ exports._REQUEST_STORAGE_NAMESPACE_KEY = '_GAE_NODE_NESTJS_REQUEST_STORAGE';
11
+ exports.REQUEST_SCOPE_INTERCEPTORS = 'REQ_SCOPE_INTERCEPTORS';
12
+ let RequestScopeMiddleware = RequestScopeMiddleware_1 = class RequestScopeMiddleware {
13
+ constructor(configurationProvider, interceptors) {
14
+ var _a;
15
+ this.interceptors = interceptors;
16
+ RequestScopeMiddleware_1.enabled = !!((_a = configurationProvider.requestScope) === null || _a === void 0 ? void 0 : _a.enabled);
17
+ if (RequestScopeMiddleware_1.enabled) {
18
+ this.namespace = (0, cls_hooked_1.createNamespace)(exports._REQUEST_STORAGE_NAMESPACE_KEY);
19
+ const interceptorNames = interceptors.map(interceptor => ` - ${interceptor.name}`).join('\n');
20
+ logging_internal_1.defaultLogger.info(`RequestScopeMiddleware setup up with interceptors: \n${interceptorNames}`);
21
+ }
22
+ else {
23
+ logging_internal_1.defaultLogger.info('RequestScopeMiddleware disabled by config');
24
+ }
25
+ }
26
+ use(req, res, next) {
27
+ if (this.namespace) {
28
+ this.namespace.run(() => {
29
+ this.interceptors.forEach(interceptor => {
30
+ interceptor.intercept(req);
31
+ });
32
+ next();
33
+ });
34
+ }
35
+ else {
36
+ next();
37
+ }
38
+ }
39
+ static isEnabled() {
40
+ return RequestScopeMiddleware_1.enabled;
41
+ }
42
+ static isDisabled() {
43
+ return !RequestScopeMiddleware_1.isEnabled();
44
+ }
45
+ };
46
+ exports.RequestScopeMiddleware = RequestScopeMiddleware;
47
+ exports.RequestScopeMiddleware = RequestScopeMiddleware = RequestScopeMiddleware_1 = tslib_1.__decorate([
48
+ (0, common_1.Injectable)(),
49
+ tslib_1.__param(0, (0, common_1.Inject)(configuration_1.CONFIGURATION)),
50
+ tslib_1.__param(1, (0, common_1.Inject)(exports.REQUEST_SCOPE_INTERCEPTORS)),
51
+ tslib_1.__metadata("design:paramtypes", [Object, Array])
52
+ ], RequestScopeMiddleware);
53
+ //# sourceMappingURL=request-scope.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-scope.middleware.js","sourceRoot":"","sources":["../../src/request-scope/request-scope.middleware.ts"],"names":[],"mappings":";;;;;AAAA,2CAAwD;AACxD,2CAAoE;AAGpE,kEAA4D;AAC5D,oDAAgE;AAEnD,QAAA,8BAA8B,GAAG,kCAAkC,CAAC;AACpE,QAAA,0BAA0B,GAAG,wBAAwB,CAAC;AAG5D,IAAM,sBAAsB,8BAA5B,MAAM,sBAAsB;IAIjC,YACyB,qBAAoC,EACN,YAAuC;;QAAvC,iBAAY,GAAZ,YAAY,CAA2B;QAG5F,wBAAsB,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA,MAAA,qBAAqB,CAAC,YAAY,0CAAE,OAAO,CAAA,CAAC;QAC/E,IAAI,wBAAsB,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS,GAAG,IAAA,4BAAe,EAAC,sCAA8B,CAAC,CAAC;YACjE,MAAM,gBAAgB,GAAG,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChG,gCAAa,CAAC,IAAI,CAAC,wDAAwD,gBAAgB,EAAE,CAAC,CAAC;QACjG,CAAC;aAAM,CAAC;YACN,gCAAa,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAgB;QAC/C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;gBACtB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;oBACtC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBAC7B,CAAC,CAAC,CAAC;gBACH,IAAI,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,EAAE,CAAC;QACT,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAS;QACd,OAAO,wBAAsB,CAAC,OAAO,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,UAAU;QACf,OAAO,CAAC,wBAAsB,CAAC,SAAS,EAAE,CAAC;IAC7C,CAAC;CACF,CAAA;AAvCY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;IAMR,mBAAA,IAAA,eAAM,EAAC,6BAAa,CAAC,CAAA;IACrB,mBAAA,IAAA,eAAM,EAAC,kCAA0B,CAAC,CAAA;;GAN1B,sBAAsB,CAuClC"}
@@ -0,0 +1,52 @@
1
+ import fetch from 'node-fetch';
2
+ import { Configuration } from '../configuration';
3
+ interface IndexEntry {
4
+ id: string;
5
+ fields: {
6
+ [key: string]: object;
7
+ };
8
+ }
9
+ export interface Sort {
10
+ field: string;
11
+ descending?: boolean;
12
+ }
13
+ export interface Page {
14
+ limit: number;
15
+ offset: number;
16
+ }
17
+ export interface QueryResults {
18
+ resultCount: number;
19
+ limit: number;
20
+ offset: number;
21
+ ids: string[];
22
+ }
23
+ export interface SearchResults<T> {
24
+ resultCount: number;
25
+ limit: number;
26
+ offset: number;
27
+ results: ReadonlyArray<T> | undefined;
28
+ }
29
+ export declare type Operator = '=' | '!=' | '>' | '<' | '>=' | '<=';
30
+ export interface SearchFields {
31
+ [key: string]: string | string[] | Predicate | Predicate[];
32
+ }
33
+ export interface Predicate {
34
+ op: Operator;
35
+ value: string | string[] | number | Date;
36
+ }
37
+ export interface SearchPredicate extends Predicate {
38
+ field: string;
39
+ }
40
+ export declare class SearchService {
41
+ private readonly configuration;
42
+ private logger;
43
+ constructor(configuration: Configuration);
44
+ index(entityName: string, entries: IndexEntry[]): Promise<fetch.Response>;
45
+ delete(entityName: string, ...ids: string[]): Promise<fetch.Response>;
46
+ deleteAll(entityName: string): Promise<fetch.Response>;
47
+ query(entityName: string, fields: SearchFields, sort?: Sort, page?: Page): Promise<QueryResults>;
48
+ private post;
49
+ private normaliseFields;
50
+ private toSearchPredicate;
51
+ }
52
+ export {};
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SearchService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const node_fetch_1 = require("node-fetch");
7
+ const logging_1 = require("../logging");
8
+ const configuration_1 = require("../configuration");
9
+ const isPredicate = (value) => {
10
+ return value.op !== undefined;
11
+ };
12
+ const isPredicateArray = (value) => {
13
+ return Array.isArray(value) && value.length > 0 && isPredicate(value[0]);
14
+ };
15
+ let SearchService = class SearchService {
16
+ constructor(configuration) {
17
+ this.configuration = configuration;
18
+ this.logger = (0, logging_1.createLogger)('search-service');
19
+ }
20
+ index(entityName, entries) {
21
+ this.logger.info(`Indexing ${entries.length} ${entityName} entities`);
22
+ return this.post('/index', {
23
+ entityName,
24
+ entries,
25
+ });
26
+ }
27
+ delete(entityName, ...ids) {
28
+ return this.post('/delete', {
29
+ entityName,
30
+ ids,
31
+ });
32
+ }
33
+ deleteAll(entityName) {
34
+ return this.post('/deleteAll', {
35
+ entityName,
36
+ });
37
+ }
38
+ async query(entityName, fields, sort, page) {
39
+ const resp = await this.post('/query', {
40
+ entityName,
41
+ fields: this.normaliseFields(fields),
42
+ sort,
43
+ page,
44
+ });
45
+ const queryResults = await resp.json();
46
+ this.logger.info(`Query returned ${queryResults.ids.length} ids of total ${queryResults.resultCount}`);
47
+ return queryResults;
48
+ }
49
+ post(path, body) {
50
+ if (!this.configuration.searchServiceEndpoint) {
51
+ throw new Error('searchServiceEndpoint must be configured in order to use the SearchService');
52
+ }
53
+ return (0, node_fetch_1.default)(this.configuration.searchServiceEndpoint + path, {
54
+ method: 'POST',
55
+ body: JSON.stringify(body),
56
+ });
57
+ }
58
+ normaliseFields(fields) {
59
+ return Object.keys(fields).reduce((result, key) => {
60
+ const field = fields[key];
61
+ if (isPredicateArray(field)) {
62
+ field.forEach(predicate => result.push(this.toSearchPredicate(key, predicate)));
63
+ }
64
+ else {
65
+ result.push(this.toSearchPredicate(key, field));
66
+ }
67
+ return result;
68
+ }, []);
69
+ }
70
+ toSearchPredicate(fieldName, input) {
71
+ return isPredicate(input)
72
+ ? {
73
+ field: fieldName,
74
+ op: input.op,
75
+ value: input.value,
76
+ }
77
+ : {
78
+ field: fieldName,
79
+ op: '=',
80
+ value: input,
81
+ };
82
+ }
83
+ };
84
+ exports.SearchService = SearchService;
85
+ exports.SearchService = SearchService = tslib_1.__decorate([
86
+ (0, common_1.Injectable)(),
87
+ tslib_1.__param(0, (0, common_1.Inject)(configuration_1.CONFIGURATION)),
88
+ tslib_1.__metadata("design:paramtypes", [Object])
89
+ ], SearchService);
90
+ //# sourceMappingURL=search.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.service.js","sourceRoot":"","sources":["../../src/search/search.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { Datastore } from '@google-cloud/datastore';
2
+ import * as t from 'io-ts';
3
+ import { Context } from '../datastore/context';
4
+ import { Index } from '../datastore/loader';
5
+ import { Repository, RepositoryOptions } from '../datastore/repository';
6
+ import { Omit } from '../util/types';
7
+ import { Page, SearchFields, SearchResults, SearchService, Sort } from './search.service';
8
+ interface SearchableRepositoryOptions<T extends {
9
+ id: any;
10
+ }> extends RepositoryOptions<T> {
11
+ searchIndex: Index<Omit<T, 'id'>>;
12
+ }
13
+ export declare class SearchableRepository<T extends {
14
+ id: string;
15
+ }> extends Repository<T> {
16
+ protected readonly searchService: SearchService;
17
+ protected readonly options: SearchableRepositoryOptions<T>;
18
+ private baseLogger;
19
+ constructor(datastore: Datastore, searchService: SearchService, kind: string, validator: t.Type<T>, options: SearchableRepositoryOptions<T>);
20
+ save(context: Context, entities: T): Promise<T>;
21
+ save(context: Context, entities: ReadonlyArray<T>): Promise<ReadonlyArray<T>>;
22
+ update(context: Context, entities: T): Promise<T>;
23
+ update(context: Context, entities: ReadonlyArray<T>): Promise<ReadonlyArray<T>>;
24
+ insert(context: Context, entities: T): Promise<T>;
25
+ insert(context: Context, entities: ReadonlyArray<T>): Promise<ReadonlyArray<T>>;
26
+ upsert(context: Context, entities: T): Promise<T>;
27
+ upsert(context: Context, entities: ReadonlyArray<T>): Promise<ReadonlyArray<T>>;
28
+ delete(context: Context, ...ids: string[]): Promise<void>;
29
+ deleteAll(context: Context): Promise<void>;
30
+ search(context: Context, searchFields: SearchFields, sort?: Sort): Promise<readonly T[]>;
31
+ searchWithPagination(context: Context, searchFields: SearchFields, sort?: Sort, page?: Page): Promise<SearchResults<T>>;
32
+ reindex(context: Context, operation?: (input: T) => T | Promise<T>): Promise<readonly T[]>;
33
+ private index;
34
+ private fetchResults;
35
+ }
36
+ export {};
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SearchableRepository = void 0;
4
+ const repository_1 = require("../datastore/repository");
5
+ const types_1 = require("../util/types");
6
+ const logging_1 = require("../logging");
7
+ class SearchableRepository extends repository_1.Repository {
8
+ constructor(datastore, searchService, kind, validator, options) {
9
+ super(datastore, kind, validator, options);
10
+ this.searchService = searchService;
11
+ this.options = options;
12
+ this.baseLogger = (0, logging_1.createLogger)('searchable-repository');
13
+ }
14
+ async save(context, entities) {
15
+ const savedEntities = await super.save(context, entities);
16
+ await this.index(savedEntities);
17
+ return savedEntities;
18
+ }
19
+ async update(context, entities) {
20
+ const savedEntities = await super.update(context, entities);
21
+ await this.index(savedEntities);
22
+ return savedEntities;
23
+ }
24
+ async insert(context, entities) {
25
+ const savedEntities = await super.insert(context, entities);
26
+ await this.index(savedEntities);
27
+ return savedEntities;
28
+ }
29
+ async upsert(context, entities) {
30
+ const savedEntities = await super.upsert(context, entities);
31
+ await this.index(savedEntities);
32
+ return savedEntities;
33
+ }
34
+ async delete(context, ...ids) {
35
+ await super.delete(context, ...ids);
36
+ await this.searchService.delete(this.kind, ...ids);
37
+ }
38
+ async deleteAll(context) {
39
+ await super.deleteAll(context);
40
+ await this.searchService.deleteAll(this.kind);
41
+ }
42
+ async search(context, searchFields, sort) {
43
+ const queryResults = await this.searchService.query(this.kind, searchFields, sort);
44
+ const requests = await this.fetchResults(context, queryResults.ids);
45
+ return requests;
46
+ }
47
+ async searchWithPagination(context, searchFields, sort, page) {
48
+ const queryResults = await this.searchService.query(this.kind, searchFields, sort, page);
49
+ const requests = await this.fetchResults(context, queryResults.ids);
50
+ return {
51
+ resultCount: queryResults.resultCount,
52
+ limit: queryResults.limit,
53
+ offset: queryResults.offset,
54
+ results: requests,
55
+ };
56
+ }
57
+ async reindex(context, operation = input => input) {
58
+ const [allEntities] = await this.query(context);
59
+ this.baseLogger.info(`Saving ${allEntities.length} searchable entities`);
60
+ const batchSize = 100;
61
+ const allUpdatedEntities = [];
62
+ for (let i = 0; i < allEntities.length; i += batchSize) {
63
+ const batchOfEntities = allEntities.slice(i, i + batchSize);
64
+ const updatedEntities = await Promise.all(batchOfEntities.map(operation));
65
+ this.baseLogger.info(`Saving batch of ${batchOfEntities.length} updated searchable entities`);
66
+ const batchUpdatedEntities = await this.update(context, updatedEntities);
67
+ allUpdatedEntities.push(...batchUpdatedEntities);
68
+ }
69
+ return allUpdatedEntities;
70
+ }
71
+ index(entities) {
72
+ const entitiesArr = (0, types_1.asArray)(entities);
73
+ const entries = entitiesArr.map((entity) => {
74
+ const fields = Object.keys(this.options.searchIndex).reduce((obj, fieldName) => {
75
+ obj[fieldName] = entity[fieldName];
76
+ return obj;
77
+ }, {});
78
+ return {
79
+ id: entity.id,
80
+ fields,
81
+ };
82
+ });
83
+ return this.searchService.index(this.kind, entries);
84
+ }
85
+ async fetchResults(context, ids) {
86
+ const results = await this.get(context, ids);
87
+ if (results && results.some(result => !result)) {
88
+ this.baseLogger.warn('Search results contained at least one null value - search index likely out of sync with datastore');
89
+ return results.filter(result => !!result);
90
+ }
91
+ return results;
92
+ }
93
+ }
94
+ exports.SearchableRepository = SearchableRepository;
95
+ //# sourceMappingURL=searchable.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchable.repository.js","sourceRoot":"","sources":["../../src/search/searchable.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import * as iots from 'io-ts';
2
+ export * from 'io-ts';
3
+ export declare const nullable: <T>(type: iots.Type<T>) => iots.UnionC<[iots.Type<T, T, unknown>, iots.NullC]>;
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nullable = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const iots = require("io-ts");
6
+ tslib_1.__exportStar(require("io-ts"), exports);
7
+ const nullable = (type) => iots.union([type, iots.null]);
8
+ exports.nullable = nullable;
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;;AAAA,8BAA8B;AAG9B,gDAAsB;AACf,MAAM,QAAQ,GAAG,CAAI,IAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAApE,QAAA,QAAQ,YAA4D"}
@@ -0,0 +1 @@
1
+ export declare const unique: <T>(src: T[] | ReadonlyArray<T>, ...newValues: T[]) => T[];
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unique = void 0;
4
+ const unique = (src, ...newValues) => {
5
+ const set = new Set(src);
6
+ newValues.forEach(val => set.add(val));
7
+ return Array.from(set);
8
+ };
9
+ exports.unique = unique;
10
+ //# sourceMappingURL=arrays.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrays.js","sourceRoot":"","sources":["../../src/util/arrays.ts"],"names":[],"mappings":";;;AAAO,MAAM,MAAM,GAAG,CAAI,GAA2B,EAAE,GAAG,SAAc,EAAO,EAAE;IAC/E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC,CAAC;AAJW,QAAA,MAAM,UAIjB"}
@@ -0,0 +1 @@
1
+ export declare const isEmpty: <T>(value: T | null | undefined) => value is null | undefined;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEmpty = void 0;
4
+ const _ = require("lodash");
5
+ const isEmpty = (value) => _.isEmpty(value);
6
+ exports.isEmpty = isEmpty;
7
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/util/guards.ts"],"names":[],"mappings":";;;AAAA,4BAA4B;AAErB,MAAM,OAAO,GAAG,CAAI,KAA2B,EAA6B,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAA1F,QAAA,OAAO,WAAmF"}
@@ -0,0 +1 @@
1
+ export * from './nestjs';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./nestjs"), exports);
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":";;;AAAA,mDAAyB"}
@@ -0,0 +1,9 @@
1
+ import { ExecutionContext } from '@nestjs/common';
2
+ import { Request } from 'express';
3
+ import { Context } from '../datastore/context';
4
+ interface RequestWithSessionAndContext extends Request {
5
+ session: any;
6
+ context: Context;
7
+ }
8
+ export declare const getRequestFromExecutionContext: (context: ExecutionContext) => RequestWithSessionAndContext;
9
+ export {};
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRequestFromExecutionContext = void 0;
4
+ const graphql_1 = require("@nestjs/graphql");
5
+ const getRequestFromExecutionContext = (context) => (context.getType() === 'graphql'
6
+ ? graphql_1.GqlExecutionContext.create(context).getContext().request
7
+ : context.switchToHttp().getRequest());
8
+ exports.getRequestFromExecutionContext = getRequestFromExecutionContext;
9
+ //# sourceMappingURL=nestjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestjs.js","sourceRoot":"","sources":["../../src/util/nestjs.ts"],"names":[],"mappings":";;;AAEA,6CAAsE;AAW/D,MAAM,8BAA8B,GAAG,CAAC,OAAyB,EAAgC,EAAE,CACxG,CAAC,OAAO,CAAC,OAAO,EAAkB,KAAK,SAAS;IAC9C,CAAC,CAAC,6BAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,EAAW,CAAC,OAAO;IACnE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAiC,CAAC;AAH9D,QAAA,8BAA8B,kCAGgC"}
@@ -0,0 +1,4 @@
1
+ export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
2
+ export type OneOrMany<T> = T | ReadonlyArray<T>;
3
+ export declare const asArray: <T>(input: OneOrMany<T>) => Array<T>;
4
+ export declare const asPromise: <T>(src: T | Promise<T>) => Promise<T>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asPromise = exports.asArray = void 0;
4
+ const asArray = (input) => (Array.isArray(input) ? input : [input]);
5
+ exports.asArray = asArray;
6
+ const asPromise = (src) => (src instanceof Promise ? src : Promise.resolve(src));
7
+ exports.asPromise = asPromise;
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/util/types.ts"],"names":[],"mappings":";;;AAGO,MAAM,OAAO,GAAG,CAAI,KAAmB,EAAY,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAa,CAAC;AAArG,QAAA,OAAO,WAA8F;AAE3G,MAAM,SAAS,GAAG,CAAI,GAAmB,EAAc,EAAE,CAAC,CAAC,GAAG,YAAY,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAA1G,QAAA,SAAS,aAAiG"}
@@ -0,0 +1 @@
1
+ export * from 'io-ts';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("io-ts"), exports);
5
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":";;;AAGA,gDAAsB"}
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@mondomob/gae-node-nestjs",
3
- "version": "12.0.0-alpha-2",
3
+ "version": "12.0.0-alpha1",
4
4
  "description": "Google App Engine datastore repositories and graphql setup with nestjs",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
7
10
  "scripts": {
8
11
  "prepublish": "npx tsc && npm run verify",
9
12
  "test": "jest",
@@ -28,7 +31,7 @@
28
31
  "@google-cloud/logging-bunyan": "5.1.0",
29
32
  "@google-cloud/storage": "7.19.0",
30
33
  "@google-cloud/tasks": "4.1.0",
31
- "@google-cloud/trace-agent": "7.1.2",
34
+ "@google-cloud/trace-agent": "8.0.0",
32
35
  "@node-saml/passport-saml": "5.1.0",
33
36
  "@types/node-fetch": "2.6.11",
34
37
  "bcryptjs": "2.4.3",
@@ -47,9 +50,9 @@
47
50
  "io-ts": "2.2.21",
48
51
  "io-ts-reporters": "2.0.1",
49
52
  "jsonwebtoken": "9.0.2",
50
- "lodash": "4.17.21",
53
+ "lodash": "4.18.1",
51
54
  "node-fetch": "2.7.0",
52
- "nodemailer": "6.9.15",
55
+ "nodemailer": "10.1.1",
53
56
  "passport": "0.6.0",
54
57
  "passport-auth0": "1.4.4",
55
58
  "passport-google-oauth": "2.0.0",
@@ -83,14 +86,13 @@
83
86
  "@types/jest": "^29.5.12",
84
87
  "@types/jsonwebtoken": "9.0.6",
85
88
  "@types/lodash": "4.17.7",
86
- "@types/nodemailer": "6.4.15",
87
89
  "@types/passport": "1.0.16",
88
90
  "@types/passport-auth0": "1.0.9",
89
91
  "@types/passport-google-oauth": "1.0.45",
90
92
  "@types/passport-local": "1.0.38",
91
93
  "@types/uuid": "8.3.4",
92
94
  "chokidar": "3.6.0",
93
- "express": "4.22.1",
95
+ "express": "4.22.2",
94
96
  "jest": "29.7.0",
95
97
  "prettier": "2.8.8",
96
98
  "rxjs": "7.8.1",
package/server-start.js CHANGED
@@ -21,7 +21,6 @@ const componentColors = {
21
21
  server: colors.blue,
22
22
  webpack: colors.magenta,
23
23
  datastore: colors.cyan,
24
- dsui: colors.green,
25
24
  };
26
25
 
27
26
  class BunyanStream {
@@ -46,17 +45,15 @@ const { buildEvents, stopWebpack } = setupWebpack(logger);
46
45
  const { stopServer, startServer } = setupServer(logger, loggingStream, buildEvents);
47
46
 
48
47
  const { stopDatastore, startDatastore } = setupDatastore(logger, buildEvents);
49
- const { startDsui, stopDsui } = setupDsui(logger);
50
48
 
51
49
  buildEvents.once('reload', startServer);
52
50
  startDatastore();
53
- startDsui();
54
51
 
55
52
  // Handle process stop
56
53
  process.on('SIGINT', async function () {
57
54
  logger.info('Caught interrupt signal');
58
55
 
59
- await Promise.all([stopWebpack(), stopDatastore(), stopDsui(), stopServer()]);
56
+ await Promise.all([stopWebpack(), stopDatastore(), stopServer()]);
60
57
 
61
58
  logger.info('Shutting down');
62
59
  process.exit();
@@ -232,74 +229,6 @@ function setupServer(logger, loggingStream, buildEvents) {
232
229
  };
233
230
  }
234
231
 
235
- function setupDsui(logger) {
236
- const dsuiLogger = logger.child({ component: 'dsui' });
237
- let dsui;
238
- const startDsui = () => {
239
- // poll the status URL until the datastore emulator is ready
240
- dsuiLogger.info('Waiting for Datastore emulator to start');
241
- const timeout = setInterval(() => {
242
- let body = '';
243
- http.get(
244
- {
245
- hostname: '127.0.0.1',
246
- port: DATASTORE_PORT,
247
- path: '/',
248
- agent: false,
249
- },
250
- res => {
251
- res.on('data', data => {
252
- body += data;
253
- });
254
- res.on('end', () => {
255
- if (res.statusCode == 200) {
256
- dsuiLogger.info('Datastore emulator is ready, starting DSUI');
257
- clearInterval(timeout);
258
- const gcloud = spawn('gcloud', ['beta', 'emulators', 'datastore', 'env-init', '--format=json']);
259
- gcloud.stdout.on('data', data => {
260
- const datastoreConfig = JSON.parse(data);
261
- _.forEach(datastoreConfig, (value, key) => {
262
- process.env[key] = value;
263
- });
264
- });
265
-
266
- gcloud.once('close', () => {
267
- dsui = spawn('npm', ['run', 'dsui']);
268
- dsui.stdout.on('data', dsuiData => {
269
- const string = dsuiData.toString('utf8');
270
- dsuiLogger.info(string);
271
- });
272
-
273
- dsui.stderr.on('data', dsuiData => {
274
- const string = dsuiData.toString('utf8');
275
- dsuiLogger.error(string);
276
- });
277
- });
278
- }
279
- });
280
- },
281
- );
282
- }, 2000);
283
- };
284
-
285
- const stopDsui = () => {
286
- return new Promise(resolve => {
287
- if (dsui) {
288
- dsuiLogger.info('Killing DSUI');
289
- dsui.kill('SIGINT');
290
- dsui.once('close', () => {
291
- logger.info('DSUI successfully shutdown');
292
- resolve();
293
- });
294
- } else {
295
- resolve();
296
- }
297
- });
298
- };
299
-
300
- return { startDsui, stopDsui };
301
- }
302
-
303
232
  function setupDatastore(logger, buildEvents) {
304
233
  const datastoreLogger = logger.child({
305
234
  component: 'datastore',
@@ -1,15 +0,0 @@
1
- # This is a sample build configuration for JavaScript.
2
- # Check our guides at https://confluence.atlassian.com/x/14UWN for more examples.
3
- # Only use spaces to indent your .yml configuration.
4
- # -----
5
- # You can specify a custom docker image from Docker Hub as your build environment.
6
- image: node:6.9.4
7
-
8
- pipelines:
9
- default:
10
- - step:
11
- caches:
12
- - node
13
- script: # Modify the commands below to build your repository.
14
- - npm install
15
- - npx tsc