@nymphjs/nymph 1.0.0-beta.8 → 1.0.0-beta.80

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 (65) hide show
  1. package/CHANGELOG.md +376 -0
  2. package/README.md +9 -19
  3. package/dist/Entity.d.ts +269 -7
  4. package/dist/Entity.js +491 -105
  5. package/dist/Entity.js.map +1 -1
  6. package/dist/Entity.test.js +25 -3
  7. package/dist/Entity.test.js.map +1 -1
  8. package/dist/Entity.types.d.ts +225 -19
  9. package/dist/Nymph.d.ts +430 -11
  10. package/dist/Nymph.js +686 -168
  11. package/dist/Nymph.js.map +1 -1
  12. package/dist/Nymph.types.d.ts +65 -7
  13. package/dist/Nymph.types.js +2 -1
  14. package/dist/Nymph.types.js.map +1 -1
  15. package/dist/conf/d.d.ts +30 -0
  16. package/dist/conf/defaults.js +27 -0
  17. package/dist/conf/defaults.js.map +1 -1
  18. package/dist/driver/NymphDriver.d.ts +136 -38
  19. package/dist/driver/NymphDriver.js +264 -131
  20. package/dist/driver/NymphDriver.js.map +1 -1
  21. package/dist/driver/testArtifacts.d.ts +1 -1
  22. package/dist/driver/testArtifacts.js +493 -51
  23. package/dist/driver/testArtifacts.js.map +1 -1
  24. package/dist/errors/EntityInvalidDataError.d.ts +6 -0
  25. package/dist/errors/EntityInvalidDataError.js +7 -1
  26. package/dist/errors/EntityInvalidDataError.js.map +1 -1
  27. package/dist/errors/EntityUniqueConstraintError.d.ts +3 -0
  28. package/dist/errors/EntityUniqueConstraintError.js +11 -0
  29. package/dist/errors/EntityUniqueConstraintError.js.map +1 -0
  30. package/dist/errors/InvalidStateError.d.ts +3 -0
  31. package/dist/errors/InvalidStateError.js +11 -0
  32. package/dist/errors/InvalidStateError.js.map +1 -0
  33. package/dist/errors/QueryFailedError.js +1 -0
  34. package/dist/errors/QueryFailedError.js.map +1 -1
  35. package/dist/errors/index.d.ts +2 -0
  36. package/dist/errors/index.js +2 -0
  37. package/dist/errors/index.js.map +1 -1
  38. package/dist/testArtifacts.d.ts +17 -5
  39. package/dist/testArtifacts.js +31 -27
  40. package/dist/testArtifacts.js.map +1 -1
  41. package/dist/testMocks.d.ts +13 -10
  42. package/dist/testMocks.js +32 -13
  43. package/dist/testMocks.js.map +1 -1
  44. package/dist/utils.d.ts +1 -1
  45. package/dist/utils.js +21 -5
  46. package/dist/utils.js.map +1 -1
  47. package/package.json +16 -14
  48. package/src/Entity.test.ts +22 -5
  49. package/src/Entity.ts +423 -134
  50. package/src/Entity.types.ts +32 -66
  51. package/src/Nymph.ts +609 -176
  52. package/src/Nymph.types.ts +131 -26
  53. package/src/conf/d.ts +12 -0
  54. package/src/conf/defaults.ts +31 -0
  55. package/src/driver/NymphDriver.ts +289 -311
  56. package/src/driver/testArtifacts.ts +562 -181
  57. package/src/errors/EntityUniqueConstraintError.ts +6 -0
  58. package/src/errors/InvalidStateError.ts +6 -0
  59. package/src/errors/index.ts +4 -0
  60. package/src/nymphJoiProps.ts +2 -2
  61. package/src/testArtifacts.ts +18 -19
  62. package/src/testMocks.ts +55 -30
  63. package/src/utils.ts +22 -8
  64. package/tsconfig.json +3 -3
  65. package/typedoc.json +4 -0
@@ -0,0 +1,6 @@
1
+ export class EntityUniqueConstraintError extends Error {
2
+ constructor(message: string) {
3
+ super(message);
4
+ this.name = 'EntityUniqueConstraintError';
5
+ }
6
+ }
@@ -0,0 +1,6 @@
1
+ export class InvalidStateError extends Error {
2
+ constructor(message: string) {
3
+ super(message);
4
+ this.name = 'InvalidStateError';
5
+ }
6
+ }
@@ -6,8 +6,12 @@ export * from './EntityInvalidDataError';
6
6
 
