@opra/common 0.20.3 → 0.21.0

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 (42) hide show
  1. package/browser.js +295 -402
  2. package/cjs/document/api-document.js +8 -0
  3. package/cjs/document/data-type/mapped-type.js +1 -1
  4. package/cjs/document/data-type/union-type.js +1 -1
  5. package/cjs/document/factory/factory.js +3 -2
  6. package/cjs/document/factory/process-resources.js +22 -7
  7. package/cjs/document/index.js +1 -0
  8. package/cjs/document/resource/storage.js +81 -0
  9. package/cjs/helpers/mixin-utils.js +6 -5
  10. package/cjs/helpers/responsive-map.js +6 -1
  11. package/cjs/http/index.js +0 -1
  12. package/cjs/schema/opra-schema.ns.js +1 -0
  13. package/cjs/schema/resource/storage.interface.js +7 -0
  14. package/cjs/schema/type-guards.js +6 -1
  15. package/esm/document/api-document.js +8 -0
  16. package/esm/document/data-type/mapped-type.js +2 -2
  17. package/esm/document/data-type/union-type.js +2 -2
  18. package/esm/document/factory/factory.js +4 -3
  19. package/esm/document/factory/process-resources.js +18 -4
  20. package/esm/document/index.js +1 -0
  21. package/esm/document/resource/storage.js +77 -0
  22. package/esm/helpers/mixin-utils.js +4 -3
  23. package/esm/helpers/responsive-map.js +6 -1
  24. package/esm/http/index.js +0 -1
  25. package/esm/schema/opra-schema.ns.js +1 -0
  26. package/esm/schema/resource/storage.interface.js +4 -0
  27. package/esm/schema/type-guards.js +4 -0
  28. package/package.json +2 -2
  29. package/types/document/api-document.d.ts +3 -10
  30. package/types/document/factory/factory.d.ts +4 -3
  31. package/types/document/factory/process-resources.d.ts +4 -2
  32. package/types/document/index.d.ts +1 -0
  33. package/types/document/resource/storage.d.ts +44 -0
  34. package/types/helpers/mixin-utils.d.ts +1 -1
  35. package/types/http/index.d.ts +0 -1
  36. package/types/schema/opra-schema.ns.d.ts +1 -0
  37. package/types/schema/resource/resource.interface.d.ts +3 -2
  38. package/types/schema/resource/storage.interface.d.ts +18 -0
  39. package/types/schema/type-guards.d.ts +1 -0
  40. package/cjs/http/http-headers.js +0 -227
  41. package/esm/http/http-headers.js +0 -223
  42. package/types/http/http-headers.d.ts +0 -86
@@ -185,6 +185,14 @@ class ApiDocument {
185
185
  return t;
186
186
  throw new index_js_1.NotAcceptableError(`Resource type "${t.name}" is not a Singleton`);
187
187
  }
188
+ getStorage(path, silent) {
189
+ const t = this.getResource(path);
190
+ if (!t && silent)
191
+ return;
192
+ if (t && t.kind === index_js_3.OpraSchema.Storage.Kind)
193
+ return t;
194
+ throw new index_js_1.NotAcceptableError(`Resource type "${t.name}" is not a Storage`);
195
+ }
188
196
  /**
189
197
  * Export as Opra schema definition object
190
198
  */
@@ -91,7 +91,7 @@ exports.MappedType = function (...args) {
91
91
  (0, index_js_1.inheritPropertyInitializers)(this, source, isInheritedPredicate);
92
92
  }
93
93
  }
94
- (0, index_js_1.applyMixins)(MappedClass, source);
94
+ (0, index_js_1.mergePrototype)(MappedClass.prototype, source.prototype);
95
95
  // const mappedTypeMetadata: MappedType.TypeMapping[] = [];
96
96
  const m = Reflect.getOwnMetadata(constants_js_1.METADATA_KEY, source);
97
97
  if (!m)
@@ -106,7 +106,7 @@ exports.UnionType = function (...args) {
106
106
  itemMeta.kind === index_js_2.OpraSchema.MappedType.Kind)))
107
107
  throw new TypeError(`Class "${c.name}" is not a ${index_js_2.OpraSchema.ComplexType.Kind}, ${index_js_2.OpraSchema.UnionType.Kind} or ${index_js_2.OpraSchema.MappedType.Kind}`);
108
108
  metadata.types.push(c);
