@speclynx/apidom-core 4.0.2 → 4.0.4

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 (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +5 -5
  3. package/src/fields/fixed-fields.cjs +47 -0
  4. package/src/fields/fixed-fields.mjs +43 -0
  5. package/src/fields/index.cjs +8 -0
  6. package/src/fields/index.mjs +1 -0
  7. package/src/identity/errors/ElementIdentityError.cjs +22 -0
  8. package/src/identity/errors/ElementIdentityError.mjs +19 -0
  9. package/src/identity/index.cjs +64 -0
  10. package/src/identity/index.mjs +58 -0
  11. package/src/index.cjs +48 -0
  12. package/src/index.mjs +41 -0
  13. package/src/media-types.cjs +21 -0
  14. package/src/media-types.mjs +18 -0
  15. package/src/merge/deepmerge.cjs +165 -0
  16. package/src/merge/deepmerge.mjs +149 -0
  17. package/src/merge/merge-left.cjs +16 -0
  18. package/src/merge/merge-left.mjs +11 -0
  19. package/src/merge/merge-right.cjs +35 -0
  20. package/src/merge/merge-right.mjs +29 -0
  21. package/src/namespace.cjs +10 -0
  22. package/src/namespace.mjs +7 -0
  23. package/src/refractor/plugins/dispatcher/index.cjs +64 -0
  24. package/src/refractor/plugins/dispatcher/index.mjs +54 -0
  25. package/src/refractor/plugins/element-identity.cjs +31 -0
  26. package/src/refractor/plugins/element-identity.mjs +26 -0
  27. package/src/refractor/plugins/semantic-element-identity.cjs +33 -0
  28. package/src/refractor/plugins/semantic-element-identity.mjs +29 -0
  29. package/src/refractor/toolbox.cjs +47 -0
  30. package/src/refractor/toolbox.mjs +41 -0
  31. package/src/specification.cjs +63 -0
  32. package/src/specification.mjs +59 -0
  33. package/src/transcluder/Transcluder.cjs +111 -0
  34. package/src/transcluder/Transcluder.mjs +107 -0
  35. package/src/transcluder/index.cjs +19 -0
  36. package/src/transcluder/index.mjs +13 -0
  37. package/src/transformers/dehydrate.cjs +15 -0
  38. package/src/transformers/dehydrate.mjs +10 -0
  39. package/src/transformers/from.cjs +34 -0
  40. package/src/transformers/from.mjs +29 -0
  41. package/src/transformers/serializers/json.cjs +75 -0
  42. package/src/transformers/serializers/json.mjs +70 -0
  43. package/src/transformers/serializers/value.cjs +50 -0
  44. package/src/transformers/serializers/value.mjs +47 -0
  45. package/src/transformers/serializers/yaml-1-2.cjs +142 -0
  46. package/src/transformers/serializers/yaml-1-2.mjs +137 -0
  47. package/src/transformers/sexprs.cjs +31 -0
  48. package/src/transformers/sexprs.mjs +28 -0
  49. package/src/transformers/to-string.cjs +16 -0
  50. package/src/transformers/to-string.mjs +11 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.0.4](https://github.com/speclynx/apidom/compare/v4.0.3...v4.0.4) (2026-03-12)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **release:** override minimatch 10.2.3 to fix glob pattern regression in lerna publish ([#157](https://github.com/speclynx/apidom/issues/157)) ([c2d65a0](https://github.com/speclynx/apidom/commit/c2d65a06a2187e8563a9dc9db74ba27255450e0b)), closes [lerna/lerna#4305](https://github.com/lerna/lerna/issues/4305) [isaacs/minimatch#284](https://github.com/isaacs/minimatch/issues/284)
11
+
12
+ ## [4.0.3](https://github.com/speclynx/apidom/compare/v4.0.2...v4.0.3) (2026-03-11)
13
+
14
+ ### Bug Fixes
15
+
16
+ - **release:** fix v4.0.2 failed release ([b4dc1c4](https://github.com/speclynx/apidom/commit/b4dc1c48e8d9b2986a70e49b5554eb0a166d7528))
17
+
6
18
  ## [4.0.2](https://github.com/speclynx/apidom/compare/v4.0.1...v4.0.2) (2026-03-11)
7
19
 
8
20
  **Note:** Version bump only for package @speclynx/apidom-core
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speclynx/apidom-core",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Tools for manipulating ApiDOM structures.",
5
5
  "keywords": [
6
6
  "apidom",
@@ -57,9 +57,9 @@
57
57
  "license": "Apache-2.0",
58
58
  "dependencies": {
59
59
  "@babel/runtime-corejs3": "^7.28.4",
60
- "@speclynx/apidom-datamodel": "4.0.2",
61
- "@speclynx/apidom-error": "4.0.2",
62
- "@speclynx/apidom-traverse": "4.0.2",
60
+ "@speclynx/apidom-datamodel": "4.0.4",
61
+ "@speclynx/apidom-error": "4.0.4",
62
+ "@speclynx/apidom-traverse": "4.0.4",
63
63
  "ramda": "~0.32.0",
64
64
  "ramda-adjunct": "^6.0.0",
65
65
  "short-unique-id": "^5.3.2",
@@ -76,5 +76,5 @@
76
76
  "README.md",
77
77
  "CHANGELOG.md"
78
78
  ],
79
- "gitHead": "af1b05d4d5e48a11a3a03cd5699324e0f1b62765"
79
+ "gitHead": "a06f6ef3d37ad5bf860cbbf4b442bfbe3a522cc2"
80
80
  }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ exports.fixedFields = fixedFields;
6
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
+ /**
8
+ * Represents a fixed field definition.
9
+ * @public
10
+ */
11
+
12
+ /**
13
+ * @public
14
+ */
15
+
16
+ /**
17
+ * Returns the fixed fields for an Element class or instance.
18
+ *
19
+ * @param elementOrClass - Element instance or class
20
+ * @param options - Options for return format
21
+ * @returns Array of fixed fields, or object indexed by name if options.indexed is true
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { fixedFields } from '@speclynx/apidom-core';
26
+ *
27
+ * // Get fixed fields as array
28
+ * const fields = fixedFields(ParameterElement);
29
+ *
30
+ * // Get fixed fields as indexed object for O(1) lookups
31
+ * const fieldsIndex = fixedFields(ParameterElement, { indexed: true });
32
+ * if (Object.hasOwn(fieldsIndex, 'description')) {
33
+ * // field exists
34
+ * }
35
+ * ```
36
+ *
37
+ * @public
38
+ */
39
+ function fixedFields(elementOrClass, options) {
40
+ const constructor = elementOrClass instanceof _apidomDatamodel.Element ? elementOrClass.constructor : elementOrClass;
41
+ const fields = constructor.fixedFields ?? [];
42
+ if (options?.indexed) {
43
+ return Object.fromEntries(fields.map(f => [f.name, f]));
44
+ }
45
+ return fields;
46
+ }
47
+ var _default = exports.default = fixedFields;
@@ -0,0 +1,43 @@
1
+ import { Element } from '@speclynx/apidom-datamodel';
2
+
3
+ /**
4
+ * Represents a fixed field definition.
5
+ * @public
6
+ */
7
+
8
+ /**
9
+ * @public
10
+ */
11
+
12
+ /**
13
+ * Returns the fixed fields for an Element class or instance.
14
+ *
15
+ * @param elementOrClass - Element instance or class
16
+ * @param options - Options for return format
17
+ * @returns Array of fixed fields, or object indexed by name if options.indexed is true
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { fixedFields } from '@speclynx/apidom-core';
22
+ *
23
+ * // Get fixed fields as array
24
+ * const fields = fixedFields(ParameterElement);
25
+ *
26
+ * // Get fixed fields as indexed object for O(1) lookups
27
+ * const fieldsIndex = fixedFields(ParameterElement, { indexed: true });
28
+ * if (Object.hasOwn(fieldsIndex, 'description')) {
29
+ * // field exists
30
+ * }
31
+ * ```
32
+ *
33
+ * @public
34
+ */
35
+ export function fixedFields(elementOrClass, options) {
36
+ const constructor = elementOrClass instanceof Element ? elementOrClass.constructor : elementOrClass;
37
+ const fields = constructor.fixedFields ?? [];
38
+ if (options?.indexed) {
39
+ return Object.fromEntries(fields.map(f => [f.name, f]));
40
+ }
41
+ return fields;
42
+ }
43
+ export default fixedFields;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
+ exports.__esModule = true;
5
+ exports.fixedFields = exports.default = void 0;
6
+ var _fixedFields = _interopRequireWildcard(require("./fixed-fields.cjs"));
7
+ exports.fixedFields = _fixedFields.fixedFields;
8
+ exports.default = _fixedFields.default;
@@ -0,0 +1 @@
1
+ export { fixedFields, default } from "./fixed-fields.mjs";
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _apidomError = require("@speclynx/apidom-error");
6
+ /**
7
+ * @public
8
+ */
9
+
10
+ /**
11
+ * @public
12
+ */
13
+ class ElementIdentityError extends _apidomError.ApiDOMStructuredError {
14
+ value;
15
+ constructor(message, structuredOptions) {
16
+ super(message, structuredOptions);
17
+ if (typeof structuredOptions !== 'undefined') {
18
+ this.value = structuredOptions.value;
19
+ }
20
+ }
21
+ }
22
+ var _default = exports.default = ElementIdentityError;
@@ -0,0 +1,19 @@
1
+ import { ApiDOMStructuredError } from '@speclynx/apidom-error';
2
+
3
+ /**
4
+ * @public
5
+ */
6
+
7
+ /**
8
+ * @public
9
+ */
10
+ class ElementIdentityError extends ApiDOMStructuredError {
11
+ value;
12
+ constructor(message, structuredOptions) {
13
+ super(message, structuredOptions);
14
+ if (typeof structuredOptions !== 'undefined') {
15
+ this.value = structuredOptions.value;
16
+ }
17
+ }
18
+ }
19
+ export default ElementIdentityError;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.defaultIdentityManager = exports.IdentityManager = void 0;
6
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
+ var _shortUniqueId = _interopRequireDefault(require("short-unique-id"));
8
+ var _ElementIdentityError = _interopRequireDefault(require("./errors/ElementIdentityError.cjs"));
9
+ /**
10
+ * @public
11
+ */
12
+ class IdentityManager {
13
+ uuid;
14
+ identityMap;
15
+ constructor({
16
+ length = 6
17
+ } = {}) {
18
+ this.uuid = new _shortUniqueId.default({
19
+ length
20
+ });
21
+ this.identityMap = new WeakMap();
22
+ }
23
+ identify(element) {
24
+ if (!(0, _apidomDatamodel.isElement)(element)) {
25
+ throw new _ElementIdentityError.default('Cannot not identify the element. `element` is neither structurally compatible nor a subclass of an Element class.', {
26
+ value: element
27
+ });
28
+ }
29
+
30
+ // use already assigned identity
31
+ if (element.hasMetaProperty('id')) {
32
+ const existingId = element.id;
33
+ if (typeof existingId === 'string' && existingId !== '') {
34
+ return existingId;
35
+ }
36
+ }
37
+
38
+ // assign identity in immutable way
39
+ if (this.identityMap.has(element)) {
40
+ return this.identityMap.get(element);
41
+ }
42
+
43
+ // return element identity
44
+ const id = this.generateId();
45
+ this.identityMap.set(element, id);
46
+ return id;
47
+ }
48
+ forget(element) {
49
+ if (this.identityMap.has(element)) {
50
+ this.identityMap.delete(element);
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+ generateId() {
56
+ return this.uuid.randomUUID();
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @public
62
+ */
63
+ exports.IdentityManager = IdentityManager;
64
+ const defaultIdentityManager = exports.defaultIdentityManager = new IdentityManager();
@@ -0,0 +1,58 @@
1
+ import { isElement } from '@speclynx/apidom-datamodel';
2
+ import ShortUniqueId from 'short-unique-id';
3
+ import ElementIdentityError from "./errors/ElementIdentityError.mjs";
4
+ /**
5
+ * @public
6
+ */
7
+ export class IdentityManager {
8
+ uuid;
9
+ identityMap;
10
+ constructor({
11
+ length = 6
12
+ } = {}) {
13
+ this.uuid = new ShortUniqueId({
14
+ length
15
+ });
16
+ this.identityMap = new WeakMap();
17
+ }
18
+ identify(element) {
19
+ if (!isElement(element)) {
20
+ throw new ElementIdentityError('Cannot not identify the element. `element` is neither structurally compatible nor a subclass of an Element class.', {
21
+ value: element
22
+ });
23
+ }
24
+
25
+ // use already assigned identity
26
+ if (element.hasMetaProperty('id')) {
27
+ const existingId = element.id;
28
+ if (typeof existingId === 'string' && existingId !== '') {
29
+ return existingId;
30
+ }
31
+ }
32
+
33
+ // assign identity in immutable way
34
+ if (this.identityMap.has(element)) {
35
+ return this.identityMap.get(element);
36
+ }
37
+
38
+ // return element identity
39
+ const id = this.generateId();
40
+ this.identityMap.set(element, id);
41
+ return id;
42
+ }
43
+ forget(element) {
44
+ if (this.identityMap.has(element)) {
45
+ this.identityMap.delete(element);
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ generateId() {
51
+ return this.uuid.randomUUID();
52
+ }
53
+ }
54
+
55
+ /**
56
+ * @public
57
+ */
58
+ export const defaultIdentityManager = new IdentityManager();
package/src/index.cjs ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5
+ exports.__esModule = true;
6
+ exports.transclude = exports.toYAML = exports.toValue = exports.toString = exports.toJSON = exports.sexprs = exports.resolveSpecification = exports.refractorPluginSemanticElementIdentity = exports.refractorPluginElementIdentity = exports.mergeRight = exports.mergeLeft = exports.from = exports.fixedFields = exports.dispatchRefractorPlugins = exports.dehydrate = exports.defaultIdentityManager = exports.deepmerge = exports.createToolbox = exports.Transcluder = exports.MediaTypes = exports.IdentityManager = exports.ElementIdentityError = void 0;
7
+ var _index = require("./refractor/plugins/dispatcher/index.cjs");
8
+ exports.dispatchRefractorPlugins = _index.dispatchPluginsSync;
9
+ var _toolbox = _interopRequireDefault(require("./refractor/toolbox.cjs"));
10
+ exports.createToolbox = _toolbox.default;
11
+ var _elementIdentity = _interopRequireDefault(require("./refractor/plugins/element-identity.cjs"));
12
+ exports.refractorPluginElementIdentity = _elementIdentity.default;
13
+ var _semanticElementIdentity = _interopRequireDefault(require("./refractor/plugins/semantic-element-identity.cjs"));
14
+ exports.refractorPluginSemanticElementIdentity = _semanticElementIdentity.default;
15
+ var _mediaTypes = _interopRequireDefault(require("./media-types.cjs"));
16
+ exports.MediaTypes = _mediaTypes.default;
17
+ var _index2 = _interopRequireWildcard(require("./transcluder/index.cjs"));
18
+ exports.transclude = _index2.transclude;
19
+ exports.Transcluder = _index2.default;
20
+ var _specification = require("./specification.cjs");
21
+ exports.resolveSpecification = _specification.resolveSpecification;
22
+ var _index3 = require("./identity/index.cjs");
23
+ exports.defaultIdentityManager = _index3.defaultIdentityManager;
24
+ exports.IdentityManager = _index3.IdentityManager;
25
+ var _ElementIdentityError = _interopRequireDefault(require("./identity/errors/ElementIdentityError.cjs"));
26
+ exports.ElementIdentityError = _ElementIdentityError.default;
27
+ var _from = _interopRequireDefault(require("./transformers/from.cjs"));
28
+ exports.from = _from.default;
29
+ var _value = _interopRequireDefault(require("./transformers/serializers/value.cjs"));
30
+ exports.toValue = _value.default;
31
+ var _json = _interopRequireDefault(require("./transformers/serializers/json.cjs"));
32
+ exports.toJSON = _json.default;
33
+ var _yaml = _interopRequireDefault(require("./transformers/serializers/yaml-1-2.cjs"));
34
+ exports.toYAML = _yaml.default;
35
+ var _dehydrate = _interopRequireDefault(require("./transformers/dehydrate.cjs"));
36
+ exports.dehydrate = _dehydrate.default;
37
+ var _toString = _interopRequireDefault(require("./transformers/to-string.cjs"));
38
+ exports.toString = _toString.default;
39
+ var _sexprs = _interopRequireDefault(require("./transformers/sexprs.cjs"));
40
+ exports.sexprs = _sexprs.default;
41
+ var _deepmerge = _interopRequireDefault(require("./merge/deepmerge.cjs"));
42
+ exports.deepmerge = _deepmerge.default;
43
+ var _mergeRight = _interopRequireDefault(require("./merge/merge-right.cjs"));
44
+ exports.mergeRight = _mergeRight.default;
45
+ var _mergeLeft = _interopRequireDefault(require("./merge/merge-left.cjs"));
46
+ exports.mergeLeft = _mergeLeft.default;
47
+ var _index4 = require("./fields/index.cjs");
48
+ exports.fixedFields = _index4.fixedFields;
package/src/index.mjs ADDED
@@ -0,0 +1,41 @@
1
+ export { dispatchPluginsSync as dispatchRefractorPlugins } from "./refractor/plugins/dispatcher/index.mjs";
2
+ export { default as createToolbox } from "./refractor/toolbox.mjs";
3
+ export { default as refractorPluginElementIdentity } from "./refractor/plugins/element-identity.mjs";
4
+ export { default as refractorPluginSemanticElementIdentity } from "./refractor/plugins/semantic-element-identity.mjs";
5
+ export { default as MediaTypes } from "./media-types.mjs";
6
+ export { transclude, default as Transcluder } from "./transcluder/index.mjs";
7
+ export { resolveSpecification } from "./specification.mjs";
8
+ export { defaultIdentityManager, IdentityManager } from "./identity/index.mjs";
9
+ export { default as ElementIdentityError } from "./identity/errors/ElementIdentityError.mjs";
10
+ /**
11
+ * Transforms data to an Element from a particular namespace.
12
+ */
13
+ export { default as from } from "./transformers/from.mjs";
14
+ /**
15
+ * Transforms the ApiDOM into JavaScript POJO.
16
+ * This POJO would be the result of interpreting the ApiDOM
17
+ * into JavaScript structure.
18
+ */
19
+ export { default as toValue } from "./transformers/serializers/value.mjs";
20
+ /**
21
+ * Transforms the ApiDOM into JSON string.
22
+ */
23
+ export { default as toJSON } from "./transformers/serializers/json.mjs";
24
+ /**
25
+ * Transforms the ApiDOM into YAML string.
26
+ */
27
+ export { default as toYAML } from "./transformers/serializers/yaml-1-2.mjs";
28
+ /**
29
+ * Creates a refract representation of an Element.
30
+ * https://github.com/refractproject/refract-spec
31
+ */
32
+ export { default as dehydrate } from "./transformers/dehydrate.mjs";
33
+ /**
34
+ * Create a refracted string representation of an Element.
35
+ */
36
+ export { default as toString } from "./transformers/to-string.mjs";
37
+ export { default as sexprs } from "./transformers/sexprs.mjs";
38
+ export { default as deepmerge } from "./merge/deepmerge.mjs";
39
+ export { default as mergeRight } from "./merge/merge-right.mjs";
40
+ export { default as mergeLeft } from "./merge/merge-left.mjs";
41
+ export { fixedFields } from "./fields/index.mjs";
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _apidomError = require("@speclynx/apidom-error");
6
+ /**
7
+ * @public
8
+ */
9
+ class MediaTypes extends Array {
10
+ unknownMediaType = 'application/octet-stream';
11
+ filterByFormat() {
12
+ throw new _apidomError.NotImplementedError('filterByFormat method in MediaTypes class is not yet implemented.');
13
+ }
14
+ findBy() {
15
+ throw new _apidomError.NotImplementedError('findBy method in MediaTypes class is not yet implemented.');
16
+ }
17
+ latest() {
18
+ throw new _apidomError.NotImplementedError('latest method in MediaTypes class is not yet implemented.');
19
+ }
20
+ }
21
+ var _default = exports.default = MediaTypes;
@@ -0,0 +1,18 @@
1
+ import { NotImplementedError } from '@speclynx/apidom-error';
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ class MediaTypes extends Array {
7
+ unknownMediaType = 'application/octet-stream';
8
+ filterByFormat() {
9
+ throw new NotImplementedError('filterByFormat method in MediaTypes class is not yet implemented.');
10
+ }
11
+ findBy() {
12
+ throw new NotImplementedError('findBy method in MediaTypes class is not yet implemented.');
13
+ }
14
+ latest() {
15
+ throw new NotImplementedError('latest method in MediaTypes class is not yet implemented.');
16
+ }
17
+ }
18
+ export default MediaTypes;
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.emptyElement = exports.defaultOptions = exports.default = void 0;
6
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
+ var _value = _interopRequireDefault(require("../transformers/serializers/value.cjs"));
8
+ /**
9
+ * @public
10
+ */
11
+
12
+ /**
13
+ * @public
14
+ */
15
+
16
+ /**
17
+ * @public
18
+ */
19
+
20
+ /**
21
+ * @public
22
+ */
23
+
24
+ /**
25
+ * @public
26
+ */
27
+
28
+ /**
29
+ * @public
30
+ */
31
+
32
+ /**
33
+ * @public
34
+ */
35
+
36
+ /**
37
+ * @public
38
+ */
39
+
40
+ /**
41
+ * @public
42
+ */
43
+
44
+ /**
45
+ * @public
46
+ */
47
+
48
+ const emptyElement = element => {
49
+ const meta = !element.isMetaEmpty ? element.meta.cloneDeep() : undefined;
50
+ const attributes = !element.isAttributesEmpty ? (0, _apidomDatamodel.cloneDeep)(element.attributes) : undefined;
51
+
52
+ // @ts-ignore
53
+ return new element.constructor(undefined, meta, attributes);
54
+ };
55
+ exports.emptyElement = emptyElement;
56
+ const cloneUnlessOtherwiseSpecified = (element, options) => options.clone && options.isMergeableElement(element) ? deepmerge(emptyElement(element), element, options) : element;
57
+ const getMergeFunction = (keyElement, options) => {
58
+ if (typeof options.customMerge !== 'function') {
59
+ return deepmerge;
60
+ }
61
+ const customMerge = options.customMerge(keyElement, options);
62
+ return typeof customMerge === 'function' ? customMerge : deepmerge;
63
+ };
64
+ const getMetaMergeFunction = options => {
65
+ if (typeof options.customMetaMerge !== 'function') {
66
+ return targetMeta => targetMeta.cloneDeep();
67
+ }
68
+ return options.customMetaMerge;
69
+ };
70
+ const getAttributesMergeFunction = options => {
71
+ if (typeof options.customAttributesMerge !== 'function') {
72
+ return targetAttributes => (0, _apidomDatamodel.cloneDeep)(targetAttributes);
73
+ }
74
+ return options.customAttributesMerge;
75
+ };
76
+ const mergeArrayElement = (targetElement, sourceElement, options) => {
77
+ const Ctor = targetElement.constructor;
78
+ const merged = targetElement.concat(sourceElement);
79
+ return new Ctor(merged.map(item => cloneUnlessOtherwiseSpecified(item, options)));
80
+ };
81
+ const mergeObjectElement = (targetElement, sourceElement, options) => {
82
+ const destination = (0, _apidomDatamodel.isObjectElement)(targetElement) ? emptyElement(targetElement) : emptyElement(sourceElement);
83
+ if ((0, _apidomDatamodel.isObjectElement)(targetElement)) {
84
+ targetElement.forEach((value, key, member) => {
85
+ const clonedMember = (0, _apidomDatamodel.cloneShallow)(member);
86
+ clonedMember.value = cloneUnlessOtherwiseSpecified(value, options);
87
+ destination.content.push(clonedMember);
88
+ });
89
+ }
90
+ sourceElement.forEach((value, key, member) => {
91
+ const keyValue = (0, _value.default)(key);
92
+ let clonedMember;
93
+ if ((0, _apidomDatamodel.isObjectElement)(targetElement) && targetElement.hasKey(keyValue) && options.isMergeableElement(value)) {
94
+ const targetValue = targetElement.get(keyValue);
95
+ clonedMember = (0, _apidomDatamodel.cloneShallow)(member);
96
+ clonedMember.value = getMergeFunction(key, options)(targetValue, value, options);
97
+ } else {
98
+ clonedMember = (0, _apidomDatamodel.cloneShallow)(member);
99
+ clonedMember.value = cloneUnlessOtherwiseSpecified(value, options);
100
+ }
101
+ destination.remove(keyValue);
102
+ destination.content.push(clonedMember);
103
+ });
104
+ return destination;
105
+ };
106
+ const defaultOptions = exports.defaultOptions = {
107
+ clone: true,
108
+ isMergeableElement: element => (0, _apidomDatamodel.isObjectElement)(element) || (0, _apidomDatamodel.isArrayElement)(element),
109
+ arrayElementMerge: mergeArrayElement,
110
+ objectElementMerge: mergeObjectElement,
111
+ customMerge: undefined,
112
+ customMetaMerge: undefined,
113
+ customAttributesMerge: undefined
114
+ };
115
+
116
+ /**
117
+ * @public
118
+ */
119
+ const deepmerge = (targetElement, sourceElement, options) => {
120
+ const mergedOptions = {
121
+ ...defaultOptions,
122
+ ...options
123
+ };
124
+ mergedOptions.isMergeableElement = mergedOptions.isMergeableElement ?? defaultOptions.isMergeableElement;
125
+ mergedOptions.arrayElementMerge = mergedOptions.arrayElementMerge ?? defaultOptions.arrayElementMerge;
126
+ mergedOptions.objectElementMerge = mergedOptions.objectElementMerge ?? defaultOptions.objectElementMerge;
127
+ const sourceIsArrayElement = (0, _apidomDatamodel.isArrayElement)(sourceElement);
128
+ const targetIsArrayElement = (0, _apidomDatamodel.isArrayElement)(targetElement);
129
+ const sourceAndTargetTypesMatch = sourceIsArrayElement === targetIsArrayElement;
130
+ if (!sourceAndTargetTypesMatch) {
131
+ return cloneUnlessOtherwiseSpecified(sourceElement, mergedOptions);
132
+ }
133
+
134
+ // merging two elements
135
+ const mergedElement = sourceIsArrayElement && typeof mergedOptions.arrayElementMerge === 'function' ? mergedOptions.arrayElementMerge(targetElement, sourceElement, mergedOptions) : mergedOptions.objectElementMerge(targetElement, sourceElement, mergedOptions);
136
+
137
+ // merging meta & attributes
138
+ if (!targetElement.isMetaEmpty && !sourceElement.isMetaEmpty) {
139
+ mergedElement.meta = getMetaMergeFunction(mergedOptions)(targetElement.meta, sourceElement.meta);
140
+ } else if (!targetElement.isMetaEmpty) {
141
+ mergedElement.meta = targetElement.meta.cloneDeep();
142
+ } else if (!sourceElement.isMetaEmpty) {
143
+ mergedElement.meta = sourceElement.meta.cloneDeep();
144
+ }
145
+ if (!targetElement.isAttributesEmpty && !sourceElement.isAttributesEmpty) {
146
+ mergedElement.attributes = getAttributesMergeFunction(mergedOptions)(targetElement.attributes, sourceElement.attributes);
147
+ } else if (!targetElement.isAttributesEmpty) {
148
+ mergedElement.attributes = (0, _apidomDatamodel.cloneDeep)(targetElement.attributes);
149
+ } else if (!sourceElement.isAttributesEmpty) {
150
+ mergedElement.attributes = (0, _apidomDatamodel.cloneDeep)(sourceElement.attributes);
151
+ }
152
+ return mergedElement;
153
+ };
154
+ deepmerge.all = (list, options) => {
155
+ if (!Array.isArray(list)) {
156
+ throw new TypeError('First argument of deepmerge should be an array.');
157
+ }
158
+ if (list.length === 0) {
159
+ return new _apidomDatamodel.ObjectElement();
160
+ }
161
+ return list.reduce((target, source) => {
162
+ return deepmerge(target, source, options);
163
+ }, emptyElement(list[0]));
164
+ };
165
+ var _default = exports.default = deepmerge;