@mittwald/react-ghostmaker 1.3.1 → 1.4.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.
@@ -1,35 +1,33 @@
1
1
  import is from "@sindresorhus/is";
2
2
  const store = new Map();
3
+ const testNameConflict = (name) => {
4
+ if (Array.from(store.values()).some((meta) => meta.name === name)) {
5
+ throw new Error(`GhostMakerModel name conflict: A model with the name "${name}" is already registered.`);
6
+ }
7
+ };
3
8
  export function GhostMakerModel(options) {
4
9
  return function (target) {
10
+ if (options.name) {
11
+ testNameConflict(options.name);
12
+ }
5
13
  store.set(target, options);
6
14
  };
7
15
  }
8
- const modelIdentifiers = [];
16
+ const dynamicModels = [];
9
17
  export function ghostMakerModel(modelIdentifier) {
10
- modelIdentifiers.push(modelIdentifier);
18
+ dynamicModels.push(modelIdentifier);
11
19
  }
12
- const getMetaDataFromIdentifiers = (something) => {
13
- for (const identifyModel of modelIdentifiers) {
20
+ const getDynamicMetaData = (something) => {
21
+ for (const identifyModel of dynamicModels) {
14
22
  const meta = identifyModel(something);
15
23
  if (meta) {
16
24
  return meta;
17
25
  }
18
26
  }
19
27
  };
20
- function isClass(value) {
21
- return typeof value === "function" && /class[\s{]/.test(value.toString());
22
- }
23
- const getClass = (something) => {
24
- return isClass(something)
25
- ? something
26
- : is.object(something)
27
- ? something.constructor
28
- : undefined;
29
- };
30
28
  export const getMetaData = (something) => {
31
29
  return (getMetaDataRecursive(something, undefined, getClass(something)) ??
32
- getMetaDataFromIdentifiers(something));
30
+ getDynamicMetaData(something));
33
31
  };
34
32
  const getMetaDataRecursive = (something, collectedMeta,
35
33
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
@@ -43,5 +41,26 @@ klass) => {
43
41
  if (!klass) {
44
42
  return mergedMeta;
45
43
  }
46
- return getMetaDataRecursive(something, mergedMeta, Object.getPrototypeOf(klass));
44
+ const prototypes = getProtoypes.current(klass);
45
+ for (const proto of prototypes) {
46
+ const result = getMetaDataRecursive(something, mergedMeta, proto);
47
+ if (result) {
48
+ return result;
49
+ }
50
+ }
51
+ };
52
+ function isClass(value) {
53
+ return typeof value === "function" && /class[\s{]/.test(value.toString());
54
+ }
55
+ const getClass = (something) => {
56
+ return isClass(something)
57
+ ? something
58
+ : is.object(something)
59
+ ? something.constructor
60
+ : undefined;
61
+ };
62
+ export const getProtoypes = {
63
+ current: (something) => {
64
+ return [Object.getPrototypeOf(something)];
65
+ },
47
66
  };
@@ -0,0 +1,3 @@
1
+ import { getPrototypeListOf } from "polytype";
2
+ import { getProtoypes } from "./metaData";
3
+ getProtoypes.current = getPrototypeListOf;
@@ -104,3 +104,9 @@ test("getMetaData returns correct names", () => {
104
104
  expect(getMetaData(Parent)?.name).toBe("TheParent");
105
105
  expect(getMetaData(Child)?.name).toBe("TheChild");
106
106
  });
107
+ test("getMetaData returns getId function", () => {
108
+ expect(getMetaData(new Child("id"))?.getId).toBeDefined();
109
+ expect(getMetaData(new Parent("id"))?.getId).toBeDefined();
110
+ expect(getMetaData(Parent)?.getId).toBeDefined();
111
+ expect(getMetaData(Child)?.getId).toBeDefined();
112
+ });
@@ -5,7 +5,10 @@ interface GhostMakerModelMeta<T extends DecoratorTarget> {
5
5
  name?: string;
6
6
  }
7
7
  export declare function GhostMakerModel<T extends DecoratorTarget>(options: GhostMakerModelMeta<T>): (target: T) => void;
8
- type IdentifyModel = (something: unknown) => GhostMakerModelMeta<DecoratorTarget> | undefined;
9
- export declare function ghostMakerModel(modelIdentifier: IdentifyModel): void;
8
+ type DynamicModel = (something: unknown) => GhostMakerModelMeta<DecoratorTarget> | void | undefined;
9
+ export declare function ghostMakerModel(modelIdentifier: DynamicModel): void;
10
10
  export declare const getMetaData: (something: unknown) => GhostMakerModelMeta<DecoratorTarget> | undefined;
11
+ export declare const getProtoypes: {
12
+ current: (something: unknown) => any[];
13
+ };
11
14
  export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/react-ghostmaker",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "author": "Mittwald CM Service GmbH & Co. KG <opensource@mittwald.de>",
5
5
  "contributors": [
6
6
  "Marco Falkenberg <m.falkenberg@mittwald.de>"
@@ -27,6 +27,10 @@
27
27
  "types": "./dist/types/index.d.ts",
28
28
  "import": "./dist/esm/index.js"
29
29
  },
30
+ "./polytype": {
31
+ "types": "./dist/types/polytype.d.ts",
32
+ "import": "./dist/esm/polytype.js"
33
+ },
30
34
  "./package.json": "./package.json"
31
35
  },
32
36
  "types": "./dist/types/index.d.ts",
@@ -56,6 +60,7 @@
56
60
  "globals": "^16.5.0",
57
61
  "happy-dom": "^20.0.2",
58
62
  "license-checker-rseidelsohn": "^4.4.2",
63
+ "polytype": "^0.17.0",
59
64
  "prettier": "^3.6.2",
60
65
  "prettier-plugin-jsdoc": "^1.3.3",
61
66
  "prettier-plugin-pkgsort": "^0.2.1",
@@ -68,8 +73,14 @@
68
73
  },
69
74
  "peerDependencies": {
70
75
  "@tanstack/react-query": "^5",
76
+ "polytype": "^0.17.0",
71
77
  "react": ">=19.2"
72
78
  },
79
+ "peerDependenciesMeta": {
80
+ "polytype": {
81
+ "optional": true
82
+ }
83
+ },
73
84
  "scripts": {
74
85
  "build": "pnpm build:clean && pnpm tsc",
75
86
  "build:clean": "rimraf dist",