109
- (0, index_js_1.applyMixins)(UnionClass, c);
109
+ (0, index_js_1.mergePrototype)(UnionClass.prototype, c.prototype);
110
110
  }
111
111
  exports.UnionType._applyMixin(UnionClass, ...clasRefs);
112
112
  return UnionClass;
@@ -60,6 +60,7 @@ DocumentFactory.designTypeMap = new Map();
60
60
  _a.prototype.extractSingletonSchema = import_resource_class_js_1.extractSingletonSchema;
61
61
  _a.prototype.extractCollectionSchema = import_resource_class_js_1.extractCollectionSchema;
62
62
  _a.prototype.processResourceQueue = process_resources_js_1.processResourceQueue;
63
- _a.prototype.createCollection = process_resources_js_1.createCollection;
64
- _a.prototype.createSingleton = process_resources_js_1.createSingleton;
63
+ _a.prototype.createCollectionResource = process_resources_js_1.createCollectionResource;
64
+ _a.prototype.createSingletonResource = process_resources_js_1.createSingletonResource;
65
+ _a.prototype.createFileResource = process_resources_js_1.createFileResource;
65
66
  })();
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createSingleton = exports.createCollection = exports.processResourceQueue = void 0;
3
+ exports.createFileResource = exports.createSingletonResource = exports.createCollectionResource = exports.processResourceQueue = void 0;
4
4
  const index_js_1 = require("../../schema/index.js");
5
5
  const collection_js_1 = require("../resource/collection.js");
6
6
  const singleton_js_1 = require("../resource/singleton.js");
7
+ const storage_js_1 = require("../resource/storage.js");
7
8
  async function processResourceQueue() {
8
9
  const { document, resourceQueue } = this;
9
10
  const resourceNames = Array.from(resourceQueue.keys());
@@ -13,12 +14,17 @@ async function processResourceQueue() {
13
14
  continue;
14
15
  try {
15
16
  if (index_js_1.OpraSchema.isCollection(schema)) {
16
- const resource = await this.createCollection(name, schema);
17
+ const resource = await this.createCollectionResource(name, schema);
17
18
  document.resources.set(name, resource);
18
19
  continue;
19
20
  }
20
21
  if (index_js_1.OpraSchema.isSingleton(schema)) {
21
- const resource = await this.createSingleton(name, schema);
22
+ const resource = await this.createSingletonResource(name, schema);
23
+ document.resources.set(name, resource);
24
+ continue;
25
+ }
26
+ if (index_js_1.OpraSchema.isStorage(schema)) {
27
+ const resource = await this.createFileResource(name, schema);
22
28
  document.resources.set(name, resource);
23
29
  continue;
24
30
  }
@@ -31,7 +37,7 @@ async function processResourceQueue() {
31
37
  }
32
38
  }
33
39
  exports.processResourceQueue = processResourceQueue;
34
- async function createCollection(name, schema) {
40
+ async function createCollectionResource(name, schema) {
35
41
  const { document } = this;
36
42
  const dataType = document.getComplexType(schema.type);
37
43
  const initArgs = {
@@ -41,8 +47,8 @@ async function createCollection(name, schema) {
41
47
  };
42
48
  return new collection_js_1.Collection(document, initArgs);
43
49
  }
44
- exports.createCollection = createCollection;
45
- async function createSingleton(name, schema) {
50
+ exports.createCollectionResource = createCollectionResource;
51
+ async function createSingletonResource(name, schema) {
46
52
  const { document } = this;
47
53
  const dataType = document.getComplexType(schema.type);
48
54
  const initArgs = {
@@ -52,4 +58,13 @@ async function createSingleton(name, schema) {
52
58
  };
53
59
  return new singleton_js_1.Singleton(document, initArgs);
54
60
  }
55
- exports.createSingleton = createSingleton;
61
+ exports.createSingletonResource = createSingletonResource;
62
+ async function createFileResource(name, schema) {
63
+ const { document } = this;
64
+ const initArgs = {
65
+ ...schema,
66
+ name
67
+ };
68
+ return new storage_js_1.Storage(document, initArgs);
69
+ }
70
+ exports.createFileResource = createFileResource;
@@ -15,3 +15,4 @@ tslib_1.__exportStar(require("./data-type/union-type.js"), exports);
15
15
  tslib_1.__exportStar(require("./resource/resource.js"), exports);
16
16
  tslib_1.__exportStar(require("./resource/collection.js"), exports);
17
17
  tslib_1.__exportStar(require("./resource/singleton.js"), exports);
18
+ tslib_1.__exportStar(require("./resource/storage.js"), exports);
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Storage = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_omit_1 = tslib_1.__importDefault(require("lodash.omit"));
6
+ const putil_merge_1 = tslib_1.__importDefault(require("putil-merge"));
7
+ const index_js_1 = require("../../helpers/index.js");
8
+ const index_js_2 = require("../../schema/index.js");
9
+ const constants_js_1 = require("../constants.js");
10
+ const resource_js_1 = require("./resource.js");
11
+ const NESTJS_INJECTABLE_WATERMARK = '__injectable__';
12
+ const NAME_PATTERN = /^(.*)(Resource)$/;
13
+ class StorageClass extends resource_js_1.Resource {
14
+ constructor(document, init) {
15
+ super(document, init);
16
+ this.kind = index_js_2.OpraSchema.Storage.Kind;
17
+ this.controller = init.controller;
18
+ const operations = this.operations = init.operations || {};
19
+ if (this.controller) {
20
+ const instance = typeof this.controller == 'function'
21
+ ? new this.controller()
22
+ : this.controller;
23
+ for (const operation of Object.values(operations)) {
24
+ if (!operation.handler && operation.handlerName) {
25
+ const fn = instance[operation.handlerName];
26
+ if (!fn)
27
+ throw new TypeError(`No such operation handler (${operation.handlerName}) found`);
28
+ operation.handler = fn.bind(instance);
29
+ }
30
+ }
31
+ }
32
+ }
33
+ exportSchema() {
34
+ const out = resource_js_1.Resource.prototype.exportSchema.call(this);
35
+ Object.assign(out, (0, index_js_1.omitUndefined)({
36
+ operations: this.operations
37
+ }));
38
+ return out;
39
+ }
40
+ }
41
+ exports.Storage = function (...args) {
42
+ // ClassDecorator
43
+ if (!this) {
44
+ const [options] = args;
45
+ return function (target) {
46
+ const name = options?.name || target.name.match(NAME_PATTERN)?.[1] || target.name;
47
+ const metadata = Reflect.getOwnMetadata(constants_js_1.METADATA_KEY, target) || {};
48
+ metadata.kind = index_js_2.OpraSchema.Storage.Kind;
49
+ metadata.name = name;
50
+ // Merge with previous metadata object
51
+ const m = Reflect.getMetadata(constants_js_1.METADATA_KEY, target);
52
+ if (m && metadata !== m)
53
+ Object.assign(metadata, (0, lodash_omit_1.default)(m), Object.keys(metadata));
54
+ // Merge options
55
+ if (options)
56
+ Object.assign(metadata, (0, lodash_omit_1.default)(options, ['kind', 'name', 'type', 'controller']));
57
+ Reflect.defineMetadata(constants_js_1.METADATA_KEY, metadata, target);
58
+ /* Define Injectable metadata for NestJS support*/
59
+ Reflect.defineMetadata(NESTJS_INJECTABLE_WATERMARK, true, target);
60
+ };
61
+ }
62
+ // Constructor
63
+ const [document, init] = args;
64
+ (0, putil_merge_1.default)(this, new StorageClass(document, init), { descriptor: true });
65
+ };
66
+ exports.Storage.prototype = StorageClass.prototype;
67
+ function createOperationDecorator(operation) {
68
+ return (options) => ((target, propertyKey) => {
69
+ const metadata = {
70
+ ...options,
71
+ handlerName: propertyKey
72
+ };
73
+ const resourceMetadata = (Reflect.getOwnMetadata(constants_js_1.METADATA_KEY, target.constructor) || {});
74
+ resourceMetadata.operations = resourceMetadata.operations || {};
75
+ resourceMetadata.operations[operation] = metadata;
76
+ Reflect.defineMetadata(constants_js_1.METADATA_KEY, resourceMetadata, target.constructor);
77
+ });
78
+ }
79
+ exports.Storage.Delete = createOperationDecorator('delete');
80
+ exports.Storage.Get = createOperationDecorator('get');
81
+ exports.Storage.Put = createOperationDecorator('put');
@@ -1,16 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.inheritPropertyInitializers = exports.applyMixins = void 0;
4
- function applyMixins(derivedCtor, baseCtor, filter) {
5
- for (const k of Object.getOwnPropertyNames(baseCtor.prototype)) {
3
+ exports.inheritPropertyInitializers = exports.mergePrototype = void 0;
4
+ function mergePrototype(targetProto, baseProto, filter) {
5
+ for (const k of Object.getOwnPropertyNames(baseProto)) {
6
6
  if ((k === 'constructor' || k === '__proto__' || k === 'toJSON' || k === 'toString') ||
7
7
  filter && !filter(k))
8
8
  continue;
9
- Object.defineProperty(derivedCtor.prototype, k, Object.getOwnPropertyDescriptor(baseCtor.prototype, k) ||
9
+ Object.defineProperty(targetProto, k, Object.getOwnPropertyDescriptor(baseProto, k) ||
10
10
  Object.create(null));
11
11
  }
12
12
  }
13
- exports.applyMixins = applyMixins;
13
+ exports.mergePrototype = mergePrototype;
14
+ // noinspection JSUnusedLocalSymbols
14
15
  function inheritPropertyInitializers(target, sourceClass,
15
16
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
16
17
  isPropertyInherited = (key) => true) {
@@ -98,7 +98,12 @@ class ResponsiveMap extends Map {
98
98
  return super.delete(orgKey);
99
99
  }
100
100
  sort(compareFn) {
101
- this[kKeyOrder].sort(compareFn);
101
+ if (compareFn)
102
+ this[kKeyOrder].sort(compareFn);
103
+ else if (this[kOptions].caseSensitive)
104
+ this[kKeyOrder].sort();
105
+ else
106
+ this[kKeyOrder].sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
102
107
  return this;
103
108
  }
104
109
  getProxy(handler) {
package/cjs/http/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./http-headers.js"), exports);
5
4
  tslib_1.__exportStar(require("./http-params.js"), exports);
6
5
  tslib_1.__exportStar(require("./enums/http-headers-codes.enum.js"), exports);
7
6
  tslib_1.__exportStar(require("./enums/http-status-codes.enum.js"), exports);
@@ -13,6 +13,7 @@ tslib_1.__exportStar(require("./resource/container.interface.js"), exports);
13
13
  tslib_1.__exportStar(require("./resource/endpoint.interface.js"), exports);
14
14
  tslib_1.__exportStar(require("./resource/resource.interface.js"), exports);
15
15
  tslib_1.__exportStar(require("./resource/singleton.interface.js"), exports);
16
+ tslib_1.__exportStar(require("./resource/storage.interface.js"), exports);
16
17
  tslib_1.__exportStar(require("./constants.js"), exports);
17
18
  tslib_1.__exportStar(require("./document.interface.js"), exports);
18
19
  tslib_1.__exportStar(require("./type-guards.js"), exports);
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Storage = void 0;
4
+ var Storage;
5
+ (function (Storage) {
6
+ Storage.Kind = 'Storage';
7
+ })(Storage || (exports.Storage = Storage = {}));
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isContainer = exports.isSingleton = exports.isCollection = exports.isResource = exports.isEnumType = exports.isMappedType = exports.isUnionType = exports.isSimpleType = exports.isComplexType = exports.isDataType = void 0;
3
+ exports.isContainer = exports.isStorage = exports.isSingleton = exports.isCollection = exports.isResource = exports.isEnumType = exports.isMappedType = exports.isUnionType = exports.isSimpleType = exports.isComplexType = exports.isDataType = void 0;
4
4
  const complex_type_interface_js_1 = require("./data-type/complex-type.interface.js");
5
5
  const enum_type_interface_js_1 = require("./data-type/enum-type.interface.js");
6
6
  const mapped_type_interface_js_1 = require("./data-type/mapped-type.interface.js");
@@ -9,6 +9,7 @@ const union_type_interface_js_1 = require("./data-type/union-type.interface.js")
9
9
  const collection_interface_js_1 = require("./resource/collection.interface.js");
10
10
  const container_interface_js_1 = require("./resource/container.interface.js");
11
11
  const singleton_interface_js_1 = require("./resource/singleton.interface.js");
12
+ const storage_interface_js_1 = require("./resource/storage.interface.js");
12
13
  function isDataType(obj) {
13
14
  return obj && typeof obj === 'object' &&
14
15
  (obj.kind === complex_type_interface_js_1.ComplexType.Kind ||
@@ -53,6 +54,10 @@ function isSingleton(obj) {
53
54
  return obj && typeof obj === 'object' && obj.kind === singleton_interface_js_1.Singleton.Kind;
54
55
  }
55
56
  exports.isSingleton = isSingleton;
57
+ function isStorage(obj) {
58
+ return obj && typeof obj === 'object' && obj.kind === storage_interface_js_1.Storage.Kind;
59
+ }
60
+ exports.isStorage = isStorage;
56
61
  function isContainer(obj) {
57
62
  return obj && typeof obj === 'object' && obj.kind === container_interface_js_1.Container.Kind;
58
63
  }
@@ -182,6 +182,14 @@ export class ApiDocument {
182
182
  return t;
183
183
  throw new NotAcceptableError(`Resource type "${t.name}" is not a Singleton`);
184
184
  }
185
+ getStorage(path, silent) {
186
+ const t = this.getResource(path);
187
+ if (!t && silent)
188
+ return;
189
+ if (t && t.kind === OpraSchema.Storage.Kind)
190
+ return t;
191
+ throw new NotAcceptableError(`Resource type "${t.name}" is not a Storage`);
192
+ }
185
193
  /**
186
194
  * Export as Opra schema definition object
187
195
  */
@@ -1,7 +1,7 @@
1
1
  import 'reflect-metadata';
2
2
  import merge from 'putil-merge';
3
3
  import * as vg from 'valgen';
4
- import { applyMixins, inheritPropertyInitializers, omitUndefined, ResponsiveMap } from '../../helpers/index.js';
4
+ import { inheritPropertyInitializers, mergePrototype, omitUndefined, ResponsiveMap } from '../../helpers/index.js';
5
5
  import { OpraSchema } from '../../schema/index.js';
6
6
  import { METADATA_KEY } from '../constants.js';
7
7
  import { DataType } from './data-type.js';
@@ -87,7 +87,7 @@ export const MappedType = function (...args) {
87
87
  inheritPropertyInitializers(this, source, isInheritedPredicate);
88
88
  }
89
89
  }
90
- applyMixins(MappedClass, source);
90
+ mergePrototype(MappedClass.prototype, source.prototype);
91
91
  // const mappedTypeMetadata: MappedType.TypeMapping[] = [];
92
92
  const m = Reflect.getOwnMetadata(METADATA_KEY, source);
93
93
  if (!m)
@@ -1,7 +1,7 @@
1
1
  import 'reflect-metadata';
2
2
  import merge from 'putil-merge';
3
3
  import * as vg from 'valgen';
4
- import { applyMixins, inheritPropertyInitializers, omitUndefined, ResponsiveMap } from '../../helpers/index.js';
4
+ import { inheritPropertyInitializers, mergePrototype, omitUndefined, ResponsiveMap } from '../../helpers/index.js';
5
5
  import { OpraSchema } from '../../schema/index.js';
6
6
  import { METADATA_KEY } from '../constants.js';
7
7
  import { ComplexType } from './complex-type.js';
@@ -102,7 +102,7 @@ export const UnionType = function (...args) {
102
102
  itemMeta.kind === OpraSchema.MappedType.Kind)))
103
103
  throw new TypeError(`Class "${c.name}" is not a ${OpraSchema.ComplexType.Kind}, ${OpraSchema.UnionType.Kind} or ${OpraSchema.MappedType.Kind}`);
104
104
  metadata.types.push(c);
105
- applyMixins(UnionClass, c);
105
+ mergePrototype(UnionClass.prototype, c.prototype);
106
106
  }
107
107
  UnionType._applyMixin(UnionClass, ...clasRefs);
108
108
  return UnionClass;
@@ -5,7 +5,7 @@ import { addReferences } from './add-references.js';
5
5
  import { createBuiltinTypeDocument, createDocument, createDocumentFromUrl } from './create-document.js';
6
6
  import { extractCollectionSchema, extractSingletonSchema, importResourceClass } from './import-resource-class.js';
7
7
  import { extractComplexTypeSchema, extractEnumTypeSchema, extractFieldSchema, extractMappedTypeSchema, extractSimpleTypeSchema, extractUnionTypeSchema, importTypeClass } from './import-type-class.js';
8
- import { createCollection, createSingleton, processResourceQueue } from './process-resources.js';
8
+ import { createCollectionResource, createFileResource, createSingletonResource, processResourceQueue } from './process-resources.js';
9
9
  import { addDataType, createDataTypeInstance, processTypes } from './process-types.js';
10
10
  /**
11
11
  * @class DocumentFactory
@@ -56,6 +56,7 @@ DocumentFactory.designTypeMap = new Map();
56
56
  _a.prototype.extractSingletonSchema = extractSingletonSchema;
57
57
  _a.prototype.extractCollectionSchema = extractCollectionSchema;
58
58
  _a.prototype.processResourceQueue = processResourceQueue;
59
- _a.prototype.createCollection = createCollection;
60
- _a.prototype.createSingleton = createSingleton;
59
+ _a.prototype.createCollectionResource = createCollectionResource;
60
+ _a.prototype.createSingletonResource = createSingletonResource;
61
+ _a.prototype.createFileResource = createFileResource;
61
62
  })();
@@ -1,6 +1,7 @@
1
1
  import { OpraSchema } from '../../schema/index.js';
2
2
  import { Collection } from '../resource/collection.js';
3
3
  import { Singleton } from '../resource/singleton.js';
4
+ import { Storage } from '../resource/storage.js';
4
5
  export async function processResourceQueue() {
5
6
  const { document, resourceQueue } = this;
6
7
  const resourceNames = Array.from(resourceQueue.keys());
@@ -10,12 +11,17 @@ export async function processResourceQueue() {
10
11
  continue;
11
12
  try {
12
13
  if (OpraSchema.isCollection(schema)) {
13
- const resource = await this.createCollection(name, schema);
14
+ const resource = await this.createCollectionResource(name, schema);
14
15
  document.resources.set(name, resource);
15
16
  continue;
16
17
  }
17
18
  if (OpraSchema.isSingleton(schema)) {
18
- const resource = await this.createSingleton(name, schema);
19
+ const resource = await this.createSingletonResource(name, schema);
20
+ document.resources.set(name, resource);
21
+ continue;
22
+ }
23
+ if (OpraSchema.isStorage(schema)) {
24
+ const resource = await this.createFileResource(name, schema);
19
25
  document.resources.set(name, resource);
20
26
  continue;
21
27
  }
@@ -27,7 +33,7 @@ export async function processResourceQueue() {
27
33
  throw new TypeError(`Invalid Resource schema: ${JSON.stringify(schema).substring(0, 20)}...`);
28
34
  }
29
35
  }
30
- export async function createCollection(name, schema) {
36
+ export async function createCollectionResource(name, schema) {
31
37
  const { document } = this;
32
38
  const dataType = document.getComplexType(schema.type);
33
39
  const initArgs = {
@@ -37,7 +43,7 @@ export async function createCollection(name, schema) {
37
43
  };
38
44
  return new Collection(document, initArgs);
39
45
  }
40
- export async function createSingleton(name, schema) {
46
+ export async function createSingletonResource(name, schema) {
41
47
  const { document } = this;
42
48
  const dataType = document.getComplexType(schema.type);
43
49
  const initArgs = {
@@ -47,3 +53,11 @@ export async function createSingleton(name, schema) {
47
53
  };
48
54
  return new Singleton(document, initArgs);
49
55
  }
56
+ export async function createFileResource(name, schema) {
57
+ const { document } = this;
58
+ const initArgs = {
59
+ ...schema,
60
+ name
61
+ };
62
+ return new Storage(document, initArgs);
63
+ }
@@ -12,3 +12,4 @@ export * from './data-type/union-type.js';
12
12
  export * from './resource/resource.js';
13
13
  export * from './resource/collection.js';
14
14
  export * from './resource/singleton.js';
15
+ export * from './resource/storage.js';
@@ -0,0 +1,77 @@
1
+ import omit from 'lodash.omit';
2
+ import merge from 'putil-merge';
3
+ import { omitUndefined } from '../../helpers/index.js';
4
+ import { OpraSchema } from '../../schema/index.js';
5
+ import { METADATA_KEY } from '../constants.js';
6
+ import { Resource } from './resource.js';
7
+ const NESTJS_INJECTABLE_WATERMARK = '__injectable__';
8
+ const NAME_PATTERN = /^(.*)(Resource)$/;
9
+ class StorageClass extends Resource {
10
+ constructor(document, init) {
11
+ super(document, init);
12
+ this.kind = OpraSchema.Storage.Kind;
13
+ this.controller = init.controller;
14
+ const operations = this.operations = init.operations || {};
15
+ if (this.controller) {
16
+ const instance = typeof this.controller == 'function'
17
+ ? new this.controller()
18
+ : this.controller;
19
+ for (const operation of Object.values(operations)) {
20
+ if (!operation.handler && operation.handlerName) {
21
+ const fn = instance[operation.handlerName];
22
+ if (!fn)
23
+ throw new TypeError(`No such operation handler (${operation.handlerName}) found`);
24
+ operation.handler = fn.bind(instance);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ exportSchema() {
30
+ const out = Resource.prototype.exportSchema.call(this);
31
+ Object.assign(out, omitUndefined({
32
+ operations: this.operations
33
+ }));
34
+ return out;
35
+ }
36
+ }
37
+ export const Storage = function (...args) {
38
+ // ClassDecorator
39
+ if (!this) {
40
+ const [options] = args;
41
+ return function (target) {
42
+ const name = options?.name || target.name.match(NAME_PATTERN)?.[1] || target.name;
43
+ const metadata = Reflect.getOwnMetadata(METADATA_KEY, target) || {};
44
+ metadata.kind = OpraSchema.Storage.Kind;
45
+ metadata.name = name;
46
+ // Merge with previous metadata object
47
+ const m = Reflect.getMetadata(METADATA_KEY, target);
48
+ if (m && metadata !== m)
49
+ Object.assign(metadata, omit(m), Object.keys(metadata));
50
+ // Merge options
51
+ if (options)
52
+ Object.assign(metadata, omit(options, ['kind', 'name', 'type', 'controller']));
53
+ Reflect.defineMetadata(METADATA_KEY, metadata, target);
54
+ /* Define Injectable metadata for NestJS support*/
55
+ Reflect.defineMetadata(NESTJS_INJECTABLE_WATERMARK, true, target);
56
+ };
57
+ }
58
+ // Constructor
59
+ const [document, init] = args;
60
+ merge(this, new StorageClass(document, init), { descriptor: true });
61
+ };
62
+ Storage.prototype = StorageClass.prototype;
63
+ function createOperationDecorator(operation) {
64
+ return (options) => ((target, propertyKey) => {
65
+ const metadata = {
66
+ ...options,
67
+ handlerName: propertyKey
68
+ };
69
+ const resourceMetadata = (Reflect.getOwnMetadata(METADATA_KEY, target.constructor) || {});
70
+ resourceMetadata.operations = resourceMetadata.operations || {};
71
+ resourceMetadata.operations[operation] = metadata;
72
+ Reflect.defineMetadata(METADATA_KEY, resourceMetadata, target.constructor);
73
+ });
74
+ }
75
+ Storage.Delete = createOperationDecorator('delete');
76
+ Storage.Get = createOperationDecorator('get');
77
+ Storage.Put = createOperationDecorator('put');
@@ -1,12 +1,13 @@
1
- export function applyMixins(derivedCtor, baseCtor, filter) {
2
- for (const k of Object.getOwnPropertyNames(baseCtor.prototype)) {
1
+ export function mergePrototype(targetProto, baseProto, filter) {
2
+ for (const k of Object.getOwnPropertyNames(baseProto)) {
3
3
  if ((k === 'constructor' || k === '__proto__' || k === 'toJSON' || k === 'toString') ||
4
4
  filter && !filter(k))
5
5
  continue;
6
- Object.defineProperty(derivedCtor.prototype, k, Object.getOwnPropertyDescriptor(baseCtor.prototype, k) ||
6
+ Object.defineProperty(targetProto, k, Object.getOwnPropertyDescriptor(baseProto, k) ||
7
7
  Object.create(null));
8
8
  }
9
9
  }
10
+ // noinspection JSUnusedLocalSymbols
10
11
  export function inheritPropertyInitializers(target, sourceClass,
11
12
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
12
13
  isPropertyInherited = (key) => true) {
@@ -95,7 +95,12 @@ export class ResponsiveMap extends Map {
95
95
  return super.delete(orgKey);
96
96
  }
97
97
  sort(compareFn) {
98
- this[kKeyOrder].sort(compareFn);
98
+ if (compareFn)
99
+ this[kKeyOrder].sort(compareFn);
100
+ else if (this[kOptions].caseSensitive)
101
+ this[kKeyOrder].sort();
102
+ else
103
+ this[kKeyOrder].sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
99
104
  return this;
100
105
  }
101
106
  getProxy(handler) {
package/esm/http/index.js CHANGED
@@ -1,4 +1,3 @@
1
- export * from './http-headers.js';
2
1
  export * from './http-params.js';
3
2
  export * from './enums/http-headers-codes.enum.js';
4
3
  export * from './enums/http-status-codes.enum.js';
@@ -10,6 +10,7 @@ export * from './resource/container.interface.js';
10
10
  export * from './resource/endpoint.interface.js';
11
11
  export * from './resource/resource.interface.js';
12
12
  export * from './resource/singleton.interface.js';
13
+ export * from './resource/storage.interface.js';
13
14
  export * from './constants.js';
14
15
  export * from './document.interface.js';
15
16
  export * from './type-guards.js';
@@ -0,0 +1,4 @@
1
+ export var Storage;
2
+ (function (Storage) {
3
+ Storage.Kind = 'Storage';
4
+ })(Storage || (Storage = {}));
@@ -6,6 +6,7 @@ import { UnionType } from './data-type/union-type.interface.js';
6
6
  import { Collection } from './resource/collection.interface.js';
7
7
  import { Container } from './resource/container.interface.js';
8
8
  import { Singleton } from './resource/singleton.interface.js';
9
+ import { Storage } from './resource/storage.interface.js';
9
10
  export function isDataType(obj) {
10
11
  return obj && typeof obj === 'object' &&
11
12
  (obj.kind === ComplexType.Kind ||
@@ -41,6 +42,9 @@ export function isCollection(obj) {
41
42
  export function isSingleton(obj) {
42
43
  return obj && typeof obj === 'object' && obj.kind === Singleton.Kind;
43
44
  }
45
+ export function isStorage(obj) {
46
+ return obj && typeof obj === 'object' && obj.kind === Storage.Kind;
47
+ }
44
48
  export function isContainer(obj) {
45
49
  return obj && typeof obj === 'object' && obj.kind === Container.Kind;
46
50
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/common",
3
- "version": "0.20.3",
3
+ "version": "0.21.0",
4
4
  "description": "Opra common package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -47,7 +47,6 @@
47
47
  "@browsery/i18next": "^0.6.0",
48
48
  "fast-tokenizer": "^1.2.2",
49
49
  "lodash.omit": "^4.5.0",
50
- "path-browserify": "^1.0.1",
51
50
  "putil-isplainobject": "^1.1.5",
52
51
  "putil-merge": "^3.10.3",
53
52
  "putil-promisify": "^1.10.0",
@@ -62,6 +61,7 @@
62
61
  "@browsery/util": "^0.4.0",
63
62
  "@types/encodeurl": "^1.0.0",
64
63
  "@types/validator": "^13.7.17",
64
+ "path-browserify": "^1.0.1",
65
65
  "ts-gems": "^2.4.0"
66
66
  },
67
67
  "engines": {
@@ -7,6 +7,7 @@ import { SimpleType } from './data-type/simple-type.js';
7
7
  import type { Collection } from './resource/collection.js';
8
8
  import { Resource } from './resource/resource.js';
9
9
  import { Singleton } from './resource/singleton.js';
10
+ import { Storage } from './resource/storage.js';
10
11
  export declare class ApiDocument {
11
12
  protected _designCtorMap: Map<Function | Type<any>, string>;
12
13
  protected _typeCache: ResponsiveMap<DataType>;
@@ -75,11 +76,6 @@ export declare class ApiDocument {
75
76
  * @param silent
76
77
  */
77
78
  getCollection(path: string, silent: true): Collection | undefined;
78
- /**
79
- * Returns ComplexType instance by name or Constructor.
80
- * Throws error undefined if not found or data type is not a ComplexType
81
- * @param path
82
- */
83
79
  getCollection(path: string): Collection;
84
80
  /**
85
81
  * Returns Singleton resource instance by path
@@ -89,12 +85,9 @@ export declare class ApiDocument {
89
85
  * @param silent
90
86
  */
91
87
  getSingleton(path: string, silent: true): Singleton | undefined;
92
- /**
93
- * Returns ComplexType instance by name or Constructor.
94
- * Throws error undefined if not found or data type is not a ComplexType
95
- * @param path
96
- */
97
88
  getSingleton(path: string): Singleton;
89
+ getStorage(path: string, silent: true): Storage | undefined;
90
+ getStorage(path: string): Storage;
98
91
  /**
99
92
  * Export as Opra schema definition object
100
93
  */