@vaadin/hilla-models 24.5.0-alpha10
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.
- package/.lintstagedrc.js +6 -0
- package/LICENSE +201 -0
- package/README.md +24 -0
- package/builders.d.ts +160 -0
- package/builders.d.ts.map +1 -0
- package/builders.js +147 -0
- package/builders.js.map +7 -0
- package/core.d.ts +48 -0
- package/core.d.ts.map +1 -0
- package/core.js +19 -0
- package/core.js.map +7 -0
- package/index.d.ts +82 -0
- package/index.d.ts.map +1 -0
- package/index.js +125 -0
- package/index.js.map +7 -0
- package/model.d.ts +136 -0
- package/model.d.ts.map +1 -0
- package/model.js +64 -0
- package/model.js.map +7 -0
- package/package.json +78 -0
package/.lintstagedrc.js
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Hilla Models
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@vaadin/hilla-models)
|
|
4
|
+
|
|
5
|
+
A collection of utilities to build data models that could be used for data binging, validation, backend integration etc.
|
|
6
|
+
|
|
7
|
+
A part of the Hilla project.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
$ npm install @vaadin/hilla-models
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Contribution
|
|
16
|
+
|
|
17
|
+
Read the [contributing guide](https://vaadin.com/docs/latest/contributing-docs/overview) to learn about our development process, how to propose bugfixes and improvements, and how to test your changes.
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
Apache License 2.0
|
|
22
|
+
|
|
23
|
+
Vaadin collects development time usage statistics to improve this product.
|
|
24
|
+
For details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics.
|
package/builders.d.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { EmptyObject } from 'type-fest';
|
|
2
|
+
import type { ObjectModel } from './core';
|
|
3
|
+
import { type AnyObject, type DefaultValueProvider, type Model, type ModelMetadata } from './model.js';
|
|
4
|
+
/**
|
|
5
|
+
* The options for creating the model property.
|
|
6
|
+
*/
|
|
7
|
+
export type ModelBuilderPropertyOptions = Readonly<{
|
|
8
|
+
meta?: ModelMetadata;
|
|
9
|
+
}>;
|
|
10
|
+
declare const $model: unique symbol;
|
|
11
|
+
/**
|
|
12
|
+
* The flags for the model constructor that allow to determine specific characteristics of the model.
|
|
13
|
+
*/
|
|
14
|
+
export type Flags = {
|
|
15
|
+
/**
|
|
16
|
+
* Defines if the model is named.
|
|
17
|
+
*/
|
|
18
|
+
named: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The keys of the self-referencing properties.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* The problem of self-reference models is that they cannot have intermediate
|
|
24
|
+
* type because during the property definition, the model itself is in the
|
|
25
|
+
* middle of construction. That's why we define the specific type-only flag
|
|
26
|
+
* that allows us to know which model properties are self-referenced. We can
|
|
27
|
+
* safely set it in the end of building using this flag.
|
|
28
|
+
*/
|
|
29
|
+
selfRefKeys: keyof any;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A builder class for creating all basic models.
|
|
33
|
+
*
|
|
34
|
+
* @typeParam V - The final value type of the model.
|
|
35
|
+
* @typeParam EX - The extra properties of the model.
|
|
36
|
+
* @typeParam F - The flags for the model constructor that allow to determine
|
|
37
|
+
* specific characteristics of the model.
|
|
38
|
+
*/
|
|
39
|
+
export declare class CoreModelBuilder<V, EX extends AnyObject = EmptyObject, F extends Flags = {
|
|
40
|
+
named: false;
|
|
41
|
+
selfRefKeys: never;
|
|
42
|
+
}> {
|
|
43
|
+
protected readonly [$model]: Model<V, EX>;
|
|
44
|
+
/**
|
|
45
|
+
* @param base - The base model to extend.
|
|
46
|
+
* @param defaultValueProvider - The function that provides the default value
|
|
47
|
+
* for the model.
|
|
48
|
+
*/
|
|
49
|
+
constructor(base: Model, defaultValueProvider?: (model: Model<V, EX>) => V);
|
|
50
|
+
/**
|
|
51
|
+
* Appends metadata to the model.
|
|
52
|
+
*
|
|
53
|
+
* @param value - The metadata to append.
|
|
54
|
+
* @returns The current builder instance.
|
|
55
|
+
*/
|
|
56
|
+
meta(value: ModelMetadata): this;
|
|
57
|
+
/**
|
|
58
|
+
* Defines a new property on the model. The property serves the purposes of
|
|
59
|
+
* storing the extra data for specific types of models.
|
|
60
|
+
*
|
|
61
|
+
* @remarks
|
|
62
|
+
* The key of the property should be a symbol to avoid conflicts with
|
|
63
|
+
* properties defined via
|
|
64
|
+
* {@link ObjectModelBuilder}.
|
|
65
|
+
*
|
|
66
|
+
* @param key - The key of the property.
|
|
67
|
+
* @param value - The descriptor of the property.
|
|
68
|
+
* @returns The current builder instance.
|
|
69
|
+
*/
|
|
70
|
+
define<DK extends symbol, DV>(key: DK, value: TypedPropertyDescriptor<DV>): CoreModelBuilder<V, EX & Readonly<Record<DK, DV>>, F>;
|
|
71
|
+
/**
|
|
72
|
+
* Sets the default value provider for the model. This is an alternative way
|
|
73
|
+
* to provide the default value for the model if for some reason using the
|
|
74
|
+
* constructor parameter is undesired.
|
|
75
|
+
*
|
|
76
|
+
* @param defaultValueProvider - The function that provides the default value
|
|
77
|
+
* for the model.
|
|
78
|
+
* @returns The current builder instance.
|
|
79
|
+
*/
|
|
80
|
+
defaultValueProvider(defaultValueProvider: DefaultValueProvider<V, EX>): this;
|
|
81
|
+
/**
|
|
82
|
+
* Sets the name of the model. The name is used for debugging purposes and is
|
|
83
|
+
* displayed in the string representation. Setting the name is required;
|
|
84
|
+
* otherwise, the {@link CoreModelBuilder.build} method won't be available.
|
|
85
|
+
*
|
|
86
|
+
* @param name - The name of the model.
|
|
87
|
+
* @returns The current builder instance.
|
|
88
|
+
*/
|
|
89
|
+
name(name: string): CoreModelBuilder<V, EX, {
|
|
90
|
+
named: true;
|
|
91
|
+
selfRefKeys: F['selfRefKeys'];
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* Builds the model. On the typing level, it checks if all the model parts are
|
|
95
|
+
* set correctly, and raises an error if not.
|
|
96
|
+
*
|
|
97
|
+
* @returns The model.
|
|
98
|
+
*/
|
|
99
|
+
build(this: F['named'] extends true ? this : never): Model<V, EX>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A builder class for creating object models.
|
|
103
|
+
*
|
|
104
|
+
* @typeParam V - The final value type of the model.
|
|
105
|
+
* @typeParam CV - The current value type of the model. It changes as the model
|
|
106
|
+
* is being built and defines if the
|
|
107
|
+
* {@link ObjectModelBuilder.build} method can be called.
|
|
108
|
+
* @typeParam EX - The extra properties of the model.
|
|
109
|
+
* @typeParam F - The flags for the model constructor that allow to determine
|
|
110
|
+
* specific characteristics of the model.
|
|
111
|
+
*/
|
|
112
|
+
export declare class ObjectModelBuilder<V extends AnyObject, CV extends AnyObject = EmptyObject, EX extends AnyObject = EmptyObject, F extends Flags = {
|
|
113
|
+
named: false;
|
|
114
|
+
selfRefKeys: never;
|
|
115
|
+
}> extends CoreModelBuilder<V, EX, F> {
|
|
116
|
+
constructor(base: Model);
|
|
117
|
+
/**
|
|
118
|
+
* The method that should follow the {@link m.extend} method. It allows to
|
|
119
|
+
* declare the extension for the model and properly name it.
|
|
120
|
+
*
|
|
121
|
+
* @param name - The name of the model.
|
|
122
|
+
*/
|
|
123
|
+
object<NV extends AnyObject>(this: F['named'] extends false ? this : never, name: string): ObjectModelBuilder<NV & V, CV, EX, {
|
|
124
|
+
named: true;
|
|
125
|
+
selfRefKeys: F['selfRefKeys'];
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* {@inheritDoc CoreModelBuilder.define}
|
|
129
|
+
*/
|
|
130
|
+
['define']: <DK extends symbol, DV>(key: DK, value: TypedPropertyDescriptor<DV>) => ObjectModelBuilder<V, CV, EX & Readonly<Record<DK, DV>>, F>;
|
|
131
|
+
/**
|
|
132
|
+
* {@inheritDoc CoreModelBuilder.meta}
|
|
133
|
+
*/
|
|
134
|
+
['meta']: (value: ModelMetadata) => this;
|
|
135
|
+
/**
|
|
136
|
+
* Defines a new model property on the model. Unlike the
|
|
137
|
+
* {@link ObjectModelBuilder.define}, this property is public and allows the
|
|
138
|
+
* user to interact with the model data structure. It also updates the current
|
|
139
|
+
* value type of the model to make it closer to the final value type.
|
|
140
|
+
*
|
|
141
|
+
* @param key - The key of the property.
|
|
142
|
+
* @param model - The model of the property value. You can also provide a
|
|
143
|
+
* function that produces the model based on the current model.
|
|
144
|
+
* @param options - Additional options for the property.
|
|
145
|
+
*
|
|
146
|
+
* @returns The current builder instance updated with the new property type.
|
|
147
|
+
* In case there is a self-referencing property, the {@link Flags.selfRefKeys}
|
|
148
|
+
* flag for the specific property is set.
|
|
149
|
+
*/
|
|
150
|
+
property<PK extends string & keyof V, EXK extends AnyObject = EmptyObject>(key: PK, model: Model<V[PK], EXK> | ((model: Model<V, EX & Readonly<Record<PK, Model<V[PK], EXK>>>>) => Model<V[PK], EXK>), options?: ModelBuilderPropertyOptions): Extract<V[PK], V> extends never ? ObjectModelBuilder<V, CV & Readonly<Record<PK, V[PK]>>, EX & Readonly<Record<PK, Model<V[PK], EXK>>>, F> : ObjectModelBuilder<V, CV & Readonly<Record<PK, V[PK]>>, EX, {
|
|
151
|
+
named: F['named'];
|
|
152
|
+
selfRefKeys: F['selfRefKeys'] | PK;
|
|
153
|
+
}>;
|
|
154
|
+
/**
|
|
155
|
+
* {@inheritDoc CoreModelBuilder.build}
|
|
156
|
+
*/
|
|
157
|
+
build: (this: F['named'] extends true ? (CV extends V ? this : never) : never) => ObjectModel<V, EX, F['selfRefKeys']>;
|
|
158
|
+
}
|
|
159
|
+
export {};
|
|
160
|
+
//# sourceMappingURL=builders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["src/builders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAML,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,KAAK,EACV,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC,CAAC;AAEH,QAAA,MAAM,MAAM,eAAkB,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;;;;;;;;OASG;IACH,WAAW,EAAE,MAAM,GAAG,CAAC;CACxB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,gBAAgB,CAC3B,CAAC,EACD,EAAE,SAAS,SAAS,GAAG,WAAW,EAClC,CAAC,SAAS,KAAK,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,KAAK,CAAA;CAAE;IAEtD,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1C;;;;OAIG;gBACS,IAAI,EAAE,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;IAQ1E;;;;;OAKG;IACH,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAKhC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,EAC1B,GAAG,EAAE,EAAE,EACP,KAAK,EAAE,uBAAuB,CAAC,EAAE,CAAC,GACjC,gBAAgB,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAKxD;;;;;;;;OAQG;IACH,oBAAoB,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI;IAS7E;;;;;;;OAOG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,CAAA;KAAE,CAAC;IAI3F;;;;;OAKG;IACH,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;CAGlE;AAWD;;;;;;;;;;GAUG;AACH,qBAAa,kBAAkB,CAC7B,CAAC,SAAS,SAAS,EACnB,EAAE,SAAS,SAAS,GAAG,WAAW,EAClC,EAAE,SAAS,SAAS,GAAG,WAAW,EAClC,CAAC,SAAS,KAAK,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,KAAK,CAAA;CAAE,CACtD,SAAQ,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACtB,IAAI,EAAE,KAAK;IAgBvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,SAAS,EACzB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,GAAG,IAAI,GAAG,KAAK,EAC7C,IAAI,EAAE,MAAM,GACX,kBAAkB,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,CAAA;KAAE,CAAC;IAIrF;;OAEG;IACK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,EACxC,GAAG,EAAE,EAAE,EACP,KAAK,EAAE,uBAAuB,CAAC,EAAE,CAAC,KAC/B,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEjE;;OAEG;IACK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAEjD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,SAAS,SAAS,GAAG,WAAW,EACvE,GAAG,EAAE,EAAE,EACP,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EACjH,OAAO,CAAC,EAAE,2BAA2B,GAGvC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,SAAS,KAAK,GAG3B,kBAAkB,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAGxG,kBAAkB,CAChB,CAAC,EACD,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAChC,EAAE,EACF;QAEE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAGlB,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC;KACpC,CACF;IAyBL;;OAEG;IACK,KAAK,EAAE,CACb,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,KAClE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;CAC3C"}
|
package/builders.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
$defaultValue,
|
|
3
|
+
$key,
|
|
4
|
+
$meta,
|
|
5
|
+
$name,
|
|
6
|
+
$owner
|
|
7
|
+
} from "./model.js";
|
|
8
|
+
const { create, defineProperty } = Object;
|
|
9
|
+
const $model = Symbol("model");
|
|
10
|
+
class CoreModelBuilder {
|
|
11
|
+
[$model];
|
|
12
|
+
/**
|
|
13
|
+
* @param base - The base model to extend.
|
|
14
|
+
* @param defaultValueProvider - The function that provides the default value
|
|
15
|
+
* for the model.
|
|
16
|
+
*/
|
|
17
|
+
constructor(base, defaultValueProvider) {
|
|
18
|
+
this[$model] = create(base);
|
|
19
|
+
if (defaultValueProvider) {
|
|
20
|
+
this.defaultValueProvider(defaultValueProvider);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Appends metadata to the model.
|
|
25
|
+
*
|
|
26
|
+
* @param value - The metadata to append.
|
|
27
|
+
* @returns The current builder instance.
|
|
28
|
+
*/
|
|
29
|
+
meta(value) {
|
|
30
|
+
this.define($meta, { value });
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Defines a new property on the model. The property serves the purposes of
|
|
35
|
+
* storing the extra data for specific types of models.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* The key of the property should be a symbol to avoid conflicts with
|
|
39
|
+
* properties defined via
|
|
40
|
+
* {@link ObjectModelBuilder}.
|
|
41
|
+
*
|
|
42
|
+
* @param key - The key of the property.
|
|
43
|
+
* @param value - The descriptor of the property.
|
|
44
|
+
* @returns The current builder instance.
|
|
45
|
+
*/
|
|
46
|
+
define(key, value) {
|
|
47
|
+
defineProperty(this[$model], key, value);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Sets the default value provider for the model. This is an alternative way
|
|
52
|
+
* to provide the default value for the model if for some reason using the
|
|
53
|
+
* constructor parameter is undesired.
|
|
54
|
+
*
|
|
55
|
+
* @param defaultValueProvider - The function that provides the default value
|
|
56
|
+
* for the model.
|
|
57
|
+
* @returns The current builder instance.
|
|
58
|
+
*/
|
|
59
|
+
defaultValueProvider(defaultValueProvider) {
|
|
60
|
+
this.define($defaultValue, {
|
|
61
|
+
get() {
|
|
62
|
+
return defaultValueProvider(this);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sets the name of the model. The name is used for debugging purposes and is
|
|
69
|
+
* displayed in the string representation. Setting the name is required;
|
|
70
|
+
* otherwise, the {@link CoreModelBuilder.build} method won't be available.
|
|
71
|
+
*
|
|
72
|
+
* @param name - The name of the model.
|
|
73
|
+
* @returns The current builder instance.
|
|
74
|
+
*/
|
|
75
|
+
name(name) {
|
|
76
|
+
return this.define($name, { value: name });
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Builds the model. On the typing level, it checks if all the model parts are
|
|
80
|
+
* set correctly, and raises an error if not.
|
|
81
|
+
*
|
|
82
|
+
* @returns The model.
|
|
83
|
+
*/
|
|
84
|
+
build() {
|
|
85
|
+
return this[$model];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const propertyRegistry = /* @__PURE__ */ new WeakMap();
|
|
89
|
+
class ObjectModelBuilder extends CoreModelBuilder {
|
|
90
|
+
constructor(base) {
|
|
91
|
+
super(base, (m) => {
|
|
92
|
+
const result = create(null);
|
|
93
|
+
for (const key in m) {
|
|
94
|
+
defineProperty(result, key, {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get: () => m[key][$defaultValue]
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The method that should follow the {@link m.extend} method. It allows to
|
|
104
|
+
* declare the extension for the model and properly name it.
|
|
105
|
+
*
|
|
106
|
+
* @param name - The name of the model.
|
|
107
|
+
*/
|
|
108
|
+
object(name) {
|
|
109
|
+
return this.name(name);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Defines a new model property on the model. Unlike the
|
|
113
|
+
* {@link ObjectModelBuilder.define}, this property is public and allows the
|
|
114
|
+
* user to interact with the model data structure. It also updates the current
|
|
115
|
+
* value type of the model to make it closer to the final value type.
|
|
116
|
+
*
|
|
117
|
+
* @param key - The key of the property.
|
|
118
|
+
* @param model - The model of the property value. You can also provide a
|
|
119
|
+
* function that produces the model based on the current model.
|
|
120
|
+
* @param options - Additional options for the property.
|
|
121
|
+
*
|
|
122
|
+
* @returns The current builder instance updated with the new property type.
|
|
123
|
+
* In case there is a self-referencing property, the {@link Flags.selfRefKeys}
|
|
124
|
+
* flag for the specific property is set.
|
|
125
|
+
*/
|
|
126
|
+
property(key, model, options) {
|
|
127
|
+
defineProperty(this[$model], key, {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
get() {
|
|
130
|
+
if (!propertyRegistry.has(this)) {
|
|
131
|
+
propertyRegistry.set(this, {});
|
|
132
|
+
}
|
|
133
|
+
const props = propertyRegistry.get(this);
|
|
134
|
+
props[key] ??= new CoreModelBuilder(
|
|
135
|
+
typeof model === "function" ? model(this) : model
|
|
136
|
+
).define($key, { value: key }).define($owner, { value: this }).define($meta, { value: options?.meta }).build();
|
|
137
|
+
return props[key];
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
CoreModelBuilder,
|
|
145
|
+
ObjectModelBuilder
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=builders.js.map
|
package/builders.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/builders.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EmptyObject } from 'type-fest';\nimport type { ObjectModel } from './core';\nimport {\n $defaultValue,\n $key,\n $meta,\n $name,\n $owner,\n type AnyObject,\n type DefaultValueProvider,\n type Model,\n type ModelMetadata,\n} from './model.js';\n\nconst { create, defineProperty } = Object;\n\n/**\n * The options for creating the model property.\n */\nexport type ModelBuilderPropertyOptions = Readonly<{\n meta?: ModelMetadata;\n}>;\n\nconst $model = Symbol('model');\n\n/**\n * The flags for the model constructor that allow to determine specific characteristics of the model.\n */\nexport type Flags = {\n /**\n * Defines if the model is named.\n */\n named: boolean;\n\n /**\n * The keys of the self-referencing properties.\n *\n * @remarks\n * The problem of self-reference models is that they cannot have intermediate\n * type because during the property definition, the model itself is in the\n * middle of construction. That's why we define the specific type-only flag\n * that allows us to know which model properties are self-referenced. We can\n * safely set it in the end of building using this flag.\n */\n selfRefKeys: keyof any;\n};\n\n/**\n * A builder class for creating all basic models.\n *\n * @typeParam V - The final value type of the model.\n * @typeParam EX - The extra properties of the model.\n * @typeParam F - The flags for the model constructor that allow to determine\n * specific characteristics of the model.\n */\nexport class CoreModelBuilder<\n V,\n EX extends AnyObject = EmptyObject,\n F extends Flags = { named: false; selfRefKeys: never },\n> {\n protected readonly [$model]: Model<V, EX>;\n\n /**\n * @param base - The base model to extend.\n * @param defaultValueProvider - The function that provides the default value\n * for the model.\n */\n constructor(base: Model, defaultValueProvider?: (model: Model<V, EX>) => V) {\n this[$model] = create(base);\n\n if (defaultValueProvider) {\n this.defaultValueProvider(defaultValueProvider);\n }\n }\n\n /**\n * Appends metadata to the model.\n *\n * @param value - The metadata to append.\n * @returns The current builder instance.\n */\n meta(value: ModelMetadata): this {\n this.define($meta, { value });\n return this;\n }\n\n /**\n * Defines a new property on the model. The property serves the purposes of\n * storing the extra data for specific types of models.\n *\n * @remarks\n * The key of the property should be a symbol to avoid conflicts with\n * properties defined via\n * {@link ObjectModelBuilder}.\n *\n * @param key - The key of the property.\n * @param value - The descriptor of the property.\n * @returns The current builder instance.\n */\n define<DK extends symbol, DV>(\n key: DK,\n value: TypedPropertyDescriptor<DV>,\n ): CoreModelBuilder<V, EX & Readonly<Record<DK, DV>>, F> {\n defineProperty(this[$model], key, value);\n return this as any;\n }\n\n /**\n * Sets the default value provider for the model. This is an alternative way\n * to provide the default value for the model if for some reason using the\n * constructor parameter is undesired.\n *\n * @param defaultValueProvider - The function that provides the default value\n * for the model.\n * @returns The current builder instance.\n */\n defaultValueProvider(defaultValueProvider: DefaultValueProvider<V, EX>): this {\n this.define($defaultValue, {\n get(this: Model<V, EX>) {\n return defaultValueProvider(this);\n },\n });\n return this;\n }\n\n /**\n * Sets the name of the model. The name is used for debugging purposes and is\n * displayed in the string representation. Setting the name is required;\n * otherwise, the {@link CoreModelBuilder.build} method won't be available.\n *\n * @param name - The name of the model.\n * @returns The current builder instance.\n */\n name(name: string): CoreModelBuilder<V, EX, { named: true; selfRefKeys: F['selfRefKeys'] }> {\n return this.define($name, { value: name }) as any;\n }\n\n /**\n * Builds the model. On the typing level, it checks if all the model parts are\n * set correctly, and raises an error if not.\n *\n * @returns The model.\n */\n build(this: F['named'] extends true ? this : never): Model<V, EX> {\n return this[$model];\n }\n}\n\n/**\n * A registry for the property models of the object model. Since the property\n * registration is lazy, we cannot store the property models directly on the\n * object model, so the registry plays a role of a private storage for them.\n *\n * @internal\n */\nconst propertyRegistry = new WeakMap<Model, Record<string, Model>>();\n\n/**\n * A builder class for creating object models.\n *\n * @typeParam V - The final value type of the model.\n * @typeParam CV - The current value type of the model. It changes as the model\n * is being built and defines if the\n * {@link ObjectModelBuilder.build} method can be called.\n * @typeParam EX - The extra properties of the model.\n * @typeParam F - The flags for the model constructor that allow to determine\n * specific characteristics of the model.\n */\nexport class ObjectModelBuilder<\n V extends AnyObject,\n CV extends AnyObject = EmptyObject,\n EX extends AnyObject = EmptyObject,\n F extends Flags = { named: false; selfRefKeys: never },\n> extends CoreModelBuilder<V, EX, F> {\n constructor(base: Model) {\n super(base, (m) => {\n const result = create(null);\n\n // eslint-disable-next-line no-restricted-syntax\n for (const key in m) {\n defineProperty(result, key, {\n enumerable: true,\n get: () => (m[key as keyof Model<V, EX>] as Model)[$defaultValue],\n });\n }\n\n return result;\n });\n }\n\n /**\n * The method that should follow the {@link m.extend} method. It allows to\n * declare the extension for the model and properly name it.\n *\n * @param name - The name of the model.\n */\n object<NV extends AnyObject>(\n this: F['named'] extends false ? this : never,\n name: string,\n ): ObjectModelBuilder<NV & V, CV, EX, { named: true; selfRefKeys: F['selfRefKeys'] }> {\n return this.name(name) as any;\n }\n\n /**\n * {@inheritDoc CoreModelBuilder.define}\n */\n declare ['define']: <DK extends symbol, DV>(\n key: DK,\n value: TypedPropertyDescriptor<DV>,\n ) => ObjectModelBuilder<V, CV, EX & Readonly<Record<DK, DV>>, F>;\n\n /**\n * {@inheritDoc CoreModelBuilder.meta}\n */\n declare ['meta']: (value: ModelMetadata) => this;\n\n /**\n * Defines a new model property on the model. Unlike the\n * {@link ObjectModelBuilder.define}, this property is public and allows the\n * user to interact with the model data structure. It also updates the current\n * value type of the model to make it closer to the final value type.\n *\n * @param key - The key of the property.\n * @param model - The model of the property value. You can also provide a\n * function that produces the model based on the current model.\n * @param options - Additional options for the property.\n *\n * @returns The current builder instance updated with the new property type.\n * In case there is a self-referencing property, the {@link Flags.selfRefKeys}\n * flag for the specific property is set.\n */\n property<PK extends string & keyof V, EXK extends AnyObject = EmptyObject>(\n key: PK,\n model: Model<V[PK], EXK> | ((model: Model<V, EX & Readonly<Record<PK, Model<V[PK], EXK>>>>) => Model<V[PK], EXK>),\n options?: ModelBuilderPropertyOptions,\n ): // It is a workaround for the self-referencing models.\n // If the type of the model property is not the model itself,\n Extract<V[PK], V> extends never\n ? // Then we simply extend the model with the property, and update the\n // current value type of the model.\n ObjectModelBuilder<V, CV & Readonly<Record<PK, V[PK]>>, EX & Readonly<Record<PK, Model<V[PK], EXK>>>, F>\n : // Otherwise, we set a flag of the model that it contains a self-reference\n // property.\n ObjectModelBuilder<\n V,\n CV & Readonly<Record<PK, V[PK]>>,\n EX,\n {\n // Just inheriting the current flag.\n named: F['named'];\n // Adding the property name to all existing self-referencing\n // properties.\n selfRefKeys: F['selfRefKeys'] | PK;\n }\n > {\n defineProperty(this[$model], key, {\n enumerable: true,\n get(this: Model<V, EX & Readonly<Record<PK, Model<V[PK], EXK>>>>) {\n if (!propertyRegistry.has(this)) {\n propertyRegistry.set(this, {});\n }\n\n const props = propertyRegistry.get(this)!;\n\n props[key] ??= new CoreModelBuilder<V[PK], EXK, { named: true; selfRefKeys: never }>(\n typeof model === 'function' ? model(this) : model,\n )\n .define($key, { value: key })\n .define($owner, { value: this })\n .define($meta, { value: options?.meta })\n .build();\n\n return props[key];\n },\n });\n\n return this as any;\n }\n\n /**\n * {@inheritDoc CoreModelBuilder.build}\n */\n declare build: (\n this: F['named'] extends true ? (CV extends V ? this : never) : never,\n ) => ObjectModel<V, EX, F['selfRefKeys']>;\n}\n"],
|
|
5
|
+
"mappings": "AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AAEP,MAAM,EAAE,QAAQ,eAAe,IAAI;AASnC,MAAM,SAAS,OAAO,OAAO;AAgCtB,MAAM,iBAIX;AAAA,EACA,CAAoB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1B,YAAY,MAAa,sBAAmD;AAC1E,SAAK,MAAM,IAAI,OAAO,IAAI;AAE1B,QAAI,sBAAsB;AACxB,WAAK,qBAAqB,oBAAoB;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAK,OAA4B;AAC/B,SAAK,OAAO,OAAO,EAAE,MAAM,CAAC;AAC5B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OACE,KACA,OACuD;AACvD,mBAAe,KAAK,MAAM,GAAG,KAAK,KAAK;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,qBAAqB,sBAAyD;AAC5E,SAAK,OAAO,eAAe;AAAA,MACzB,MAAwB;AACtB,eAAO,qBAAqB,IAAI;AAAA,MAClC;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,KAAK,MAAuF;AAC1F,WAAO,KAAK,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAkE;AAChE,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;AASA,MAAM,mBAAmB,oBAAI,QAAsC;AAa5D,MAAM,2BAKH,iBAA2B;AAAA,EACnC,YAAY,MAAa;AACvB,UAAM,MAAM,CAAC,MAAM;AACjB,YAAM,SAAS,OAAO,IAAI;AAG1B,iBAAW,OAAO,GAAG;AACnB,uBAAe,QAAQ,KAAK;AAAA,UAC1B,YAAY;AAAA,UACZ,KAAK,MAAO,EAAE,GAAyB,EAAY,aAAa;AAAA,QAClE,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAEE,MACoF;AACpF,WAAO,KAAK,KAAK,IAAI;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,SACE,KACA,OACA,SAoBI;AACJ,mBAAe,KAAK,MAAM,GAAG,KAAK;AAAA,MAChC,YAAY;AAAA,MACZ,MAAkE;AAChE,YAAI,CAAC,iBAAiB,IAAI,IAAI,GAAG;AAC/B,2BAAiB,IAAI,MAAM,CAAC,CAAC;AAAA,QAC/B;AAEA,cAAM,QAAQ,iBAAiB,IAAI,IAAI;AAEvC,cAAM,GAAG,MAAM,IAAI;AAAA,UACjB,OAAO,UAAU,aAAa,MAAM,IAAI,IAAI;AAAA,QAC9C,EACG,OAAO,MAAM,EAAE,OAAO,IAAI,CAAC,EAC3B,OAAO,QAAQ,EAAE,OAAO,KAAK,CAAC,EAC9B,OAAO,OAAO,EAAE,OAAO,SAAS,KAAK,CAAC,EACtC,MAAM;AAET,eAAO,MAAM,GAAG;AAAA,MAClB;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAQF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/core.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { EmptyObject } from 'type-fest';
|
|
2
|
+
import { $enum, $itemModel, type $members, type AnyObject, type Enum, Model, type Value } from './model.js';
|
|
3
|
+
/**
|
|
4
|
+
* The model of a primitive value, like `string`, `number` or `boolean`.
|
|
5
|
+
*/
|
|
6
|
+
export type PrimitiveModel<V = unknown> = Model<V>;
|
|
7
|
+
export declare const PrimitiveModel: Model<unknown, EmptyObject>;
|
|
8
|
+
/**
|
|
9
|
+
* The model of a string value.
|
|
10
|
+
*/
|
|
11
|
+
export type StringModel = PrimitiveModel<string>;
|
|
12
|
+
export declare const StringModel: Model<string, EmptyObject>;
|
|
13
|
+
/**
|
|
14
|
+
* The model of a number value.
|
|
15
|
+
*/
|
|
16
|
+
export type NumberModel = PrimitiveModel<number>;
|
|
17
|
+
export declare const NumberModel: Model<number, EmptyObject>;
|
|
18
|
+
/**
|
|
19
|
+
* The model of a boolean value.
|
|
20
|
+
*/
|
|
21
|
+
export type BooleanModel = PrimitiveModel<boolean>;
|
|
22
|
+
export declare const BooleanModel: Model<boolean, EmptyObject>;
|
|
23
|
+
/**
|
|
24
|
+
* The model of an array data.
|
|
25
|
+
*/
|
|
26
|
+
export type ArrayModel<M extends Model = Model> = Model<Array<Value<M>>, Readonly<{
|
|
27
|
+
[$itemModel]: M;
|
|
28
|
+
}>>;
|
|
29
|
+
export declare const ArrayModel: Model<unknown[], EmptyObject & Readonly<Record<typeof $itemModel, Model<unknown, EmptyObject, never>>>>;
|
|
30
|
+
/**
|
|
31
|
+
* The model of an object data.
|
|
32
|
+
*/
|
|
33
|
+
export type ObjectModel<V, EX extends AnyObject = EmptyObject, R extends keyof any = never> = Model<V, EX, R>;
|
|
34
|
+
export declare const ObjectModel: Model<Readonly<Record<never, never>>, EmptyObject>;
|
|
35
|
+
/**
|
|
36
|
+
* The model of an enum data.
|
|
37
|
+
*/
|
|
38
|
+
export type EnumModel<T extends typeof Enum> = Model<T[keyof T], Readonly<{
|
|
39
|
+
[$enum]: T;
|
|
40
|
+
}>>;
|
|
41
|
+
export declare const EnumModel: Model<string, EmptyObject & Readonly<Record<typeof $enum, typeof Enum>>>;
|
|
42
|
+
/**
|
|
43
|
+
* The model of a union data.
|
|
44
|
+
*/
|
|
45
|
+
export type UnionModel<MM extends Model[]> = Model<Value<MM[number]>, Readonly<{
|
|
46
|
+
[$members]: MM;
|
|
47
|
+
}>>;
|
|
48
|
+
//# sourceMappingURL=core.d.ts.map
|
package/core.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["src/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAE5G;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;AACnD,eAAO,MAAM,cAAc,6BAAkF,CAAC;AAE9G;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;AACjD,eAAO,MAAM,WAAW,4BAAwE,CAAC;AAEjG;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;AACjD,eAAO,MAAM,WAAW,4BAAuE,CAAC;AAEhG;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;AACnD,eAAO,MAAM,YAAY,6BAA4E,CAAC;AAEtG;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,IAAI,KAAK,CACrD,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACf,QAAQ,CAAC;IACP,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;CACjB,CAAC,CACH,CAAC;AAEF,eAAO,MAAM,UAAU,yGAGb,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,EAAE,EAAE,SAAS,SAAS,GAAG,WAAW,EAAE,CAAC,SAAS,MAAM,GAAG,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AAE9G,eAAO,MAAM,WAAW,oDAA4E,CAAC;AAErG;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,OAAO,IAAI,IAAI,KAAK,CAClD,CAAC,CAAC,MAAM,CAAC,CAAC,EACV,QAAQ,CAAC;IACP,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;CACZ,CAAC,CACH,CAAC;AAEF,eAAO,MAAM,SAAS,0EAKZ,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,EAAE,SAAS,KAAK,EAAE,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC;IAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAA;CAAE,CAAC,CAAC,CAAC"}
|
package/core.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CoreModelBuilder } from "./builders.js";
|
|
2
|
+
import { $enum, $itemModel, Model } from "./model.js";
|
|
3
|
+
const PrimitiveModel = new CoreModelBuilder(Model, () => void 0).name("primitive").build();
|
|
4
|
+
const StringModel = new CoreModelBuilder(PrimitiveModel, () => "").name("string").build();
|
|
5
|
+
const NumberModel = new CoreModelBuilder(PrimitiveModel, () => 0).name("number").build();
|
|
6
|
+
const BooleanModel = new CoreModelBuilder(PrimitiveModel, () => false).name("boolean").build();
|
|
7
|
+
const ArrayModel = new CoreModelBuilder(Model, () => []).name("Array").define($itemModel, { value: Model }).build();
|
|
8
|
+
const ObjectModel = new CoreModelBuilder(Model, () => ({})).name("Object").build();
|
|
9
|
+
const EnumModel = new CoreModelBuilder(Model).name("Enum").define($enum, { value: {} }).defaultValueProvider((self) => Object.values(self[$enum])[0]).build();
|
|
10
|
+
export {
|
|
11
|
+
ArrayModel,
|
|
12
|
+
BooleanModel,
|
|
13
|
+
EnumModel,
|
|
14
|
+
NumberModel,
|
|
15
|
+
ObjectModel,
|
|
16
|
+
PrimitiveModel,
|
|
17
|
+
StringModel
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=core.js.map
|
package/core.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/core.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EmptyObject } from 'type-fest';\nimport { CoreModelBuilder } from './builders.js';\nimport { $enum, $itemModel, type $members, type AnyObject, type Enum, Model, type Value } from './model.js';\n\n/**\n * The model of a primitive value, like `string`, `number` or `boolean`.\n */\nexport type PrimitiveModel<V = unknown> = Model<V>;\nexport const PrimitiveModel = new CoreModelBuilder(Model, (): unknown => undefined).name('primitive').build();\n\n/**\n * The model of a string value.\n */\nexport type StringModel = PrimitiveModel<string>;\nexport const StringModel = new CoreModelBuilder(PrimitiveModel, () => '').name('string').build();\n\n/**\n * The model of a number value.\n */\nexport type NumberModel = PrimitiveModel<number>;\nexport const NumberModel = new CoreModelBuilder(PrimitiveModel, () => 0).name('number').build();\n\n/**\n * The model of a boolean value.\n */\nexport type BooleanModel = PrimitiveModel<boolean>;\nexport const BooleanModel = new CoreModelBuilder(PrimitiveModel, () => false).name('boolean').build();\n\n/**\n * The model of an array data.\n */\nexport type ArrayModel<M extends Model = Model> = Model<\n Array<Value<M>>,\n Readonly<{\n [$itemModel]: M;\n }>\n>;\n\nexport const ArrayModel = new CoreModelBuilder(Model, (): unknown[] => [])\n .name('Array')\n .define($itemModel, { value: Model })\n .build();\n\n/**\n * The model of an object data.\n */\nexport type ObjectModel<V, EX extends AnyObject = EmptyObject, R extends keyof any = never> = Model<V, EX, R>;\n\nexport const ObjectModel = new CoreModelBuilder(Model, (): AnyObject => ({})).name('Object').build();\n\n/**\n * The model of an enum data.\n */\nexport type EnumModel<T extends typeof Enum> = Model<\n T[keyof T],\n Readonly<{\n [$enum]: T;\n }>\n>;\n\nexport const EnumModel = new CoreModelBuilder<(typeof Enum)[keyof typeof Enum]>(Model)\n .name('Enum')\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n .define($enum, { value: {} as typeof Enum })\n .defaultValueProvider((self) => Object.values(self[$enum])[0])\n .build();\n\n/**\n * The model of a union data.\n */\nexport type UnionModel<MM extends Model[]> = Model<Value<MM[number]>, Readonly<{ [$members]: MM }>>;\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,OAAO,YAAsD,aAAyB;AAMxF,MAAM,iBAAiB,IAAI,iBAAiB,OAAO,MAAe,MAAS,EAAE,KAAK,WAAW,EAAE,MAAM;AAMrG,MAAM,cAAc,IAAI,iBAAiB,gBAAgB,MAAM,EAAE,EAAE,KAAK,QAAQ,EAAE,MAAM;AAMxF,MAAM,cAAc,IAAI,iBAAiB,gBAAgB,MAAM,CAAC,EAAE,KAAK,QAAQ,EAAE,MAAM;AAMvF,MAAM,eAAe,IAAI,iBAAiB,gBAAgB,MAAM,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM;AAY7F,MAAM,aAAa,IAAI,iBAAiB,OAAO,MAAiB,CAAC,CAAC,EACtE,KAAK,OAAO,EACZ,OAAO,YAAY,EAAE,OAAO,MAAM,CAAC,EACnC,MAAM;AAOF,MAAM,cAAc,IAAI,iBAAiB,OAAO,OAAkB,CAAC,EAAE,EAAE,KAAK,QAAQ,EAAE,MAAM;AAY5F,MAAM,YAAY,IAAI,iBAAmD,KAAK,EAClF,KAAK,MAAM,EAEX,OAAO,OAAO,EAAE,OAAO,CAAC,EAAiB,CAAC,EAC1C,qBAAqB,CAAC,SAAS,OAAO,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,EAC5D,MAAM;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { EmptyObject } from 'type-fest';
|
|
2
|
+
import { ObjectModelBuilder } from './builders.js';
|
|
3
|
+
import { ArrayModel, EnumModel, type UnionModel } from './core.js';
|
|
4
|
+
import { type AnyObject, type Target, type Enum, type Extensions, Model, type References, type Value } from './model.js';
|
|
5
|
+
export * from './model.js';
|
|
6
|
+
export * from './core.js';
|
|
7
|
+
export type * from './builders.js';
|
|
8
|
+
/**
|
|
9
|
+
* The utility object that provides methods to create and manipulate models.
|
|
10
|
+
*/
|
|
11
|
+
declare const m: {
|
|
12
|
+
/**
|
|
13
|
+
* Attaches the given model to the target.
|
|
14
|
+
*
|
|
15
|
+
* @param model - The model to attach.
|
|
16
|
+
* @param target - The target to attach the model to. It could be a Binder
|
|
17
|
+
* instance, a Signal, or another object. However, it could never be another
|
|
18
|
+
* model.
|
|
19
|
+
*/
|
|
20
|
+
attach<M extends Model>(model: M, target: Target<Value<M>>): M;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new model that extends the given base model.
|
|
23
|
+
*
|
|
24
|
+
* @param base - The base model to extend.
|
|
25
|
+
*/
|
|
26
|
+
extend<M extends Model<AnyObject>>(base: M): ObjectModelBuilder<Value<M>, Value<M>, Extensions<M>, {
|
|
27
|
+
named: false;
|
|
28
|
+
selfRefKeys: References<M>;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new model that represents an optional value.
|
|
32
|
+
*
|
|
33
|
+
* @param base - The base model to extend.
|
|
34
|
+
*/
|
|
35
|
+
optional<M extends Model>(base: M): M;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new model that represents an array of items.
|
|
38
|
+
*
|
|
39
|
+
* @param itemModel - The model of the items in the array.
|
|
40
|
+
*/
|
|
41
|
+
array<M extends Model>(itemModel: M): ArrayModel<M>;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new model that represents an object.
|
|
44
|
+
*
|
|
45
|
+
* @param name - The name of the object.
|
|
46
|
+
*/
|
|
47
|
+
object<T extends AnyObject>(name: string): ObjectModelBuilder<T, EmptyObject, EmptyObject, {
|
|
48
|
+
named: true;
|
|
49
|
+
selfRefKeys: never;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new model that represents an enum.
|
|
53
|
+
*
|
|
54
|
+
* @param obj - The enum object to represent.
|
|
55
|
+
* @param name - The name of the model.
|
|
56
|
+
*/
|
|
57
|
+
enum<T extends typeof Enum>(obj: T, name: string): EnumModel<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Creates a new model that represents a union of the values of the given
|
|
60
|
+
* models.
|
|
61
|
+
*
|
|
62
|
+
* @param members - The models to create the union from.
|
|
63
|
+
*/
|
|
64
|
+
union<MM extends Model[]>(...members: MM): UnionModel<MM>;
|
|
65
|
+
/**
|
|
66
|
+
* Iterates over the given array model yielding an item model for each item
|
|
67
|
+
* the model value has.
|
|
68
|
+
*
|
|
69
|
+
* @param model - The array model to iterate over.
|
|
70
|
+
*/
|
|
71
|
+
items<V extends Model>(model: ArrayModel<V>): Generator<V, undefined, void>;
|
|
72
|
+
/**
|
|
73
|
+
* Provides the value the given model represents. For attached models it will
|
|
74
|
+
* be the owner value or its part, for detached models it will be the default
|
|
75
|
+
* value of the model.
|
|
76
|
+
*
|
|
77
|
+
* @param model - The model to get the value from.
|
|
78
|
+
*/
|
|
79
|
+
value<T>(model: Model<T>): T;
|
|
80
|
+
};
|
|
81
|
+
export default m;
|
|
82
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAoB,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAe,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EASL,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,EAEL,KAAK,UAAU,EACf,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AAEpB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,mBAAmB,eAAe,CAAC;AAmBnC;;GAEG;AACH,QAAA,MAAM,CAAC;IACL;;;;;;;OAOG;WACI,CAAC,SAAS,KAAK,SAAS,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAW9D;;;;OAIG;WACI,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,QACzB,CAAC,GACN,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC;IAItG;;;;OAIG;aACM,CAAC,SAAS,KAAK,QAAQ,CAAC,GAAG,CAAC;IAMrC;;;;OAIG;UACG,CAAC,SAAS,KAAK,aAAa,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAOnD;;;;OAIG;WACI,CAAC,SAAS,SAAS,QAClB,MAAM,GACX,kBAAkB,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAE,CAAC;IAIvF;;;;;OAKG;SACE,CAAC,SAAS,OAAO,IAAI,OAAO,CAAC,QAAQ,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAI/D;;;;;OAKG;UACG,EAAE,SAAS,KAAK,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC;IAOzD;;;;;OAKG;UACI,CAAC,SAAS,KAAK,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC;IAoB5E;;;;;;OAMG;UACG,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;CAM7B,CAAC;AAEF,eAAe,CAAC,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { CoreModelBuilder, ObjectModelBuilder } from "./builders.js";
|
|
2
|
+
import { ArrayModel, EnumModel, ObjectModel } from "./core.js";
|
|
3
|
+
import {
|
|
4
|
+
$defaultValue,
|
|
5
|
+
$enum,
|
|
6
|
+
$itemModel,
|
|
7
|
+
$key,
|
|
8
|
+
$members,
|
|
9
|
+
$name,
|
|
10
|
+
$optional,
|
|
11
|
+
$owner,
|
|
12
|
+
Model,
|
|
13
|
+
nothing
|
|
14
|
+
} from "./model.js";
|
|
15
|
+
export * from "./model.js";
|
|
16
|
+
export * from "./core.js";
|
|
17
|
+
const { defineProperty } = Object;
|
|
18
|
+
const arrayItemModels = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
function getRawValue(model) {
|
|
20
|
+
if (model[$owner] instanceof Model) {
|
|
21
|
+
const parentValue = getRawValue(model[$owner]);
|
|
22
|
+
return parentValue === nothing ? nothing : parentValue[model[$key]];
|
|
23
|
+
}
|
|
24
|
+
return model[$owner].value;
|
|
25
|
+
}
|
|
26
|
+
const m = {
|
|
27
|
+
/**
|
|
28
|
+
* Attaches the given model to the target.
|
|
29
|
+
*
|
|
30
|
+
* @param model - The model to attach.
|
|
31
|
+
* @param target - The target to attach the model to. It could be a Binder
|
|
32
|
+
* instance, a Signal, or another object. However, it could never be another
|
|
33
|
+
* model.
|
|
34
|
+
*/
|
|
35
|
+
attach(model, target) {
|
|
36
|
+
const _model = new CoreModelBuilder(model).name(`@${model[$name]}`).build();
|
|
37
|
+
defineProperty(_model, $owner, { value: target });
|
|
38
|
+
defineProperty(target, "model", { enumerable: true, configurable: true, value: model });
|
|
39
|
+
return _model;
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Creates a new model that extends the given base model.
|
|
43
|
+
*
|
|
44
|
+
* @param base - The base model to extend.
|
|
45
|
+
*/
|
|
46
|
+
extend(base) {
|
|
47
|
+
return new ObjectModelBuilder(base);
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new model that represents an optional value.
|
|
51
|
+
*
|
|
52
|
+
* @param base - The base model to extend.
|
|
53
|
+
*/
|
|
54
|
+
optional(base) {
|
|
55
|
+
return new CoreModelBuilder(base).define($optional, { value: true }).build();
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new model that represents an array of items.
|
|
59
|
+
*
|
|
60
|
+
* @param itemModel - The model of the items in the array.
|
|
61
|
+
*/
|
|
62
|
+
array(itemModel) {
|
|
63
|
+
return new CoreModelBuilder(ArrayModel).name(`Array<${itemModel[$name]}>`).define($itemModel, { value: itemModel }).build();
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new model that represents an object.
|
|
67
|
+
*
|
|
68
|
+
* @param name - The name of the object.
|
|
69
|
+
*/
|
|
70
|
+
object(name) {
|
|
71
|
+
return new ObjectModelBuilder(ObjectModel).name(name);
|
|
72
|
+
},
|
|
73
|
+
/**
|
|
74
|
+
* Creates a new model that represents an enum.
|
|
75
|
+
*
|
|
76
|
+
* @param obj - The enum object to represent.
|
|
77
|
+
* @param name - The name of the model.
|
|
78
|
+
*/
|
|
79
|
+
enum(obj, name) {
|
|
80
|
+
return new CoreModelBuilder(EnumModel).define($enum, { value: obj }).name(name).build();
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* Creates a new model that represents a union of the values of the given
|
|
84
|
+
* models.
|
|
85
|
+
*
|
|
86
|
+
* @param members - The models to create the union from.
|
|
87
|
+
*/
|
|
88
|
+
union(...members) {
|
|
89
|
+
return new CoreModelBuilder(Model, () => members[0][$defaultValue]).name(members.map((model) => model[$name]).join(" | ")).define($members, { value: members }).build();
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* Iterates over the given array model yielding an item model for each item
|
|
93
|
+
* the model value has.
|
|
94
|
+
*
|
|
95
|
+
* @param model - The array model to iterate over.
|
|
96
|
+
*/
|
|
97
|
+
*items(model) {
|
|
98
|
+
const list = arrayItemModels.get(model) ?? [];
|
|
99
|
+
arrayItemModels.set(model, list);
|
|
100
|
+
const value = m.value(model);
|
|
101
|
+
list.length = value.length;
|
|
102
|
+
for (let i = 0; i < value.length; i++) {
|
|
103
|
+
if (!list[i]) {
|
|
104
|
+
list[i] = new CoreModelBuilder(model[$itemModel], () => value[i]).name(`${model[$itemModel][$name]}[${i}]`).define($key, { value: i }).define($owner, { value: model }).build();
|
|
105
|
+
}
|
|
106
|
+
yield list[i];
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Provides the value the given model represents. For attached models it will
|
|
111
|
+
* be the owner value or its part, for detached models it will be the default
|
|
112
|
+
* value of the model.
|
|
113
|
+
*
|
|
114
|
+
* @param model - The model to get the value from.
|
|
115
|
+
*/
|
|
116
|
+
value(model) {
|
|
117
|
+
const value = getRawValue(model);
|
|
118
|
+
return value === nothing ? model[$defaultValue] : value;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var src_default = m;
|
|
122
|
+
export {
|
|
123
|
+
src_default as default
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EmptyObject } from 'type-fest';\nimport { CoreModelBuilder, ObjectModelBuilder } from './builders.js';\nimport { ArrayModel, EnumModel, ObjectModel, type UnionModel } from './core.js';\nimport {\n $defaultValue,\n $enum,\n $itemModel,\n $key,\n $members,\n $name,\n $optional,\n $owner,\n type AnyObject,\n type Target,\n type Enum,\n type Extensions,\n Model,\n nothing,\n type References,\n type Value,\n} from './model.js';\n\nexport * from './model.js';\nexport * from './core.js';\nexport type * from './builders.js';\n\nconst { defineProperty } = Object;\n\nconst arrayItemModels = new WeakMap<ArrayModel, Model[]>();\n\nfunction getRawValue<T>(model: Model<T>): T | typeof nothing {\n if (model[$owner] instanceof Model) {\n // If the current model is a property of another model, the owner is\n // definitely an object. So we just return the part of the value of\n // the owner.\n const parentValue = getRawValue(model[$owner] as Model<Record<keyof any, T>>);\n return parentValue === nothing ? nothing : parentValue[model[$key]];\n }\n\n // Otherwise, the owner is a Target, so we can return the full value.\n return (model[$owner] as Target<T>).value;\n}\n\n/**\n * The utility object that provides methods to create and manipulate models.\n */\nconst m = {\n /**\n * Attaches the given model to the target.\n *\n * @param model - The model to attach.\n * @param target - The target to attach the model to. It could be a Binder\n * instance, a Signal, or another object. However, it could never be another\n * model.\n */\n attach<M extends Model>(model: M, target: Target<Value<M>>): M {\n const _model = new CoreModelBuilder<Value<M>, Extensions<M>, { named: false; selfRefKeys: References<M> }>(model)\n .name(`@${model[$name]}`)\n .build();\n defineProperty(_model, $owner, { value: target });\n defineProperty(target, 'model', { enumerable: true, configurable: true, value: model });\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return _model as any;\n },\n\n /**\n * Creates a new model that extends the given base model.\n *\n * @param base - The base model to extend.\n */\n extend<M extends Model<AnyObject>>(\n base: M,\n ): ObjectModelBuilder<Value<M>, Value<M>, Extensions<M>, { named: false; selfRefKeys: References<M> }> {\n return new ObjectModelBuilder(base);\n },\n\n /**\n * Creates a new model that represents an optional value.\n *\n * @param base - The base model to extend.\n */\n optional<M extends Model>(base: M): M {\n return new CoreModelBuilder<Value<M>, Extensions<M>, { named: true; selfRefKeys: References<M> }>(base)\n .define($optional, { value: true })\n .build() as M;\n },\n\n /**\n * Creates a new model that represents an array of items.\n *\n * @param itemModel - The model of the items in the array.\n */\n array<M extends Model>(itemModel: M): ArrayModel<M> {\n return new CoreModelBuilder<Array<Value<M>>>(ArrayModel)\n .name(`Array<${itemModel[$name]}>`)\n .define($itemModel, { value: itemModel })\n .build();\n },\n\n /**\n * Creates a new model that represents an object.\n *\n * @param name - The name of the object.\n */\n object<T extends AnyObject>(\n name: string,\n ): ObjectModelBuilder<T, EmptyObject, EmptyObject, { named: true; selfRefKeys: never }> {\n return new ObjectModelBuilder(ObjectModel).name(name) as any;\n },\n\n /**\n * Creates a new model that represents an enum.\n *\n * @param obj - The enum object to represent.\n * @param name - The name of the model.\n */\n enum<T extends typeof Enum>(obj: T, name: string): EnumModel<T> {\n return new CoreModelBuilder<T[keyof T]>(EnumModel).define($enum, { value: obj }).name(name).build();\n },\n\n /**\n * Creates a new model that represents a union of the values of the given\n * models.\n *\n * @param members - The models to create the union from.\n */\n union<MM extends Model[]>(...members: MM): UnionModel<MM> {\n return new CoreModelBuilder(Model, () => members[0][$defaultValue] as Value<MM[number]>)\n .name(members.map((model) => model[$name]).join(' | '))\n .define($members, { value: members })\n .build();\n },\n\n /**\n * Iterates over the given array model yielding an item model for each item\n * the model value has.\n *\n * @param model - The array model to iterate over.\n */\n *items<V extends Model>(model: ArrayModel<V>): Generator<V, undefined, void> {\n const list = arrayItemModels.get(model) ?? [];\n arrayItemModels.set(model, list);\n const value = m.value(model);\n\n list.length = value.length;\n\n for (let i = 0; i < value.length; i++) {\n if (!list[i]) {\n list[i] = new CoreModelBuilder(model[$itemModel], () => value[i])\n .name(`${model[$itemModel][$name]}[${i}]`)\n .define($key, { value: i })\n .define($owner, { value: model })\n .build();\n }\n\n yield list[i] as V;\n }\n },\n\n /**\n * Provides the value the given model represents. For attached models it will\n * be the owner value or its part, for detached models it will be the default\n * value of the model.\n *\n * @param model - The model to get the value from.\n */\n value<T>(model: Model<T>): T {\n const value = getRawValue(model);\n\n // If the value is `nothing`, we return the default value of the model.\n return value === nothing ? model[$defaultValue] : value;\n },\n};\n\nexport default m;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/model.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { EmptyObject } from 'type-fest';
|
|
2
|
+
export interface JvmTypeRef {
|
|
3
|
+
jvmType: string;
|
|
4
|
+
genericArguments?: JvmTypeRef[];
|
|
5
|
+
}
|
|
6
|
+
export type AnnotationValue = AnnotationValue[] | JvmTypeRef | boolean | number | string | undefined;
|
|
7
|
+
export interface Annotation {
|
|
8
|
+
jvmType: string;
|
|
9
|
+
arguments: Record<string, AnnotationValue>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The metadata of a model.
|
|
13
|
+
*/
|
|
14
|
+
export interface ModelMetadata {
|
|
15
|
+
jvmType?: string;
|
|
16
|
+
annotations?: Annotation[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The target to which a model is attached. It could be a Binder instance, a
|
|
20
|
+
* Signal or another object. However, it could never be another model.
|
|
21
|
+
*/
|
|
22
|
+
export type Target<T = unknown> = Readonly<{
|
|
23
|
+
model?: Model<T>;
|
|
24
|
+
value: T;
|
|
25
|
+
}>;
|
|
26
|
+
export declare const nothing: unique symbol;
|
|
27
|
+
export declare enum Enum {
|
|
28
|
+
}
|
|
29
|
+
export type AnyObject = Readonly<Record<never, never>>;
|
|
30
|
+
/**
|
|
31
|
+
* The symbol that represents the {@link Model[$key]} property.
|
|
32
|
+
*/
|
|
33
|
+
export declare const $key: unique symbol;
|
|
34
|
+
/**
|
|
35
|
+
* The symbol that represents the {@link Model[$name]} property.
|
|
36
|
+
*/
|
|
37
|
+
export declare const $name: unique symbol;
|
|
38
|
+
/**
|
|
39
|
+
* The symbol that represents the {@link Model[$owner]} property.
|
|
40
|
+
*/
|
|
41
|
+
export declare const $owner: unique symbol;
|
|
42
|
+
/**
|
|
43
|
+
* The symbol that represents the {@link Model[$meta]} property.
|
|
44
|
+
*/
|
|
45
|
+
export declare const $meta: unique symbol;
|
|
46
|
+
/**
|
|
47
|
+
* The symbol that represents the {@link Model[$optional]} property.
|
|
48
|
+
*/
|
|
49
|
+
export declare const $optional: unique symbol;
|
|
50
|
+
/**
|
|
51
|
+
* The symbol that represents the {@link Model[$value]} property.
|
|
52
|
+
*/
|
|
53
|
+
export declare const $defaultValue: unique symbol;
|
|
54
|
+
/**
|
|
55
|
+
* The symbol that represents the {@link EnumModel[$enumerate]} property.
|
|
56
|
+
*/
|
|
57
|
+
export declare const $enum: unique symbol;
|
|
58
|
+
/**
|
|
59
|
+
* The symbol that represents the {@link UnionModel[$members]} property.
|
|
60
|
+
*/
|
|
61
|
+
export declare const $members: unique symbol;
|
|
62
|
+
/**
|
|
63
|
+
* The symbol that represents the {@link ArrayModel[$itemModel]} property.
|
|
64
|
+
*/
|
|
65
|
+
export declare const $itemModel: unique symbol;
|
|
66
|
+
/**
|
|
67
|
+
* Extracts the value type the model represents.
|
|
68
|
+
*/
|
|
69
|
+
export type Value<M extends Model> = M extends Model<infer T> ? T : never;
|
|
70
|
+
/**
|
|
71
|
+
* Extracts the list of extra properties of the model.
|
|
72
|
+
*/
|
|
73
|
+
export type Extensions<M extends Model> = M extends Model<unknown, infer EX> ? EX : EmptyObject;
|
|
74
|
+
/**
|
|
75
|
+
* Extracts the list of self-referencing properties of the model.
|
|
76
|
+
*/
|
|
77
|
+
export type References<M extends Model> = M extends Model<unknown, AnyObject, infer R> ? R : never;
|
|
78
|
+
/**
|
|
79
|
+
* A model that represents a specific type of data.
|
|
80
|
+
*
|
|
81
|
+
* @typeParam V - The type of the data described by the model.
|
|
82
|
+
* @typeParam EX - The extra properties of the model. It could be either a model
|
|
83
|
+
* that represents a property of the object the current model describe, or a
|
|
84
|
+
* model-specific metadata. It's recommended to use a symbol as a key for the
|
|
85
|
+
* metadata property to avoid the potential naming conflicts with the described
|
|
86
|
+
* object properties.
|
|
87
|
+
* @typeParam R - The keys of the self-referencing properties of the model.
|
|
88
|
+
*
|
|
89
|
+
* @remarks
|
|
90
|
+
* Since we know the full model definition only on this step, the `R` type
|
|
91
|
+
* parameter is essential to describe a model with self-reference properties.
|
|
92
|
+
*/
|
|
93
|
+
export type Model<V = unknown, EX extends AnyObject = EmptyObject, R extends keyof any = never> = EX & Readonly<{
|
|
94
|
+
[P in R]: Model<V, EX, R>;
|
|
95
|
+
}> & Readonly<{
|
|
96
|
+
/**
|
|
97
|
+
* The key of the model in the owner model.
|
|
98
|
+
*/
|
|
99
|
+
[$key]: keyof any;
|
|
100
|
+
/**
|
|
101
|
+
* The name of the model. For attached models, the name will be prefixed
|
|
102
|
+
* with the `@` symbol.
|
|
103
|
+
*/
|
|
104
|
+
[$name]: string;
|
|
105
|
+
/**
|
|
106
|
+
* The owner model of the model. For detached models, the owner will always
|
|
107
|
+
* be a specific global object `detachedTarget`.
|
|
108
|
+
*/
|
|
109
|
+
[$owner]: Model | Target;
|
|
110
|
+
/**
|
|
111
|
+
* The metadata of the model.
|
|
112
|
+
*/
|
|
113
|
+
[$meta]?: ModelMetadata;
|
|
114
|
+
/**
|
|
115
|
+
* Whether the model is optional. It describes if the data described by
|
|
116
|
+
* this model is nullable.
|
|
117
|
+
*/
|
|
118
|
+
[$optional]: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* The default value of the model.
|
|
121
|
+
*/
|
|
122
|
+
[$defaultValue]: V;
|
|
123
|
+
[Symbol.toStringTag]: string;
|
|
124
|
+
[Symbol.hasInstance](value: any): value is Model<V, EX, R>;
|
|
125
|
+
toString(): string;
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* A function that provides a default value for a model.
|
|
129
|
+
*
|
|
130
|
+
* @typeParam V - The type of the data described by the model.
|
|
131
|
+
* @typeParam EX - The extra properties of the model.
|
|
132
|
+
* @typeParam R - The keys of the self-referencing properties of the model.
|
|
133
|
+
*/
|
|
134
|
+
export type DefaultValueProvider<V, EX extends AnyObject = EmptyObject, R extends keyof any = never> = (model: Model<V, EX, R>) => V;
|
|
135
|
+
export declare const Model: Model;
|
|
136
|
+
//# sourceMappingURL=model.d.ts.map
|
package/model.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC;CACjC;AAED,MAAM,MAAM,eAAe,GAAG,eAAe,EAAE,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErG,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,CAAC;IACzC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,KAAK,EAAE,CAAC,CAAC;CACV,CAAC,CAAC;AAEH,eAAO,MAAM,OAAO,eAAoB,CAAC;AAYzC,MAAM,CAAC,OAAO,MAAM,IAAI;CAAG;AAE3B,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAGvD;;GAEG;AACH,eAAO,MAAM,IAAI,eAAgB,CAAC;AAElC;;GAEG;AACH,eAAO,MAAM,KAAK,eAAiB,CAAC;AAEpC;;GAEG;AACH,eAAO,MAAM,MAAM,eAAkB,CAAC;AAEtC;;GAEG;AACH,eAAO,MAAM,KAAK,eAAiB,CAAC;AAEpC;;GAEG;AACH,eAAO,MAAM,SAAS,eAAqB,CAAC;AAE5C;;GAEG;AACH,eAAO,MAAM,aAAa,eAAkB,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,KAAK,eAAsB,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,QAAQ,eAAoB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,UAAU,eAAsB,CAAC;AAI9C;;GAEG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;AAEhG;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEnG;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,SAAS,SAAS,GAAG,WAAW,EAAE,CAAC,SAAS,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE,GAClG,QAAQ,CAAC;KACN,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;CAC1B,CAAC,GACF,QAAQ,CAAC;IACP;;OAEG;IACH,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC;IAElB;;;OAGG;IACH,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC;IAExB;;;OAGG;IACH,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC7B,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,QAAQ,IAAI,MAAM,CAAC;CACpB,CAAC,CAAC;AAEL;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,EAAE,EAAE,SAAS,SAAS,GAAG,WAAW,EAAE,CAAC,SAAS,MAAM,GAAG,GAAG,KAAK,IAAI,CACrG,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KACnB,CAAC,CAAC;AAEP,eAAO,MAAM,KAAK,EAAE,KA8BlB,CAAC"}
|
package/model.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const nothing = Symbol("nothing");
|
|
2
|
+
const detachedTarget = Object.create(
|
|
3
|
+
{
|
|
4
|
+
toString: () => ":detached:"
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
model: { value: void 0 },
|
|
8
|
+
value: { value: nothing }
|
|
9
|
+
}
|
|
10
|
+
);
|
|
11
|
+
const $key = Symbol("key");
|
|
12
|
+
const $name = Symbol("name");
|
|
13
|
+
const $owner = Symbol("owner");
|
|
14
|
+
const $meta = Symbol("meta");
|
|
15
|
+
const $optional = Symbol("optional");
|
|
16
|
+
const $defaultValue = Symbol("value");
|
|
17
|
+
const $enum = Symbol("enumerate");
|
|
18
|
+
const $members = Symbol("members");
|
|
19
|
+
const $itemModel = Symbol("itemModel");
|
|
20
|
+
const Model = Object.create(null, {
|
|
21
|
+
[$key]: {
|
|
22
|
+
value: "model"
|
|
23
|
+
},
|
|
24
|
+
[$name]: {
|
|
25
|
+
value: "Model"
|
|
26
|
+
},
|
|
27
|
+
[$owner]: {
|
|
28
|
+
value: detachedTarget
|
|
29
|
+
},
|
|
30
|
+
[$meta]: {},
|
|
31
|
+
[$optional]: {
|
|
32
|
+
value: false
|
|
33
|
+
},
|
|
34
|
+
[$defaultValue]: {},
|
|
35
|
+
[Symbol.toStringTag]: {
|
|
36
|
+
get() {
|
|
37
|
+
return this[$name];
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
[Symbol.hasInstance]: {
|
|
41
|
+
value(o) {
|
|
42
|
+
return typeof o === "object" && o != null && (this === o || Object.prototype.isPrototypeOf.call(this, o));
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
toString: {
|
|
46
|
+
value() {
|
|
47
|
+
return `[${String(this[$owner])} / ${String(this[$key])}${this[$optional] ? "?" : ""}] ${this[$name]}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
export {
|
|
52
|
+
$defaultValue,
|
|
53
|
+
$enum,
|
|
54
|
+
$itemModel,
|
|
55
|
+
$key,
|
|
56
|
+
$members,
|
|
57
|
+
$meta,
|
|
58
|
+
$name,
|
|
59
|
+
$optional,
|
|
60
|
+
$owner,
|
|
61
|
+
Model,
|
|
62
|
+
nothing
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=model.js.map
|
package/model.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/model.ts"],
|
|
4
|
+
"sourcesContent": ["import type { EmptyObject } from 'type-fest';\n\nexport interface JvmTypeRef {\n jvmType: string;\n genericArguments?: JvmTypeRef[];\n}\n\nexport type AnnotationValue = AnnotationValue[] | JvmTypeRef | boolean | number | string | undefined;\n\nexport interface Annotation {\n jvmType: string;\n arguments: Record<string, AnnotationValue>;\n}\n\n/**\n * The metadata of a model.\n */\nexport interface ModelMetadata {\n jvmType?: string;\n annotations?: Annotation[];\n}\n\n/**\n * The target to which a model is attached. It could be a Binder instance, a\n * Signal or another object. However, it could never be another model.\n */\nexport type Target<T = unknown> = Readonly<{\n model?: Model<T>;\n value: T;\n}>;\n\nexport const nothing = Symbol('nothing');\n\nconst detachedTarget: Target = Object.create(\n {\n toString: () => ':detached:',\n },\n {\n model: { value: undefined },\n value: { value: nothing },\n },\n);\n\nexport declare enum Enum {}\n\nexport type AnyObject = Readonly<Record<never, never>>; // {}\n\n/* eslint-disable tsdoc/syntax */\n/**\n * The symbol that represents the {@link Model[$key]} property.\n */\nexport const $key = Symbol('key');\n\n/**\n * The symbol that represents the {@link Model[$name]} property.\n */\nexport const $name = Symbol('name');\n\n/**\n * The symbol that represents the {@link Model[$owner]} property.\n */\nexport const $owner = Symbol('owner');\n\n/**\n * The symbol that represents the {@link Model[$meta]} property.\n */\nexport const $meta = Symbol('meta');\n\n/**\n * The symbol that represents the {@link Model[$optional]} property.\n */\nexport const $optional = Symbol('optional');\n\n/**\n * The symbol that represents the {@link Model[$value]} property.\n */\nexport const $defaultValue = Symbol('value');\n\n/**\n * The symbol that represents the {@link EnumModel[$enumerate]} property.\n */\nexport const $enum = Symbol('enumerate');\n\n/**\n * The symbol that represents the {@link UnionModel[$members]} property.\n */\nexport const $members = Symbol('members');\n\n/**\n * The symbol that represents the {@link ArrayModel[$itemModel]} property.\n */\nexport const $itemModel = Symbol('itemModel');\n\n/* eslint-enable tsdoc/syntax */\n\n/**\n * Extracts the value type the model represents.\n */\nexport type Value<M extends Model> = M extends Model<infer T> ? T : never;\n\n/**\n * Extracts the list of extra properties of the model.\n */\nexport type Extensions<M extends Model> = M extends Model<unknown, infer EX> ? EX : EmptyObject;\n\n/**\n * Extracts the list of self-referencing properties of the model.\n */\nexport type References<M extends Model> = M extends Model<unknown, AnyObject, infer R> ? R : never;\n\n/**\n * A model that represents a specific type of data.\n *\n * @typeParam V - The type of the data described by the model.\n * @typeParam EX - The extra properties of the model. It could be either a model\n * that represents a property of the object the current model describe, or a\n * model-specific metadata. It's recommended to use a symbol as a key for the\n * metadata property to avoid the potential naming conflicts with the described\n * object properties.\n * @typeParam R - The keys of the self-referencing properties of the model.\n *\n * @remarks\n * Since we know the full model definition only on this step, the `R` type\n * parameter is essential to describe a model with self-reference properties.\n */\nexport type Model<V = unknown, EX extends AnyObject = EmptyObject, R extends keyof any = never> = EX &\n Readonly<{\n [P in R]: Model<V, EX, R>;\n }> &\n Readonly<{\n /**\n * The key of the model in the owner model.\n */\n [$key]: keyof any;\n\n /**\n * The name of the model. For attached models, the name will be prefixed\n * with the `@` symbol.\n */\n [$name]: string;\n\n /**\n * The owner model of the model. For detached models, the owner will always\n * be a specific global object `detachedTarget`.\n */\n [$owner]: Model | Target;\n\n /**\n * The metadata of the model.\n */\n [$meta]?: ModelMetadata;\n\n /**\n * Whether the model is optional. It describes if the data described by\n * this model is nullable.\n */\n [$optional]: boolean;\n\n /**\n * The default value of the model.\n */\n [$defaultValue]: V;\n [Symbol.toStringTag]: string;\n [Symbol.hasInstance](value: any): value is Model<V, EX, R>;\n toString(): string;\n }>;\n\n/**\n * A function that provides a default value for a model.\n *\n * @typeParam V - The type of the data described by the model.\n * @typeParam EX - The extra properties of the model.\n * @typeParam R - The keys of the self-referencing properties of the model.\n */\nexport type DefaultValueProvider<V, EX extends AnyObject = EmptyObject, R extends keyof any = never> = (\n model: Model<V, EX, R>,\n) => V;\n\nexport const Model: Model = Object.create(null, {\n [$key]: {\n value: 'model',\n },\n [$name]: {\n value: 'Model',\n },\n [$owner]: {\n value: detachedTarget,\n },\n [$meta]: {},\n [$optional]: {\n value: false,\n },\n [$defaultValue]: {},\n [Symbol.toStringTag]: {\n get(this: Model) {\n return this[$name];\n },\n },\n [Symbol.hasInstance]: {\n value(this: Model, o: unknown) {\n return typeof o === 'object' && o != null && (this === o || Object.prototype.isPrototypeOf.call(this, o));\n },\n },\n toString: {\n value(this: Model) {\n return `[${String(this[$owner])} / ${String(this[$key])}${this[$optional] ? '?' : ''}] ${this[$name]}`;\n },\n },\n});\n"],
|
|
5
|
+
"mappings": "AA+BO,MAAM,UAAU,OAAO,SAAS;AAEvC,MAAM,iBAAyB,OAAO;AAAA,EACpC;AAAA,IACE,UAAU,MAAM;AAAA,EAClB;AAAA,EACA;AAAA,IACE,OAAO,EAAE,OAAO,OAAU;AAAA,IAC1B,OAAO,EAAE,OAAO,QAAQ;AAAA,EAC1B;AACF;AAUO,MAAM,OAAO,OAAO,KAAK;AAKzB,MAAM,QAAQ,OAAO,MAAM;AAK3B,MAAM,SAAS,OAAO,OAAO;AAK7B,MAAM,QAAQ,OAAO,MAAM;AAK3B,MAAM,YAAY,OAAO,UAAU;AAKnC,MAAM,gBAAgB,OAAO,OAAO;AAKpC,MAAM,QAAQ,OAAO,WAAW;AAKhC,MAAM,WAAW,OAAO,SAAS;AAKjC,MAAM,aAAa,OAAO,WAAW;AAuFrC,MAAM,QAAe,OAAO,OAAO,MAAM;AAAA,EAC9C,CAAC,IAAI,GAAG;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,CAAC,KAAK,GAAG;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,CAAC,MAAM,GAAG;AAAA,IACR,OAAO;AAAA,EACT;AAAA,EACA,CAAC,KAAK,GAAG,CAAC;AAAA,EACV,CAAC,SAAS,GAAG;AAAA,IACX,OAAO;AAAA,EACT;AAAA,EACA,CAAC,aAAa,GAAG,CAAC;AAAA,EAClB,CAAC,OAAO,WAAW,GAAG;AAAA,IACpB,MAAiB;AACf,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EACA,CAAC,OAAO,WAAW,GAAG;AAAA,IACpB,MAAmB,GAAY;AAC7B,aAAO,OAAO,MAAM,YAAY,KAAK,SAAS,SAAS,KAAK,OAAO,UAAU,cAAc,KAAK,MAAM,CAAC;AAAA,IACzG;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,QAAmB;AACjB,aAAO,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,MAAM,OAAO,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,MAAM,EAAE,KAAK,KAAK,KAAK,CAAC;AAAA,IACtG;AAAA,EACF;AACF,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vaadin/hilla-models",
|
|
3
|
+
"version": "24.5.0-alpha10",
|
|
4
|
+
"description": "Generative form models for Hilla",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "index.js",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/vaadin/hilla.git",
|
|
11
|
+
"directory": "packages/ts/form-models"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"Hilla",
|
|
15
|
+
"Form",
|
|
16
|
+
"Models"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"clean:build": "git clean -fx . -e .vite -e node_modules",
|
|
20
|
+
"build": "concurrently npm:build:*",
|
|
21
|
+
"build:esbuild": "tsx ../../../scripts/build.ts",
|
|
22
|
+
"build:dts": "tsc --isolatedModules -p tsconfig.build.json",
|
|
23
|
+
"build:copy": "cd src && copyfiles **/*.d.ts ..",
|
|
24
|
+
"lint": "eslint src test",
|
|
25
|
+
"lint:fix": "eslint src test --fix",
|
|
26
|
+
"test": "mocha test/**/*.spec.ts --config ../../../.mocharc.cjs",
|
|
27
|
+
"test:coverage": "c8 --experimental-monocart -c ../../../.c8rc.json npm test",
|
|
28
|
+
"test:watch": "npm run test -- --watch",
|
|
29
|
+
"typecheck": "tsc --noEmit"
|
|
30
|
+
},
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"default": "./index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"author": "Vaadin Ltd",
|
|
37
|
+
"license": "Apache-2.0",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/vaadin/hilla/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://hilla.dev",
|
|
42
|
+
"files": [
|
|
43
|
+
"*.{d.ts.map,d.ts,js.map,js}"
|
|
44
|
+
],
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@vaadin/hilla-lit-form": "24.5.0-alpha10"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"react": "^18"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@esm-bundle/chai": "^4.3.4-fix.0",
|
|
56
|
+
"@testing-library/react": "^14.0.0",
|
|
57
|
+
"@testing-library/user-event": "^14.5.1",
|
|
58
|
+
"@types/chai": "^4.3.6",
|
|
59
|
+
"@types/chai-as-promised": "^7.1.8",
|
|
60
|
+
"@types/chai-dom": "^1.11.1",
|
|
61
|
+
"@types/chai-like": "^1.1.3",
|
|
62
|
+
"@types/mocha": "^10.0.2",
|
|
63
|
+
"@types/node": "^20.14.2",
|
|
64
|
+
"@types/react": "^18.2.23",
|
|
65
|
+
"@types/sinon": "^10.0.17",
|
|
66
|
+
"@types/sinon-chai": "^3.2.10",
|
|
67
|
+
"@types/validator": "^13.11.2",
|
|
68
|
+
"c8": "^10.1.2",
|
|
69
|
+
"chai-as-promised": "^7.1.1",
|
|
70
|
+
"chai-dom": "^1.11.0",
|
|
71
|
+
"glob": "^10.4.1",
|
|
72
|
+
"mocha": "^10.4.0",
|
|
73
|
+
"monocart-coverage-reports": "^2.8.4",
|
|
74
|
+
"sinon": "^16.0.0",
|
|
75
|
+
"sinon-chai": "^3.7.0",
|
|
76
|
+
"typescript": "5.5.2"
|
|
77
|
+
}
|
|
78
|
+
}
|