@opra/core 0.0.5

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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/cjs/constants.js +5 -0
  4. package/cjs/decorators/entity-resource.decorator.js +24 -0
  5. package/cjs/enums/http-headers.enum.js +393 -0
  6. package/cjs/enums/http-status.enum.js +300 -0
  7. package/cjs/enums/index.js +5 -0
  8. package/cjs/enums/issue-severity.enum.js +2 -0
  9. package/cjs/exception/api-exception.js +63 -0
  10. package/cjs/exception/errors/bad-request.error.js +22 -0
  11. package/cjs/exception/errors/failed-dependency.error.js +21 -0
  12. package/cjs/exception/errors/forbidden.error.js +23 -0
  13. package/cjs/exception/errors/internal-server.error.js +21 -0
  14. package/cjs/exception/errors/method-not-allowed.error.js +22 -0
  15. package/cjs/exception/errors/not-found.error.js +25 -0
  16. package/cjs/exception/errors/unauthorized.error.js +22 -0
  17. package/cjs/exception/errors/unprocessable-entity.error.js +21 -0
  18. package/cjs/exception/index.js +11 -0
  19. package/cjs/implementation/adapter/adapter.js +72 -0
  20. package/cjs/implementation/adapter/express-adapter.js +93 -0
  21. package/cjs/implementation/adapter/http-adapter.js +262 -0
  22. package/cjs/implementation/data-type/complex-type.js +39 -0
  23. package/cjs/implementation/data-type/data-type.js +35 -0
  24. package/cjs/implementation/data-type/entity-type.js +33 -0
  25. package/cjs/implementation/data-type/simple-type.js +30 -0
  26. package/cjs/implementation/execution-context.js +49 -0
  27. package/cjs/implementation/opra-document.js +116 -0
  28. package/cjs/implementation/opra-service.js +59 -0
  29. package/cjs/implementation/resource/container-resource-controller.js +26 -0
  30. package/cjs/implementation/resource/entity-resource-info.js +68 -0
  31. package/cjs/implementation/resource/resource-info.js +24 -0
  32. package/cjs/implementation/schema-generator.js +173 -0
  33. package/cjs/index.js +25 -0
  34. package/cjs/interfaces/entity-resource.interface.js +2 -0
  35. package/cjs/interfaces/execution-query.interface.js +190 -0
  36. package/cjs/interfaces/http-context.interface.js +2 -0
  37. package/cjs/interfaces/opra-schema.metadata.js +2 -0
  38. package/cjs/interfaces/resource-container.interface.js +2 -0
  39. package/cjs/package.json +3 -0
  40. package/cjs/services/data-service.js +9 -0
  41. package/cjs/services/json-data-service.js +15 -0
  42. package/cjs/types.js +2 -0
  43. package/cjs/utils/class-utils.js +37 -0
  44. package/cjs/utils/headers.js +58 -0
  45. package/cjs/utils/internal-data-types.js +44 -0
  46. package/cjs/utils/responsive-object.js +49 -0
  47. package/cjs/utils/string-path-to-object-tree.js +26 -0
  48. package/cjs/utils/terminal-utils.js +7 -0
  49. package/esm/constants.d.ts +2 -0
  50. package/esm/constants.js +2 -0
  51. package/esm/decorators/entity-resource.decorator.d.ts +5 -0
  52. package/esm/decorators/entity-resource.decorator.js +19 -0
  53. package/esm/enums/http-headers.enum.d.ts +368 -0
  54. package/esm/enums/http-headers.enum.js +390 -0
  55. package/esm/enums/http-status.enum.d.ts +290 -0
  56. package/esm/enums/http-status.enum.js +297 -0
  57. package/esm/enums/index.d.ts +2 -0
  58. package/esm/enums/index.js +2 -0
  59. package/esm/enums/issue-severity.enum.d.ts +1 -0
  60. package/esm/enums/issue-severity.enum.js +1 -0
  61. package/esm/exception/api-exception.d.ts +38 -0
  62. package/esm/exception/api-exception.js +59 -0
  63. package/esm/exception/errors/bad-request.error.d.ts +9 -0
  64. package/esm/exception/errors/bad-request.error.js +18 -0
  65. package/esm/exception/errors/failed-dependency.error.d.ts +8 -0
  66. package/esm/exception/errors/failed-dependency.error.js +17 -0
  67. package/esm/exception/errors/forbidden.error.d.ts +10 -0
  68. package/esm/exception/errors/forbidden.error.js +19 -0
  69. package/esm/exception/errors/internal-server.error.d.ts +8 -0
  70. package/esm/exception/errors/internal-server.error.js +17 -0
  71. package/esm/exception/errors/method-not-allowed.error.d.ts +9 -0
  72. package/esm/exception/errors/method-not-allowed.error.js +18 -0
  73. package/esm/exception/errors/not-found.error.d.ts +12 -0
  74. package/esm/exception/errors/not-found.error.js +21 -0
  75. package/esm/exception/errors/unauthorized.error.d.ts +9 -0
  76. package/esm/exception/errors/unauthorized.error.js +18 -0
  77. package/esm/exception/errors/unprocessable-entity.error.d.ts +8 -0
  78. package/esm/exception/errors/unprocessable-entity.error.js +17 -0
  79. package/esm/exception/index.d.ts +8 -0
  80. package/esm/exception/index.js +8 -0
  81. package/esm/implementation/adapter/adapter.d.ts +18 -0
  82. package/esm/implementation/adapter/adapter.js +68 -0
  83. package/esm/implementation/adapter/express-adapter.d.ts +12 -0
  84. package/esm/implementation/adapter/express-adapter.js +89 -0
  85. package/esm/implementation/adapter/http-adapter.d.ts +27 -0
  86. package/esm/implementation/adapter/http-adapter.js +258 -0
  87. package/esm/implementation/data-type/complex-type.d.ts +18 -0
  88. package/esm/implementation/data-type/complex-type.js +35 -0
  89. package/esm/implementation/data-type/data-type.d.ts +15 -0
  90. package/esm/implementation/data-type/data-type.js +31 -0
  91. package/esm/implementation/data-type/entity-type.d.ts +10 -0
  92. package/esm/implementation/data-type/entity-type.js +29 -0
  93. package/esm/implementation/data-type/simple-type.d.ts +15 -0
  94. package/esm/implementation/data-type/simple-type.js +26 -0
  95. package/esm/implementation/execution-context.d.ts +42 -0
  96. package/esm/implementation/execution-context.js +43 -0
  97. package/esm/implementation/opra-document.d.ts +26 -0
  98. package/esm/implementation/opra-document.js +111 -0
  99. package/esm/implementation/opra-service.d.ts +19 -0
  100. package/esm/implementation/opra-service.js +55 -0
  101. package/esm/implementation/resource/container-resource-controller.d.ts +12 -0
  102. package/esm/implementation/resource/container-resource-controller.js +22 -0
  103. package/esm/implementation/resource/entity-resource-info.d.ts +24 -0
  104. package/esm/implementation/resource/entity-resource-info.js +63 -0
  105. package/esm/implementation/resource/resource-info.d.ts +10 -0
  106. package/esm/implementation/resource/resource-info.js +20 -0
  107. package/esm/implementation/schema-generator.d.ts +21 -0
  108. package/esm/implementation/schema-generator.js +169 -0
  109. package/esm/index.d.ts +22 -0
  110. package/esm/index.js +22 -0
  111. package/esm/interfaces/entity-resource.interface.d.ts +9 -0
  112. package/esm/interfaces/entity-resource.interface.js +1 -0
  113. package/esm/interfaces/execution-query.interface.d.ts +102 -0
  114. package/esm/interfaces/execution-query.interface.js +186 -0
  115. package/esm/interfaces/http-context.interface.d.ts +23 -0
  116. package/esm/interfaces/http-context.interface.js +1 -0
  117. package/esm/interfaces/opra-schema.metadata.d.ts +14 -0
  118. package/esm/interfaces/opra-schema.metadata.js +1 -0
  119. package/esm/interfaces/resource-container.interface.d.ts +6 -0
  120. package/esm/interfaces/resource-container.interface.js +1 -0
  121. package/esm/services/data-service.d.ts +2 -0
  122. package/esm/services/data-service.js +5 -0
  123. package/esm/services/json-data-service.d.ts +9 -0
  124. package/esm/services/json-data-service.js +10 -0
  125. package/esm/types.d.ts +11 -0
  126. package/esm/types.js +1 -0
  127. package/esm/utils/class-utils.d.ts +6 -0
  128. package/esm/utils/class-utils.js +30 -0
  129. package/esm/utils/headers.d.ts +9 -0
  130. package/esm/utils/headers.js +55 -0
  131. package/esm/utils/internal-data-types.d.ts +4 -0
  132. package/esm/utils/internal-data-types.js +41 -0
  133. package/esm/utils/responsive-object.d.ts +3 -0
  134. package/esm/utils/responsive-object.js +45 -0
  135. package/esm/utils/string-path-to-object-tree.d.ts +4 -0
  136. package/esm/utils/string-path-to-object-tree.js +22 -0
  137. package/esm/utils/terminal-utils.d.ts +4 -0
  138. package/esm/utils/terminal-utils.js +4 -0
  139. package/package.json +77 -0
@@ -0,0 +1,169 @@
1
+ import { isPromise } from 'util/types';
2
+ import { DATATYPE_METADATA, DATATYPE_PROPERTIES, OpraSchema } from '@opra/schema';
3
+ import { RESOURCE_METADATA } from '../constants.js';
4
+ import { isConstructor, resolveClassAsync } from '../utils/class-utils.js';
5
+ import { builtinClassMap, internalDataTypes, primitiveDataTypeNames } from '../utils/internal-data-types.js';
6
+ const entityMethods = ['search', 'create', 'read', 'update', 'updateMany', 'delete', 'deleteMany'];
7
+ export class SchemaGenerator {
8
+ _dataTypes = {};
9
+ _resources = {};
10
+ constructor() {
11
+ //
12
+ }
13
+ async addDataType(thunk) {
14
+ let schema;
15
+ thunk = isPromise(thunk) ? await thunk : thunk;
16
+ if (typeof thunk === 'function' && !isConstructor(thunk))
17
+ thunk = await thunk();
18
+ if (!isConstructor(thunk) || OpraSchema.isDataType(thunk))
19
+ throw new TypeError(`Function must return a type class or type schema`);
20
+ if (isConstructor(thunk)) {
21
+ const ctor = thunk;
22
+ const metadata = Reflect.getOwnMetadata(DATATYPE_METADATA, ctor);
23
+ if (!metadata)
24
+ throw new TypeError(`Class "${ctor}" has no type metadata`);
25
+ schema = this._dataTypes[metadata.name];
26
+ if (schema) {
27
+ if (schema.kind !== metadata.kind ||
28
+ (OpraSchema.isComplexType(schema) && schema.ctor !== ctor))
29
+ throw new Error(`An other instance of "${schema.name}" data type previously defined`);
30
+ return schema;
31
+ }
32
+ // Add base data type
33
+ let base;
34
+ let baseCtor = Object.getPrototypeOf(ctor);
35
+ if (Reflect.hasMetadata(DATATYPE_METADATA, baseCtor)) {
36
+ while (!Reflect.hasOwnMetadata(DATATYPE_METADATA, baseCtor)) {
37
+ baseCtor = Object.getPrototypeOf(baseCtor);
38
+ }
39
+ const baseSchema = await this.addDataType(baseCtor);
40
+ base = baseSchema.name;
41
+ }
42
+ if (OpraSchema.isComplexType(metadata) || OpraSchema.isEntityType(metadata)) {
43
+ schema = {
44
+ ...metadata,
45
+ ctor,
46
+ base
47
+ };
48
+ const properties = Reflect.getMetadata(DATATYPE_PROPERTIES, ctor.prototype);
49
+ if (properties) {
50
+ for (const [k, p] of Object.entries(properties)) {
51
+ let type;
52
+ if (isConstructor(p.type) && builtinClassMap.has(p.type))
53
+ type = builtinClassMap.get(p.type);
54
+ else if (typeof p.type === 'function' || typeof p.type === 'object') {
55
+ const t = await this.addDataType(p.type);
56
+ type = t.name;
57
+ }
58
+ else
59
+ type = p.type || 'string';
60
+ if (internalDataTypes.has(type) && !this._dataTypes[type])
61
+ this._dataTypes[type] = internalDataTypes.get(type.toLowerCase());
62
+ schema.properties = schema.properties || {};
63
+ schema.properties[k] = { ...p, type };
64
+ }
65
+ }
66
+ }
67
+ else if (OpraSchema.isSimpleType(metadata)) {
68
+ if (!primitiveDataTypeNames.includes(metadata.type))
69
+ throw new Error(`"type" of SimpleType schema must be one of enumerated value (${primitiveDataTypeNames})`);
70
+ schema = {
71
+ ...metadata
72
+ };
73
+ }
74
+ else
75
+ /* istanbul ignore next */
76
+ throw new TypeError(`Invalid metadata`);
77
+ }
78
+ else if (OpraSchema.isDataType(thunk)) {
79
+ schema = thunk;
80
+ }
81
+ else
82
+ throw new TypeError(`Invalid data type schema`);
83
+ this._dataTypes[schema.name] = schema;
84
+ return schema;
85
+ }
86
+ async addResource(instance) {
87
+ if (isConstructor(instance))
88
+ throw new Error(`You should provide Resource instance instead of Resource class`);
89
+ const proto = Object.getPrototypeOf(instance);
90
+ const ctor = proto.constructor;
91
+ const metadata = Reflect.getMetadata(RESOURCE_METADATA, ctor);
92
+ let resourceSchema;
93
+ if (metadata) {
94
+ const name = metadata.name || ctor.name.replace(/Resource$/, '');
95
+ const t = typeof metadata.type === 'function'
96
+ ? await resolveClassAsync(metadata.type)
97
+ : metadata.type;
98
+ const type = typeof t === 'function'
99
+ ? (await this.addDataType(t)).name
100
+ : t;
101
+ resourceSchema = {
102
+ ...metadata,
103
+ type,
104
+ name
105
+ };
106
+ if (OpraSchema.isEntityResource(resourceSchema)) {
107
+ for (const methodName of entityMethods) {
108
+ const fn = instance[methodName];
109
+ if (typeof fn === 'function') {
110
+ resourceSchema[methodName] = fn.bind(instance);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ else
116
+ resourceSchema = instance;
117
+ if (OpraSchema.isResource(resourceSchema)) {
118
+ if (OpraSchema.isEntityResource(resourceSchema)) {
119
+ const t = this._dataTypes[resourceSchema.type];
120
+ if (!t)
121
+ throw new Error(`Resource registration error. Type "${resourceSchema.type}" not found.`);
122
+ if (this._resources[resourceSchema.name])
123
+ throw new Error(`An other instance of "${resourceSchema.name}" resource previously defined`);
124
+ this._resources[resourceSchema.name] = resourceSchema;
125
+ return;
126
+ }
127
+ throw new Error(`Invalid resource metadata`);
128
+ }
129
+ throw new Error(`Invalid resource object`);
130
+ }
131
+ static async generateDocumentSchema(args) {
132
+ const generator = new SchemaGenerator();
133
+ if (args.types) {
134
+ for (const thunk of args.types) {
135
+ await generator.addDataType(thunk);
136
+ }
137
+ }
138
+ const types = Object.keys(generator._dataTypes).sort()
139
+ .map(name => generator._dataTypes[name]);
140
+ return {
141
+ version: '1',
142
+ ...args,
143
+ types
144
+ };
145
+ }
146
+ static async generateServiceSchema(args) {
147
+ const generator = new SchemaGenerator();
148
+ if (args.types) {
149
+ for (const thunk of args.types) {
150
+ await generator.addDataType(thunk);
151
+ }
152
+ }
153
+ if (args.resources) {
154
+ for (const resource of args.resources) {
155
+ await generator.addResource(resource);
156
+ }
157
+ }
158
+ const types = Object.keys(generator._dataTypes).sort()
159
+ .map(name => generator._dataTypes[name]);
160
+ const resources = Object.keys(generator._resources).sort()
161
+ .map(name => generator._resources[name]);
162
+ return {
163
+ version: '1',
164
+ ...args,
165
+ types,
166
+ resources
167
+ };
168
+ }
169
+ }
package/esm/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import "reflect-metadata";
2
+ export * from './constants.js';
3
+ export * from './types.js';
4
+ export * from './enums/index.js';
5
+ export * from './exception/index.js';
6
+ export * from './decorators/entity-resource.decorator.js';
7
+ export * from './interfaces/http-context.interface.js';
8
+ export * from './interfaces/execution-query.interface.js';
9
+ export * from './interfaces/entity-resource.interface.js';
10
+ export * from './interfaces/resource-container.interface.js';
11
+ export * from './implementation/execution-context.js';
12
+ export * from './implementation/opra-document.js';
13
+ export * from './implementation/opra-service.js';
14
+ export * from './implementation/schema-generator.js';
15
+ export * from './implementation/adapter/adapter.js';
16
+ export * from './implementation/adapter/express-adapter.js';
17
+ export * from './implementation/data-type/data-type.js';
18
+ export * from './implementation/data-type/complex-type.js';
19
+ export * from './implementation/data-type/simple-type.js';
20
+ export * from './implementation/resource/resource-info.js';
21
+ export * from './implementation/resource/entity-resource-info.js';
22
+ export * from './services/json-data-service.js';
package/esm/index.js ADDED
@@ -0,0 +1,22 @@
1
+ import "reflect-metadata";
2
+ export * from './constants.js';
3
+ export * from './types.js';
4
+ export * from './enums/index.js';
5
+ export * from './exception/index.js';
6
+ export * from './decorators/entity-resource.decorator.js';
7
+ export * from './interfaces/http-context.interface.js';
8
+ export * from './interfaces/execution-query.interface.js';
9
+ export * from './interfaces/entity-resource.interface.js';
10
+ export * from './interfaces/resource-container.interface.js';
11
+ export * from './implementation/execution-context.js';
12
+ export * from './implementation/opra-document.js';
13
+ export * from './implementation/opra-service.js';
14
+ export * from './implementation/schema-generator.js';
15
+ export * from './implementation/adapter/adapter.js';
16
+ export * from './implementation/adapter/express-adapter.js';
17
+ export * from './implementation/data-type/data-type.js';
18
+ export * from './implementation/data-type/complex-type.js';
19
+ export * from './implementation/data-type/simple-type.js';
20
+ export * from './implementation/resource/resource-info.js';
21
+ export * from './implementation/resource/entity-resource-info.js';
22
+ export * from './services/json-data-service.js';
@@ -0,0 +1,9 @@
1
+ export interface IEntityResource {
2
+ search?(...args: any[]): any;
3
+ read?(...args: any[]): any;
4
+ create?(...args: any[]): any;
5
+ update?(...args: any[]): any;
6
+ updateMany?(...args: any[]): any;
7
+ delete?(...args: any[]): any;
8
+ deleteMany?(...args: any[]): any;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,102 @@
1
+ import { StrictOmit } from 'ts-gems';
2
+ import { OpraSchema } from '@opra/schema';
3
+ import { Expression } from '@opra/url';
4
+ import { EntityResourceInfo } from '../implementation/resource/entity-resource-info.js';
5
+ import { KeyValue, OperationType, QueryScope, QueryType } from '../types.js';
6
+ export declare type ExecutionQuery = CreateQuery | ReadQuery | SearchQuery | UpdateQuery | UpdateManyQuery | DeleteQuery | DeleteManyQuery;
7
+ interface BaseQuery {
8
+ queryType: QueryType;
9
+ scope: QueryScope;
10
+ operationType: OperationType;
11
+ }
12
+ export interface CreateQuery extends BaseQuery {
13
+ queryType: 'create';
14
+ scope: 'collection';
15
+ operationType: 'create';
16
+ resource: EntityResourceInfo;
17
+ data: {};
18
+ pick?: string[];
19
+ omit?: string[];
20
+ include?: string[];
21
+ }
22
+ export interface ReadQuery extends BaseQuery {
23
+ queryType: 'read';
24
+ scope: 'instance';
25
+ operationType: 'read';
26
+ resource: EntityResourceInfo;
27
+ keyValue: KeyValue;
28
+ pick?: string[];
29
+ omit?: string[];
30
+ include?: string[];
31
+ nested?: PropertyQuery;
32
+ }
33
+ export interface PropertyQuery extends BaseQuery {
34
+ queryType: 'read';
35
+ scope: 'property';
36
+ operationType: 'read';
37
+ property: OpraSchema.Property;
38
+ nested?: PropertyQuery;
39
+ }
40
+ export interface UpdateQuery extends BaseQuery {
41
+ queryType: 'update';
42
+ scope: 'instance';
43
+ operationType: 'update';
44
+ resource: EntityResourceInfo;
45
+ keyValue: KeyValue;
46
+ data: {};
47
+ pick?: string[];
48
+ omit?: string[];
49
+ include?: string[];
50
+ }
51
+ export interface UpdateManyQuery extends BaseQuery {
52
+ queryType: 'updateMany';
53
+ scope: 'collection';
54
+ operationType: 'update';
55
+ resource: EntityResourceInfo;
56
+ filter?: string | Expression;
57
+ data: {};
58
+ }
59
+ export interface DeleteQuery extends BaseQuery {
60
+ queryType: 'delete';
61
+ scope: 'instance';
62
+ operationType: 'delete';
63
+ resource: EntityResourceInfo;
64
+ keyValue: KeyValue;
65
+ }
66
+ export interface DeleteManyQuery extends BaseQuery {
67
+ queryType: 'deleteMany';
68
+ scope: 'collection';
69
+ operationType: 'delete';
70
+ resource: EntityResourceInfo;
71
+ filter?: string | Expression;
72
+ }
73
+ export interface SearchQuery extends BaseQuery {
74
+ queryType: 'search';
75
+ scope: 'collection';
76
+ operationType: 'read';
77
+ resource: EntityResourceInfo;
78
+ pick?: string[];
79
+ omit?: string[];
80
+ include?: string[];
81
+ filter?: string | Expression;
82
+ limit?: number;
83
+ skip?: number;
84
+ distinct?: boolean;
85
+ total?: boolean;
86
+ sort?: string[];
87
+ }
88
+ export declare namespace ExecutionQuery {
89
+ function forCreate(resource: EntityResourceInfo, values: {}, options?: StrictOmit<CreateQuery, 'queryType' | 'scope' | 'operationType' | 'resource' | 'data'>): CreateQuery;
90
+ function forRead(resource: EntityResourceInfo, key: KeyValue, options?: StrictOmit<ReadQuery, 'queryType' | 'scope' | 'operationType' | 'resource' | 'keyValue'>): ReadQuery;
91
+ function forSearch(resource: EntityResourceInfo, options?: StrictOmit<SearchQuery, 'queryType' | 'scope' | 'operationType' | 'resource'>): SearchQuery;
92
+ function forProperty(property: OpraSchema.Property, options?: StrictOmit<PropertyQuery, 'queryType' | 'scope' | 'operationType' | 'property'>): PropertyQuery;
93
+ function forUpdate(resource: EntityResourceInfo, keyValue: KeyValue, values: any, options?: StrictOmit<UpdateQuery, 'queryType' | 'scope' | 'operationType' | 'resource' | 'keyValue' | 'data'>): UpdateQuery;
94
+ function forUpdateMany(resource: EntityResourceInfo, values: any, options?: StrictOmit<UpdateManyQuery, 'queryType' | 'scope' | 'operationType' | 'resource' | 'data'>): UpdateManyQuery;
95
+ function forDelete(resource: EntityResourceInfo, key: KeyValue): DeleteQuery;
96
+ function forDeleteMany(resource: EntityResourceInfo, options?: StrictOmit<DeleteManyQuery, 'queryType' | 'scope' | 'operationType' | 'resource'>): DeleteManyQuery;
97
+ function isCreateQuery(q: any): q is CreateQuery;
98
+ function isSearchQuery(q: any): q is SearchQuery;
99
+ function isReadQuery(q: any): q is ReadQuery;
100
+ function isDeleteQuery(q: any): q is DeleteQuery;
101
+ }
102
+ export {};
@@ -0,0 +1,186 @@
1
+ import _ from 'lodash';
2
+ import { ComplexType } from '../implementation/data-type/complex-type.js';
3
+ import { stringPathToObjectTree } from '../utils/string-path-to-object-tree.js';
4
+ export var ExecutionQuery;
5
+ (function (ExecutionQuery) {
6
+ function forCreate(resource, values, options) {
7
+ if (options?.pick)
8
+ options.pick = normalizePick(resource, options.pick);
9
+ if (options?.omit)
10
+ options.omit = normalizePick(resource, options.omit);
11
+ if (options?.include)
12
+ options.include = normalizePick(resource, options.include);
13
+ const out = {
14
+ queryType: 'create',
15
+ scope: 'collection',
16
+ operationType: 'create',
17
+ resource,
18
+ data: values
19
+ };
20
+ Object.assign(out, _.omit(options, Object.keys(out)));
21
+ return out;
22
+ }
23
+ ExecutionQuery.forCreate = forCreate;
24
+ function forRead(resource, key, options) {
25
+ if (options?.pick)
26
+ options.pick = normalizePick(resource, options.pick);
27
+ if (options?.omit)
28
+ options.omit = normalizePick(resource, options.omit);
29
+ if (options?.include)
30
+ options.include = normalizePick(resource, options.include);
31
+ checkKeyFields(resource, key);
32
+ const out = {
33
+ queryType: 'read',
34
+ scope: 'instance',
35
+ operationType: 'read',
36
+ resource,
37
+ keyValue: key
38
+ };
39
+ Object.assign(out, _.omit(options, Object.keys(out)));
40
+ return out;
41
+ }
42
+ ExecutionQuery.forRead = forRead;
43
+ function forSearch(resource, options) {
44
+ if (options?.pick)
45
+ options.pick = normalizePick(resource, options.pick);
46
+ if (options?.omit)
47
+ options.omit = normalizePick(resource, options.omit);
48
+ if (options?.include)
49
+ options.include = normalizePick(resource, options.include);
50
+ if (options?.sort)
51
+ options.sort = normalizePick(resource, options.sort); // todo check allowed sort fields
52
+ const out = {
53
+ queryType: 'search',
54
+ scope: 'collection',
55
+ operationType: 'read',
56
+ resource
57
+ };
58
+ Object.assign(out, _.omit(options, Object.keys(out)));
59
+ return out;
60
+ }
61
+ ExecutionQuery.forSearch = forSearch;
62
+ function forProperty(property, options) {
63
+ const out = {
64
+ queryType: 'read',
65
+ scope: 'property',
66
+ operationType: 'read',
67
+ property
68
+ };
69
+ Object.assign(out, _.omit(options, Object.keys(out)));
70
+ return out;
71
+ }
72
+ ExecutionQuery.forProperty = forProperty;
73
+ function forUpdate(resource, keyValue, values, options) {
74
+ if (options?.pick)
75
+ options.pick = normalizePick(resource, options.pick);
76
+ if (options?.omit)
77
+ options.omit = normalizePick(resource, options.omit);
78
+ if (options?.include)
79
+ options.include = normalizePick(resource, options.include);
80
+ checkKeyFields(resource, keyValue);
81
+ const out = {
82
+ queryType: 'update',
83
+ scope: 'instance',
84
+ operationType: 'update',
85
+ resource,
86
+ keyValue,
87
+ data: values
88
+ };
89
+ Object.assign(out, _.omit(options, Object.keys(out)));
90
+ return out;
91
+ }
92
+ ExecutionQuery.forUpdate = forUpdate;
93
+ function forUpdateMany(resource, values, options) {
94
+ const out = {
95
+ queryType: 'updateMany',
96
+ scope: 'collection',
97
+ operationType: 'update',
98
+ resource,
99
+ data: values
100
+ };
101
+ Object.assign(out, _.omit(options, Object.keys(out)));
102
+ return out;
103
+ }
104
+ ExecutionQuery.forUpdateMany = forUpdateMany;
105
+ function forDelete(resource, key) {
106
+ checkKeyFields(resource, key);
107
+ return {
108
+ queryType: 'delete',
109
+ scope: 'instance',
110
+ operationType: 'delete',
111
+ resource,
112
+ keyValue: key
113
+ };
114
+ }
115
+ ExecutionQuery.forDelete = forDelete;
116
+ function forDeleteMany(resource, options) {
117
+ const out = {
118
+ queryType: 'deleteMany',
119
+ scope: 'collection',
120
+ operationType: 'delete',
121
+ resource,
122
+ };
123
+ Object.assign(out, _.omit(options, Object.keys(out)));
124
+ return out;
125
+ }
126
+ ExecutionQuery.forDeleteMany = forDeleteMany;
127
+ function isCreateQuery(q) {
128
+ return q && typeof q === 'object' && q.scope === 'collection' && q.queryType === 'create';
129
+ }
130
+ ExecutionQuery.isCreateQuery = isCreateQuery;
131
+ function isSearchQuery(q) {
132
+ return q && typeof q === 'object' && q.scope === 'collection' && q.queryType === 'search';
133
+ }
134
+ ExecutionQuery.isSearchQuery = isSearchQuery;
135
+ function isReadQuery(q) {
136
+ return q && typeof q === 'object' && q.scope === 'instance' && q.queryType === 'read';
137
+ }
138
+ ExecutionQuery.isReadQuery = isReadQuery;
139
+ function isDeleteQuery(q) {
140
+ return q && typeof q === 'object' && q.scope === 'instance' && q.queryType === 'delete';
141
+ }
142
+ ExecutionQuery.isDeleteQuery = isDeleteQuery;
143
+ })(ExecutionQuery || (ExecutionQuery = {}));
144
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
145
+ function checkKeyFields(resource, key) {
146
+ if (!resource.dataType.primaryKey)
147
+ throw new Error(`"${resource.name}" has no primary key`);
148
+ }
149
+ function normalizePick(resource, fields) {
150
+ const fieldsTree = stringPathToObjectTree(fields) || {};
151
+ return _normalizeFieldsList([], resource.service, resource, resource.dataType, fieldsTree, '', {
152
+ additionalProperties: true
153
+ });
154
+ }
155
+ function _normalizeFieldsList(target, service, resource, dataType, node, parentPath = '', options) {
156
+ let curPath = '';
157
+ for (const k of Object.keys(node)) {
158
+ const nodeVal = node[k];
159
+ const prop = dataType?.properties?.[k];
160
+ if (!prop) {
161
+ curPath = parentPath ? parentPath + '.' + k : k;
162
+ if (!options?.additionalProperties || (dataType && !dataType.additionalProperties))
163
+ throw new TypeError(`Unknown field path "${resource.name + '.' + curPath}"`);
164
+ if (typeof nodeVal === 'object')
165
+ _normalizeFieldsList(target, service, resource, undefined, nodeVal, curPath, options);
166
+ else
167
+ target.push(curPath);
168
+ continue;
169
+ }
170
+ curPath = parentPath ? parentPath + '.' + prop.name : prop.name;
171
+ const propType = service.getDataType(prop.type || 'string');
172
+ if (typeof nodeVal === 'object') {
173
+ if (!(propType instanceof ComplexType))
174
+ throw new TypeError(`"${curPath}" is not a complex type and has no sub fields`);
175
+ if (target.findIndex(x => x === parentPath) >= 0)
176
+ continue;
177
+ target = _normalizeFieldsList(target, service, resource, propType, nodeVal, curPath, options);
178
+ continue;
179
+ }
180
+ if (target.findIndex(x => x.startsWith(curPath + '.')) >= 0) {
181
+ target = target.filter(x => !x.startsWith(curPath + '.'));
182
+ }
183
+ target.push(curPath);
184
+ }
185
+ return target;
186
+ }
@@ -0,0 +1,23 @@
1
+ export interface IHttpAdapterContext {
2
+ getRequest(): IHttpRequest;
3
+ getResponse(): IHttpResponse;
4
+ }
5
+ export interface IHttpRequest {
6
+ getInstance(): any;
7
+ getUrl(): string;
8
+ getMethod(): string;
9
+ getHeaderNames(): string[];
10
+ getHeader(name: string): string | undefined;
11
+ getHeaders(): Record<string, any>;
12
+ getBody(): any;
13
+ }
14
+ export interface IHttpResponse {
15
+ getInstance(): any;
16
+ getStatus(): number | undefined;
17
+ setStatus(value: number): this;
18
+ getHeaderNames(name: string): string[];
19
+ getHeader(name: string): string | undefined;
20
+ setHeader(name: string, value: string): this;
21
+ send(body: any): this;
22
+ end(): this;
23
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import { StrictOmit } from 'ts-gems';
2
+ import { OpraSchema } from '@opra/schema';
3
+ import { TypeThunkAsync } from '../types.js';
4
+ export declare type EntityResourceMetadata = StrictOmit<OpraSchema.EntityResource, 'type' | 'name'> & {
5
+ type: TypeThunkAsync | string;
6
+ name?: string;
7
+ };
8
+ export declare type ResourceReadOperationMetadata = StrictOmit<OpraSchema.ResourceReadOperation, 'handler'>;
9
+ export declare type ResourceSearchOperationMetadata = StrictOmit<OpraSchema.ResourceSearchOperation, 'handler'>;
10
+ export declare type ResourceCreateOperationMetadata = StrictOmit<OpraSchema.ResourceCreateOperation, 'handler'>;
11
+ export declare type ResourceUpdateOperationMetadata = StrictOmit<OpraSchema.ResourceUpdateOperation, 'handler'>;
12
+ export declare type ResourcePatchOperationMetadata = StrictOmit<OpraSchema.ResourcePatchOperation, 'handler'>;
13
+ export declare type ResourceDeleteOperationMetadata = StrictOmit<OpraSchema.ResourceDeleteOperation, 'handler'>;
14
+ export declare type ResourceExecuteOperationMetadata = StrictOmit<OpraSchema.ResourceExecuteOperation, 'handler'>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { EntityResourceInfo } from '../implementation/resource/entity-resource-info.js';
2
+ import { ResourceInfo } from '../implementation/resource/resource-info.js';
3
+ export interface IResourceContainer {
4
+ getResource<T extends ResourceInfo>(name: string): T;
5
+ getEntityResource(name: string): EntityResourceInfo;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare abstract class DataService<T = any> {
2
+ }
@@ -0,0 +1,5 @@
1
+ /* eslint-disable */
2
+ // import { Type } from 'ts-gems';
3
+ // import { ComplexType } from '../implementation/data-type/complex-type.js';
4
+ export class DataService {
5
+ }
@@ -0,0 +1,9 @@
1
+ import { DataService } from './data-service.js';
2
+ export interface JsonDataServiceAgs {
3
+ data: any[];
4
+ primaryKey: string | string[];
5
+ }
6
+ export declare class JsonDataService extends DataService {
7
+ data: any[];
8
+ constructor(args: JsonDataServiceAgs);
9
+ }
@@ -0,0 +1,10 @@
1
+ import ruleJudgment from 'rule-judgment';
2
+ import { DataService } from './data-service.js';
3
+ // Fix invalid importing (with ESM) of rule-judgment package
4
+ const toArrayFilter = typeof ruleJudgment === 'function' ? ruleJudgment : ruleJudgment.default;
5
+ export class JsonDataService extends DataService {
6
+ data;
7
+ constructor(args) {
8
+ super();
9
+ }
10
+ }
package/esm/types.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { DeepPartial, DeepPickJson, DeepPickWritable, Type } from 'ts-gems';
2
+ export declare type Thunk<T> = T | (() => T);
3
+ export declare type ThunkAsync<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
4
+ export declare type TypeThunk<T = any> = Thunk<Type<T>>;
5
+ export declare type TypeThunkAsync<T = any> = ThunkAsync<Type<T>>;
6
+ export declare type QueryScope = 'collection' | 'instance' | 'property';
7
+ export declare type QueryType = 'create' | 'read' | 'update' | 'patch' | 'delete' | 'execute' | 'search' | 'updateMany' | 'patchMany' | 'deleteMany';
8
+ export declare type OperationType = 'create' | 'read' | 'update' | 'patch' | 'delete' | 'execute';
9
+ export declare type KeyValue = string | number | boolean | object;
10
+ export declare type PartialInput<T> = DeepPartial<DeepPickWritable<DeepPickJson<T>>>;
11
+ export declare type PartialOutput<T> = DeepPartial<DeepPickJson<T>>;
package/esm/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { Type } from 'ts-gems';
2
+ import { TypeThunk, TypeThunkAsync } from '../types.js';
3
+ export declare function isConstructor(obj: any): obj is Type;
4
+ export declare function resolveClass<T>(typeOrFunc: TypeThunk<T>): Type<T>;
5
+ export declare function resolveClassAsync<T>(typeOrFunc: TypeThunkAsync<T>): Promise<Type<T>>;
6
+ export declare function isInternalClass(t: any): boolean;
@@ -0,0 +1,30 @@
1
+ const knownInternalClasses = [String, Number, Boolean, Date];
2
+ export function isConstructor(obj) {
3
+ return typeof obj === 'function' &&
4
+ !!(obj.prototype && obj.prototype.constructor);
5
+ }
6
+ export function resolveClass(typeOrFunc) {
7
+ if (typeof typeOrFunc === 'function' && !isConstructor(typeOrFunc)) {
8
+ typeOrFunc = typeOrFunc();
9
+ if (isConstructor(typeOrFunc))
10
+ return typeOrFunc;
11
+ throw new TypeError(`Function must return a constructor`);
12
+ }
13
+ if (isConstructor(typeOrFunc))
14
+ return typeOrFunc;
15
+ throw new TypeError(`${typeOrFunc} is not a constructor`);
16
+ }
17
+ export async function resolveClassAsync(typeOrFunc) {
18
+ if (typeof typeOrFunc === 'function' && !isConstructor(typeOrFunc)) {
19
+ typeOrFunc = await typeOrFunc();
20
+ if (isConstructor(typeOrFunc))
21
+ return typeOrFunc;
22
+ throw new TypeError(`Function must return a constructor`);
23
+ }
24
+ if (isConstructor(typeOrFunc))
25
+ return typeOrFunc;
26
+ throw new TypeError(`${typeOrFunc} is not a constructor`);
27
+ }
28
+ export function isInternalClass(t) {
29
+ return knownInternalClasses.includes(t) || Buffer.isBuffer(t);
30
+ }