7
7
  export * from './EntityIsSleepingReferenceError';
8
8
 
9
+ export * from './EntityUniqueConstraintError';
10
+
9
11
  export * from './InvalidParametersError';
10
12
 
13
+ export * from './InvalidStateError';
14
+
11
15
  export * from './NotConfiguredError';
12
16
 
13
17
  export * from './QueryFailedError';
@@ -4,7 +4,7 @@ export default {
4
4
  guid: Joi.alternatives()
5
5
  .try(
6
6
  Joi.any().only().allow(null),
7
- Joi.string().trim(false).length(24).hex()
7
+ Joi.string().trim(false).length(24).hex(),
8
8
  )
9
9
  .required(),
10
10
  cdate: Joi.alternatives()
@@ -18,7 +18,7 @@ export default {
18
18
  Joi.string().pattern(/[[\x01-\x1F\x7F]]/, {
19
19
  name: 'control characters',
20
20
  invert: true,
21
- })
21
+ }),
22
22
  )
23
23
  .required(),
24
24
  };
@@ -17,8 +17,10 @@ export type TestModelData = {
17
17
  [k: string]: TestModel & TestModelData;
18
18
  };
19
19
  parent?: TestModel & TestModelData;
20
- // For Import/Export Tests.
20
+ // For import/export tests.
21
21
  index?: string;
22
+ // For uniqueness tests.
23
+ uniques?: string[];
22
24
  };
23
25
 
24
26
  /**
@@ -34,21 +36,16 @@ export class TestModel extends Entity<TestModelData> {
34
36
  protected $protectedTags = ['test', 'notag'];
35
37
  protected $allowlistTags? = ['newtag'];
36
38
 
37
- static async factory(guid?: string): Promise<TestModel & TestModelData> {
38
- return (await super.factory(guid)) as TestModel & TestModelData;
39
- }
39
+ constructor() {
40
+ super();
40
41
 
41
- static factorySync(guid?: string): TestModel & TestModelData {
42
- return super.factorySync(guid) as TestModel & TestModelData;
42
+ this.$addTag('test');
43
+ this.$data.boolean = true;
44
+ this.$data.uniques = [];
43
45
  }
44
46
 
45
- constructor(guid?: string) {
46
- super(guid);
47
-
48
- if (this.guid == null) {
49
- this.$addTag('test');
50
- this.$data.boolean = true;
51
- }
47
+ public async $getUniques() {
48
+ return this.$data.uniques ?? [];
52
49
  }
53
50
 
54
51
  public $useProtectedData() {
@@ -77,12 +74,14 @@ export class TestModel extends Entity<TestModelData> {
77
74
  export class TestBModel extends TestModel {
78
75
  static ETYPE = 'test_b_model';
79
76
  static class = 'TestBModel';
77
+ }
80
78
 
81
- static async factory(guid?: string): Promise<TestBModel & TestModelData> {
82
- return (await super.factory(guid)) as TestBModel & TestModelData;
83
- }
79
+ export type TestEmptyModelData = {};
84
80
 
85
- static factorySync(guid?: string): TestBModel & TestModelData {
86
- return super.factorySync(guid) as TestBModel & TestModelData;
87
- }
81
+ /**
82
+ * This class is a test class that extends the Entity class.
83
+ */
84
+ export class TestEmptyModel extends Entity<TestEmptyModelData> {
85
+ static ETYPE = 'test_empty_model';
86
+ static class = 'TestEmptyModel';
88
87
  }
package/src/testMocks.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  import { guid } from '@nymphjs/guid';
2
2
 
3
3
  import type Nymph from './Nymph';
4
- import { EntityConstructor, EntityInterface, EntityJson } from './Entity.types';
4
+ import type { EntityInstanceType } from './Entity';
5
+ import type {
6
+ EntityConstructor,
7
+ EntityInterface,
8
+ EntityJson,
9
+ } from './Entity.types';
5
10
  import { Options, Selector } from './Nymph.types';
6
11
  import { ClassNotAvailableError } from './errors';
7
12
  import Entity from './Entity';
@@ -15,34 +20,34 @@ export class MockNymphDriver {
15
20
  this.nymph = nymph;
16
21
  }
17
22
 
18
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
23
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
19
24
  options: Options<T> & { return: 'guid' },
20
25
  ...selectors: Selector[]
21
- ): string | null;
22
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
26
+ ): Promise<string | null>;
27
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
23
28
  options: Options<T>,
24
29
  ...selectors: Selector[]
25
- ): ReturnType<T['factorySync']> | null;
26
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
30
+ ): Promise<EntityInstanceType<T> | null>;
31
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
27
32
  options: Options<T> & { return: 'guid' },
28
- guid: string
29
- ): string | null;
30
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
33
+ guid: string,
34
+ ): Promise<string | null>;
35
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
31
36
  options: Options<T>,
32
- guid: string
33
- ): ReturnType<T['factorySync']> | null;
34
- public getEntitySync<T extends EntityConstructor = EntityConstructor>(
37
+ guid: string,
38
+ ): Promise<EntityInstanceType<T> | null>;
39
+ public async getEntity<T extends EntityConstructor = EntityConstructor>(
35
40
  options: Options<T> = {},
36
41
  ...selectors: Selector[] | string[]
37
- ): ReturnType<T['factorySync']> | string | null {
42
+ ): Promise<EntityInstanceType<T> | string | null> {
38
43
  const guid =
39
44
  typeof selectors[0] === 'string' ? selectors[0] : selectors[0].guid;
40
45
  if (!options || !guid || typeof guid !== 'string' || !(guid in entities)) {
41
46
  return null;
42
47
  }
43
48
 
44
- const entity: EntityInterface = (
45
- (options.class as T) ?? this.nymph.getEntityClass('Entity')
49
+ const entity = (
50
+ (options.class ?? this.nymph.getEntityClass('Entity')) as T
46
51
  ).factorySync();
47
52
  const entityJson = entities[guid];
48
53
  entity.guid = guid;
@@ -51,7 +56,7 @@ export class MockNymphDriver {
51
56
  entity.tags = entityJson.tags;
52
57
  entity.$putData(entityJson.data, {});
53
58
 
54
- return entity as ReturnType<T['factorySync']>;
59
+ return entity as EntityInstanceType<T>;
55
60
  }
56
61
  }
57
62
 
@@ -68,24 +73,44 @@ export class MockNymph {
68
73
  this.Entity = this.addEntityClass(Entity);
69
74
  }
70
75
 
71
- public addEntityClass<T extends EntityConstructor>(entityClass: T): T {
76
+ public addEntityClass<T extends EntityConstructor>(EntityClass: T): T {
72
77
  const nymph = this;
73
- class NymphEntity extends entityClass {
78
+ this.entityClasses[EntityClass.class] = class extends EntityClass {
74
79
  static nymph: Nymph = nymph as unknown as Nymph;
75
80
 
76
81
  constructor(...args: any[]) {
77
82
  super(...args);
78
83
  }
84
+ };
85
+ return this.entityClasses[EntityClass.class] as T;
86
+ }
87
+
88
+ public getEntityClass(className: string): EntityConstructor;
89
+ public getEntityClass<T extends EntityConstructor>(className: T): T;
90
+ public getEntityClass<T extends EntityConstructor = EntityConstructor>(
91
+ className: T | string,
92
+ ): T | EntityConstructor {
93
+ let key: string | null = null;
94
+ if (typeof className === 'string') {
95
+ key = className;
96
+ } else {
97
+ key = className.class;
98
+ }
99
+ if (key in this.entityClasses) {
100
+ return this.entityClasses[key];
79
101
  }
80
- this.entityClasses[entityClass.class] = NymphEntity;
81
- return NymphEntity;
102
+ throw new ClassNotAvailableError(`Tried to use missing class "${key}".`);
82
103
  }
83
104
 
84
- public getEntityClass(className: string): EntityConstructor {
85
- if (className in this.entityClasses) {
86
- return this.entityClasses[className];
105
+ public getEntityClassByEtype(etype: string): EntityConstructor {
106
+ for (const EntityClass of Object.values(this.entityClasses)) {
107
+ if (EntityClass.ETYPE === etype) {
108
+ return EntityClass;
109
+ }
87
110
  }
88
- throw new ClassNotAvailableError('Tried to use class: ' + className);
111
+ throw new ClassNotAvailableError(
112
+ `Tried to use missing class by etype "${etype}".`,
113
+ );
89
114
  }
90
115
 
91
116
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
@@ -95,21 +120,21 @@ export class MockNymph {
95
120
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
96
121
  options: Options<T>,
97
122
  ...selectors: Selector[]
98
- ): Promise<ReturnType<T['factorySync']> | null>;
123
+ ): Promise<EntityInstanceType<T> | null>;
99
124
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
100
125
  options: Options<T> & { return: 'guid' },
101
- guid: string
126
+ guid: string,
102
127
  ): Promise<string | null>;
103
128
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
104
129
  options: Options<T>,
105
- guid: string
106
- ): Promise<ReturnType<T['factorySync']> | null>;
130
+ guid: string,
131
+ ): Promise<EntityInstanceType<T> | null>;
107
132
  public async getEntity<T extends EntityConstructor = EntityConstructor>(
108
133
  options: Options<T> = {},
109
134
  ...selectors: Selector[] | string[]
110
- ): Promise<ReturnType<T['factorySync']> | string | null> {
135
+ ): Promise<EntityInstanceType<T> | string | null> {
111
136
  // @ts-ignore: The selector type is correct here.
112
- return this.driver.getEntitySync(options, ...selectors);
137
+ return await this.driver.getEntity(options, ...selectors);
113
138
  }
114
139
 
115
140
  public async saveEntity(entity: EntityInterface): Promise<boolean> {
package/src/utils.ts CHANGED
@@ -17,7 +17,8 @@ export function uniqueStrings(array: string[]) {
17
17
 
18
18
  export function classNamesToEntityConstructors(
19
19
  nymph: Nymph,
20
- selectors: Selector[]
20
+ selectors: Selector[],
21
+ enforceRestEnabledFlag = false,
21
22
  ): Selector[] {
22
23
  const newSelectors: Selector[] = [];
23
24
 
@@ -45,22 +46,35 @@ export function classNamesToEntityConstructors(
45
46
  for (let i = 0; i < tmpArr.length; i++) {
46
47
  const name = tmpArr[i][0];
47
48
  const [qrefOptions, ...selectors] = tmpArr[i][1];
48
- const QrefEntityClass =
49
- typeof qrefOptions.class === 'string'
50
- ? nymph.getEntityClass(qrefOptions.class)
51
- : qrefOptions.class ?? nymph.getEntityClass('Entity');
49
+ const QrefEntityClass = qrefOptions.class
50
+ ? nymph.getEntityClass(qrefOptions.class)
51
+ : nymph.getEntityClass('Entity');
52
+ if (enforceRestEnabledFlag && !QrefEntityClass.restEnabled) {
53
+ throw new Error('Not accessible.');
54
+ }
52
55
  const options = { ...qrefOptions, class: QrefEntityClass };
53
56
  if (!newSelector[key]) {
54
57
  newSelector[key] = [];
55
58
  }
56
59
  (newSelector[key] as [string, [Options, ...Selector[]]][]).push([
57
60
  name,
58
- [options, ...classNamesToEntityConstructors(nymph, selectors)],
61
+ [
62
+ options,
63
+ ...classNamesToEntityConstructors(
64
+ nymph,
65
+ selectors,
66
+ enforceRestEnabledFlag,
67
+ ),
68
+ ],
59
69
  ]);
60
70
  }
61
71
  } else if (key === 'selector' || key === '!selector') {
62
72
  const tmpArr = (Array.isArray(value) ? value : [value]) as Selector[];
63
- newSelector[key] = classNamesToEntityConstructors(nymph, tmpArr);
73
+ newSelector[key] = classNamesToEntityConstructors(
74
+ nymph,
75
+ tmpArr,
76
+ enforceRestEnabledFlag,
77
+ );
64
78
  } else {
65
79
  // @ts-ignore: ts doesn't know what value is here.
66
80
  newSelector[key] = value;
@@ -94,7 +108,7 @@ export function entitiesToReferences(item: any): any {
94
108
  export function referencesToEntities(
95
109
  item: any,
96
110
  nymph: Nymph,
97
- useSkipAc = false
111
+ useSkipAc = false,
98
112
  ): any {
99
113
  if (Array.isArray(item)) {
100
114
  // Check if it's a reference.
package/tsconfig.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "extends": "@tsconfig/recommended/tsconfig.json",
3
3
 
4
4
  "compilerOptions": {
5
- "lib": ["ES2021"],
6
- "target": "ES2021",
5
+ "lib": ["ES2023"],
6
+ "target": "ES2022",
7
7
  "noImplicitAny": true,
8
- "removeComments": true,
8
+ "removeComments": false,
9
9
  "sourceMap": true,
10
10
  "outDir": "dist",
11
11
  "resolveJsonModule": true,
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }