@microsoft/fast-html 1.0.0-alpha.18 → 1.0.0-alpha.19

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/README.md CHANGED
@@ -22,12 +22,12 @@ npm install --save @microsoft/fast-html
22
22
  In your JS bundle you will need to include the `@microsoft/fast-html` package:
23
23
 
24
24
  ```typescript
25
- import { TemplateElement } from "@microsoft/fast-html";
25
+ import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
26
26
  import { MyCustomElement } from "./my-custom-element";
27
27
 
28
- MyCustomElement.define({
28
+ RenderableFASTElement(MyCustomElement).defineAsync({
29
29
  name: "my-custom-element",
30
- shadowOptions: null,
30
+ templateOptions: "defer-and-hydrate",
31
31
  });
32
32
 
33
33
  TemplateElement.define({
@@ -35,9 +35,7 @@ TemplateElement.define({
35
35
  });
36
36
  ```
37
37
 
38
- This will include the `<f-template>` custom element and all logic for interpreting the declarative HTML syntax for a FAST web component as well as the `shadowOptions` for any element an `<f-template>` has been used to define.
39
-
40
- It is necessary to set the initial `shadowOptions` of your custom elements to `null` otherwise a shadowRoot will be attached and cause a FOUC (Flash Of Unstyled Content). For more information about how this affects hydration, check out our [document](./RENDERING.md#setting-shadow-options) on rendering DOM from a non-browser environment.
38
+ This will include the `<f-template>` custom element and all logic for interpreting the declarative HTML syntax for a FAST web component.
41
39
 
42
40
  The template must be wrapped in `<f-template name="[custom-element-name]"><template>[template logic]</template></f-template>` with a `name` attribute for the custom elements name, and the template logic inside.
43
41
 
@@ -77,23 +75,19 @@ TemplateElement.options({
77
75
 
78
76
  #### Using the RenderableFASTElement
79
77
 
80
- The exported abstract class `RenderableFASTElement` is available for automatic addition and removal of `defer-hydration` and `needs-hydration`. If you use `FASTElement` you will need to add `defer-hydration` and `needs-hydration` attributes to your rendered markup and remove them via your component.
78
+ The use of `RenderableFASTElement` as a mixin for your custom element will automatically remove the `defer-hydration` attribute signalling for hydration to begin, and if you need to add state before hydration should occur you can make use of the `prepare` method.
81
79
 
82
80
  Example:
83
81
  ```typescript
84
- import { RenderableFASTElement, TemplateElement } from "@microsoft/fast-html";
85
-
86
- class MyCustomElement extends RenderableFASTElement {
87
- // component logic
82
+ class MyCustomElement extends FASTElement {
83
+ private prepare(): Promise<void> {
84
+ // Get initial state
85
+ }
88
86
  }
89
87
 
90
- MyCustomElement.define({
88
+ RenderableFASTElement(MyCustomElement).defineAsync({
91
89
  name: "my-custom-element",
92
- shadowOptions: null,
93
- });
94
-
95
- TemplateElement.define({
96
- name: "f-template",
90
+ templateOptions: "defer-and-hydrate",
97
91
  });
98
92
  ```
99
93
 
@@ -0,0 +1,126 @@
1
+ interface JSONSchemaDefinition extends JSONSchemaCommon {
2
+ $fast_context: string;
3
+ $fast_parent_contexts: Array<string>;
4
+ }
5
+ interface JSONSchemaCommon {
6
+ type?: string;
7
+ properties?: any;
8
+ }
9
+ interface JSONSchema extends JSONSchemaCommon {
10
+ $schema: string;
11
+ $id: string;
12
+ $defs?: Record<string, JSONSchemaDefinition>;
13
+ $ref?: string;
14
+ }
15
+ type AccessCachedPathType = "access";
16
+ export interface AccessCachedPath {
17
+ type: AccessCachedPathType;
18
+ currentContext: string | null;
19
+ path: string;
20
+ }
21
+ type DefaultCachedPathType = "default";
22
+ export interface DefaultCachedPath {
23
+ type: DefaultCachedPathType;
24
+ currentContext: string | null;
25
+ path: string;
26
+ }
27
+ type EventCachedPathType = "event";
28
+ export interface EventCachedPath {
29
+ type: EventCachedPathType;
30
+ currentContext: string | null;
31
+ path: string;
32
+ }
33
+ type RepeatCachedPathType = "repeat";
34
+ export interface RepeatCachedPath {
35
+ type: RepeatCachedPathType;
36
+ parentContext: string | null;
37
+ currentContext: string;
38
+ path: string;
39
+ }
40
+ export type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;
41
+ export type CachedPathMap = Map<string, JSONSchema>;
42
+ interface RegisterPathConfig {
43
+ rootPropertyName: string;
44
+ pathConfig: CachedPath;
45
+ }
46
+ /**
47
+ * A constructed JSON schema from a template
48
+ */
49
+ export declare class Schema {
50
+ /**
51
+ * The name of the custom element
52
+ */
53
+ private customElementName;
54
+ /**
55
+ * A JSON schema describing each root schema
56
+ */
57
+ private jsonSchemaMap;
58
+ constructor(name: string);
59
+ /**
60
+ * Add a path to a schema
61
+ * @param config RegisterPathConfig
62
+ */
63
+ addPath(config: RegisterPathConfig): void;
64
+ /**
65
+ * Gets the JSON schema for a property name
66
+ * @param rootPropertyName - the root property the JSON schema is mapped to
67
+ * @returns The JSON schema for the root property
68
+ */
69
+ getSchema(rootPropertyName: string): JSONSchema | null;
70
+ /**
71
+ * Get a path split into property names
72
+ * @param path The dot syntax path e.g. a.b.c
73
+ * @returns An array of items in the path
74
+ */
75
+ private getSplitPath;
76
+ /**
77
+ * Gets the path to the $def
78
+ * @param context The context name e.g. {{item in items}} in a repeat creates the "item" context
79
+ * @returns A string to use as a $ref
80
+ */
81
+ private getDefsPath;
82
+ /**
83
+ * Add a new JSON schema to the JSON schema map
84
+ * @param propertyName The name of the property to assign this JSON schema to
85
+ */
86
+ private addNewSchema;
87
+ /**
88
+ * Add properties to a context
89
+ * @param schema The schema to add the properties to
90
+ * @param splitPath The path split into property/context names
91
+ * @param context The paths context
92
+ */
93
+ private addPropertiesToAContext;
94
+ /**
95
+ * Add properties to an object
96
+ * @param schema The schema to add the properties to
97
+ * @param splitPath The path split into property/context names
98
+ * @param context The paths context
99
+ * @param type The data type (see JSON schema for details)
100
+ */
101
+ private addPropertiesToAnObject;
102
+ /**
103
+ * Add an array to an object property
104
+ * @param schema The schema to add the properties to
105
+ * @param context The name of the context
106
+ */
107
+ private addArrayToAnObject;
108
+ /**
109
+ * Add a context to the $defs property
110
+ * @param schema The schema to use
111
+ * @param propertyName The name of the property the context belongs to
112
+ * @param currentContext The current context
113
+ * @param parentContext The parent context
114
+ * @returns
115
+ */
116
+ private addContext;
117
+ /**
118
+ * Get parent contexts
119
+ * @param schema The schema to use
120
+ * @param parentContext The parent context
121
+ * @param contexts A list of parent contexts
122
+ * @returns
123
+ */
124
+ private getParentContexts;
125
+ }
126
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,196 @@
1
+ // The context, in most cases the array property e.g. users
2
+ const fastContextMetaData = "$fast_context";
3
+ // The list of contexts preceeding this context, the first of which should be the root property
4
+ const fastContextsMetaData = "$fast_parent_contexts";
5
+ const defsPropertyName = "$defs";
6
+ const refPropertyName = "$ref";
7
+ /**
8
+ * A constructed JSON schema from a template
9
+ */
10
+ export class Schema {
11
+ constructor(name) {
12
+ /**
13
+ * A JSON schema describing each root schema
14
+ */
15
+ this.jsonSchemaMap = new Map();
16
+ this.customElementName = name;
17
+ }
18
+ /**
19
+ * Add a path to a schema
20
+ * @param config RegisterPathConfig
21
+ */
22
+ addPath(config) {
23
+ var _a, _b;
24
+ const splitPath = this.getSplitPath(config.pathConfig.path);
25
+ let schema = this.jsonSchemaMap.get(config.rootPropertyName);
26
+ // Create a root level property JSON
27
+ if (!schema) {
28
+ this.addNewSchema(config.rootPropertyName);
29
+ schema = this.jsonSchemaMap.get(config.rootPropertyName);
30
+ }
31
+ switch (config.pathConfig.type) {
32
+ case "default":
33
+ case "access": {
34
+ if (config.pathConfig.currentContext === null) {
35
+ this.addPropertiesToAnObject(schema, splitPath.slice(1), config.pathConfig.currentContext);
36
+ }
37
+ else {
38
+ this.addPropertiesToAContext((_a = schema === null || schema === void 0 ? void 0 : schema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[splitPath[0]], splitPath.slice(1), config.pathConfig.currentContext);
39
+ }
40
+ break;
41
+ }
42
+ case "repeat": {
43
+ this.addContext(schema, splitPath[splitPath.length - 1], // example items
44
+ config.pathConfig.currentContext, // example item
45
+ config.pathConfig.parentContext);
46
+ if (splitPath.length > 2) {
47
+ let updatedSchema = schema;
48
+ if (config.pathConfig.parentContext) {
49
+ updatedSchema = this.addPropertiesToAnObject((_b = schema[defsPropertyName]) === null || _b === void 0 ? void 0 : _b[config.pathConfig.parentContext], splitPath.slice(1, -1), config.pathConfig.parentContext);
50
+ }
51
+ this.addPropertiesToAnObject(updatedSchema, splitPath.slice(-1), config.pathConfig.currentContext, "array");
52
+ }
53
+ else if (splitPath.length > 1) {
54
+ this.addPropertiesToAnObject(schema, splitPath.slice(1), config.pathConfig.currentContext, "array");
55
+ }
56
+ else {
57
+ schema.type = "array";
58
+ schema[refPropertyName] = this.getDefsPath(config.pathConfig.currentContext);
59
+ }
60
+ break;
61
+ }
62
+ }
63
+ }
64
+ /**
65
+ * Gets the JSON schema for a property name
66
+ * @param rootPropertyName - the root property the JSON schema is mapped to
67
+ * @returns The JSON schema for the root property
68
+ */
69
+ getSchema(rootPropertyName) {
70
+ var _a;
71
+ return (_a = this.jsonSchemaMap.get(rootPropertyName)) !== null && _a !== void 0 ? _a : null;
72
+ }
73
+ /**
74
+ * Get a path split into property names
75
+ * @param path The dot syntax path e.g. a.b.c
76
+ * @returns An array of items in the path
77
+ */
78
+ getSplitPath(path) {
79
+ return path.split(".");
80
+ }
81
+ /**
82
+ * Gets the path to the $def
83
+ * @param context The context name e.g. {{item in items}} in a repeat creates the "item" context
84
+ * @returns A string to use as a $ref
85
+ */
86
+ getDefsPath(context) {
87
+ return `#/${defsPropertyName}/${context}`;
88
+ }
89
+ /**
90
+ * Add a new JSON schema to the JSON schema map
91
+ * @param propertyName The name of the property to assign this JSON schema to
92
+ */
93
+ addNewSchema(propertyName) {
94
+ this.jsonSchemaMap.set(propertyName, {
95
+ $schema: "https://json-schema.org/draft/2019-09/schema",
96
+ $id: `https://fast.design/schemas/${this.customElementName}/${propertyName}.json`,
97
+ [defsPropertyName]: {},
98
+ });
99
+ }
100
+ /**
101
+ * Add properties to a context
102
+ * @param schema The schema to add the properties to
103
+ * @param splitPath The path split into property/context names
104
+ * @param context The paths context
105
+ */
106
+ addPropertiesToAContext(schema, splitPath, context) {
107
+ schema.type = "object";
108
+ if (schema.properties) {
109
+ schema.properties[splitPath[0]] = {};
110
+ }
111
+ else {
112
+ schema.properties = {
113
+ [splitPath[0]]: {},
114
+ };
115
+ }
116
+ if (splitPath.length > 1) {
117
+ this.addPropertiesToAnObject(schema.properties[splitPath[0]], splitPath.slice(1), context);
118
+ }
119
+ }
120
+ /**
121
+ * Add properties to an object
122
+ * @param schema The schema to add the properties to
123
+ * @param splitPath The path split into property/context names
124
+ * @param context The paths context
125
+ * @param type The data type (see JSON schema for details)
126
+ */
127
+ addPropertiesToAnObject(schema, splitPath, context, type = "object") {
128
+ schema.type = "object";
129
+ if (schema.properties) {
130
+ schema.properties[splitPath[0]] = {};
131
+ }
132
+ else {
133
+ schema.properties = {
134
+ [splitPath[0]]: {},
135
+ };
136
+ }
137
+ if (context === null && type === "object" && splitPath.length > 1) {
138
+ return this.addPropertiesToAnObject(schema.properties[splitPath[0]], splitPath.slice(1), context, type);
139
+ }
140
+ else if (type === "array") {
141
+ if (splitPath.length > 1) {
142
+ return this.addPropertiesToAnObject(schema.properties[splitPath[0]], splitPath.slice(1), context, type);
143
+ }
144
+ else {
145
+ return this.addArrayToAnObject(schema.properties[splitPath[0]], context);
146
+ }
147
+ }
148
+ return schema.properties[splitPath[0]];
149
+ }
150
+ /**
151
+ * Add an array to an object property
152
+ * @param schema The schema to add the properties to
153
+ * @param context The name of the context
154
+ */
155
+ addArrayToAnObject(schema, context) {
156
+ schema.type = "array";
157
+ schema.items = {
158
+ [refPropertyName]: this.getDefsPath(context),
159
+ };
160
+ return schema.items;
161
+ }
162
+ /**
163
+ * Add a context to the $defs property
164
+ * @param schema The schema to use
165
+ * @param propertyName The name of the property the context belongs to
166
+ * @param currentContext The current context
167
+ * @param parentContext The parent context
168
+ * @returns
169
+ */
170
+ addContext(schema, propertyName, // e.g items
171
+ currentContext, // e.g. item
172
+ parentContext) {
173
+ if (schema[defsPropertyName][currentContext]) {
174
+ return;
175
+ }
176
+ schema[defsPropertyName][currentContext] = {
177
+ [fastContextMetaData]: propertyName,
178
+ [fastContextsMetaData]: this.getParentContexts(schema, parentContext),
179
+ };
180
+ }
181
+ /**
182
+ * Get parent contexts
183
+ * @param schema The schema to use
184
+ * @param parentContext The parent context
185
+ * @param contexts A list of parent contexts
186
+ * @returns
187
+ */
188
+ getParentContexts(schema, parentContext, contexts = []) {
189
+ var _a;
190
+ if (parentContext === null) {
191
+ return [null, ...contexts];
192
+ }
193
+ const parentParentContext = (_a = schema === null || schema === void 0 ? void 0 : schema[defsPropertyName]) === null || _a === void 0 ? void 0 : _a[parentContext].$fast_parent_contexts;
194
+ return this.getParentContexts(schema, parentParentContext.at(-1), [parentContext, ...contexts]);
195
+ }
196
+ }
@@ -0,0 +1,248 @@
1
+ import { __awaiter } from "tslib";
2
+ import { expect, test } from "@playwright/test";
3
+ import { Schema } from "./schema.js";
4
+ test.describe("Schema", () => __awaiter(void 0, void 0, void 0, function* () {
5
+ test("should instantiate with a custom element name without throwing", () => __awaiter(void 0, void 0, void 0, function* () {
6
+ expect(() => new Schema("my-custom-element")).not.toThrow();
7
+ }));
8
+ test("should return null when a JSON schema is requested but none exists for that property name", () => __awaiter(void 0, void 0, void 0, function* () {
9
+ const schema = new Schema("my-custom-element");
10
+ expect(schema.getSchema("foo")).toEqual(null);
11
+ }));
12
+ test("should be able to return a JSON schema after adding a path", () => __awaiter(void 0, void 0, void 0, function* () {
13
+ const schema = new Schema("my-custom-element");
14
+ schema.addPath({
15
+ rootPropertyName: "a",
16
+ pathConfig: {
17
+ type: "default",
18
+ path: "a",
19
+ currentContext: null,
20
+ }
21
+ });
22
+ const schemaA = schema.getSchema("a");
23
+ expect(schemaA).not.toBe(null);
24
+ expect(schemaA.$id).toEqual("https://fast.design/schemas/my-custom-element/a.json");
25
+ expect(schemaA.$schema).toEqual("https://json-schema.org/draft/2019-09/schema");
26
+ }));
27
+ test("should add a property and cast the schema as type object if a nested path is given", () => __awaiter(void 0, void 0, void 0, function* () {
28
+ const schema = new Schema("my-custom-element");
29
+ schema.addPath({
30
+ rootPropertyName: "a",
31
+ pathConfig: {
32
+ type: "default",
33
+ path: "a.b",
34
+ currentContext: null,
35
+ },
36
+ });
37
+ let schemaA = schema.getSchema("a");
38
+ expect(schemaA.properties).toBeDefined();
39
+ expect(schemaA.properties).toHaveProperty("b");
40
+ schema.addPath({
41
+ rootPropertyName: "a",
42
+ pathConfig: {
43
+ type: "default",
44
+ path: "a.b.c",
45
+ currentContext: null,
46
+ },
47
+ });
48
+ schemaA = schema.getSchema("a");
49
+ expect(schemaA.properties).toBeDefined();
50
+ expect(schemaA.properties).toHaveProperty("b");
51
+ expect(schemaA.properties.b.properties).toBeDefined();
52
+ expect(schemaA.properties.b.properties).toHaveProperty("c");
53
+ }));
54
+ test("should add a new context in a schema", () => __awaiter(void 0, void 0, void 0, function* () {
55
+ var _a, _b, _c;
56
+ const schema = new Schema("my-custom-element");
57
+ schema.addPath({
58
+ rootPropertyName: "items",
59
+ pathConfig: {
60
+ type: "repeat",
61
+ path: "items",
62
+ currentContext: "item",
63
+ parentContext: null,
64
+ },
65
+ });
66
+ const schemaA = schema.getSchema("items");
67
+ expect(schemaA).toBeDefined();
68
+ expect(schemaA.$ref).toBeDefined();
69
+ expect(schemaA.$ref).toEqual("#/$defs/item");
70
+ expect(schemaA.type).toEqual("array");
71
+ expect((_a = schemaA.$defs) === null || _a === void 0 ? void 0 : _a["item"]).toBeDefined();
72
+ expect((_b = schemaA.$defs) === null || _b === void 0 ? void 0 : _b["item"].$fast_context).toEqual("items");
73
+ expect((_c = schemaA.$defs) === null || _c === void 0 ? void 0 : _c["item"].$fast_parent_contexts).toEqual([null]);
74
+ }));
75
+ test("should add a nested context in a schema", () => __awaiter(void 0, void 0, void 0, function* () {
76
+ var _d, _e, _f, _g, _h;
77
+ const schema = new Schema("my-custom-element");
78
+ schema.addPath({
79
+ rootPropertyName: "a",
80
+ pathConfig: {
81
+ type: "default",
82
+ path: "a",
83
+ currentContext: null,
84
+ },
85
+ });
86
+ schema.addPath({
87
+ rootPropertyName: "a",
88
+ pathConfig: {
89
+ type: "repeat",
90
+ path: "a.items",
91
+ currentContext: "item",
92
+ parentContext: null,
93
+ },
94
+ });
95
+ const schemaA = schema.getSchema("a");
96
+ expect(schemaA).toBeDefined();
97
+ expect((_d = schemaA === null || schemaA === void 0 ? void 0 : schemaA.properties) === null || _d === void 0 ? void 0 : _d["items"]).toBeDefined();
98
+ expect((_e = schemaA === null || schemaA === void 0 ? void 0 : schemaA.properties) === null || _e === void 0 ? void 0 : _e["items"].items.$ref).toEqual("#/$defs/item");
99
+ expect((_f = schemaA.$defs) === null || _f === void 0 ? void 0 : _f["item"]).toBeDefined();
100
+ expect((_g = schemaA.$defs) === null || _g === void 0 ? void 0 : _g["item"].$fast_context).toEqual("items");
101
+ expect((_h = schemaA.$defs) === null || _h === void 0 ? void 0 : _h["item"].$fast_parent_contexts).toEqual([null]);
102
+ }));
103
+ test("should define an object as a nested context in a schema", () => __awaiter(void 0, void 0, void 0, function* () {
104
+ var _j, _k, _l, _m, _o, _p, _q;
105
+ const schema = new Schema("my-custom-element");
106
+ schema.addPath({
107
+ rootPropertyName: "a",
108
+ pathConfig: {
109
+ type: "default",
110
+ path: "a",
111
+ currentContext: null,
112
+ },
113
+ });
114
+ schema.addPath({
115
+ rootPropertyName: "a",
116
+ pathConfig: {
117
+ type: "repeat",
118
+ path: "a.items",
119
+ currentContext: "item",
120
+ parentContext: null,
121
+ },
122
+ });
123
+ schema.addPath({
124
+ rootPropertyName: "a",
125
+ pathConfig: {
126
+ type: "access",
127
+ path: "item.b",
128
+ currentContext: "item",
129
+ },
130
+ });
131
+ const schemaA = schema.getSchema("a");
132
+ expect(schemaA).toBeDefined();
133
+ expect((_j = schemaA.$defs) === null || _j === void 0 ? void 0 : _j["item"]).toBeDefined();
134
+ expect((_k = schemaA.$defs) === null || _k === void 0 ? void 0 : _k["item"].$fast_context).toEqual("items");
135
+ expect((_l = schemaA.$defs) === null || _l === void 0 ? void 0 : _l["item"].$fast_parent_contexts).toEqual([null]);
136
+ expect((_m = schemaA.$defs) === null || _m === void 0 ? void 0 : _m["item"].type).toEqual("object");
137
+ expect((_o = schemaA.$defs) === null || _o === void 0 ? void 0 : _o["item"].properties).toBeDefined();
138
+ expect((_q = (_p = schemaA.$defs) === null || _p === void 0 ? void 0 : _p["item"].properties) === null || _q === void 0 ? void 0 : _q["b"]).toBeDefined();
139
+ }));
140
+ test("should define nested contexts in a schema", () => __awaiter(void 0, void 0, void 0, function* () {
141
+ var _r, _s, _t, _u, _v, _w;
142
+ const schema = new Schema("my-custom-element");
143
+ schema.addPath({
144
+ rootPropertyName: "a",
145
+ pathConfig: {
146
+ type: "default",
147
+ path: "a",
148
+ currentContext: null,
149
+ },
150
+ });
151
+ schema.addPath({
152
+ rootPropertyName: "a",
153
+ pathConfig: {
154
+ type: "repeat",
155
+ path: "a.users",
156
+ currentContext: "user",
157
+ parentContext: null,
158
+ },
159
+ });
160
+ schema.addPath({
161
+ rootPropertyName: "a",
162
+ pathConfig: {
163
+ type: "repeat",
164
+ path: "user.posts",
165
+ currentContext: "post",
166
+ parentContext: "user"
167
+ },
168
+ });
169
+ const schemaA = schema.getSchema("a");
170
+ expect(schemaA).toBeDefined();
171
+ expect((_r = schemaA.$defs) === null || _r === void 0 ? void 0 : _r["user"]).toBeDefined();
172
+ expect((_s = schemaA.$defs) === null || _s === void 0 ? void 0 : _s["user"].$fast_context).toEqual("users");
173
+ expect((_t = schemaA.$defs) === null || _t === void 0 ? void 0 : _t["user"].$fast_parent_contexts).toEqual([null]);
174
+ expect((_u = schemaA.$defs) === null || _u === void 0 ? void 0 : _u["post"]).toBeDefined();
175
+ expect((_v = schemaA.$defs) === null || _v === void 0 ? void 0 : _v["post"].$fast_context).toEqual("posts");
176
+ expect((_w = schemaA.$defs) === null || _w === void 0 ? void 0 : _w["post"].$fast_parent_contexts).toEqual([null, "user"]);
177
+ }));
178
+ test("should define nested contexts with objects in a schema", () => __awaiter(void 0, void 0, void 0, function* () {
179
+ var _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17;
180
+ const schema = new Schema("my-custom-element");
181
+ schema.addPath({
182
+ rootPropertyName: "a",
183
+ pathConfig: {
184
+ type: "repeat",
185
+ path: "a.users",
186
+ currentContext: "user",
187
+ parentContext: null,
188
+ },
189
+ });
190
+ schema.addPath({
191
+ rootPropertyName: "a",
192
+ pathConfig: {
193
+ type: "access",
194
+ path: "user.a.b",
195
+ currentContext: "user",
196
+ },
197
+ });
198
+ schema.addPath({
199
+ rootPropertyName: "a",
200
+ pathConfig: {
201
+ type: "repeat",
202
+ path: "user.posts",
203
+ currentContext: "post",
204
+ parentContext: "user"
205
+ },
206
+ });
207
+ schema.addPath({
208
+ rootPropertyName: "a",
209
+ pathConfig: {
210
+ type: "access",
211
+ path: "post.c.d",
212
+ currentContext: "post",
213
+ },
214
+ });
215
+ schema.addPath({
216
+ rootPropertyName: "a",
217
+ pathConfig: {
218
+ type: "repeat",
219
+ path: "post.meta.tags",
220
+ currentContext: "tag",
221
+ parentContext: "post"
222
+ },
223
+ });
224
+ const schemaA = schema.getSchema("a");
225
+ expect(schemaA).toBeDefined();
226
+ expect((_x = schemaA.$defs) === null || _x === void 0 ? void 0 : _x["user"]).toBeDefined();
227
+ expect((_y = schemaA.$defs) === null || _y === void 0 ? void 0 : _y["user"].$fast_context).toEqual("users");
228
+ expect((_z = schemaA.$defs) === null || _z === void 0 ? void 0 : _z["user"].$fast_parent_contexts).toEqual([null]);
229
+ expect((_0 = schemaA.$defs) === null || _0 === void 0 ? void 0 : _0["user"].type).toEqual("object");
230
+ expect((_1 = schemaA.$defs) === null || _1 === void 0 ? void 0 : _1["user"].properties).toBeDefined();
231
+ expect((_2 = schemaA.$defs) === null || _2 === void 0 ? void 0 : _2["user"].properties["a"]).toBeDefined();
232
+ expect((_3 = schemaA.$defs) === null || _3 === void 0 ? void 0 : _3["user"].properties["a"].properties["b"]).toBeDefined();
233
+ expect((_4 = schemaA.$defs) === null || _4 === void 0 ? void 0 : _4["post"]).toBeDefined();
234
+ expect((_5 = schemaA.$defs) === null || _5 === void 0 ? void 0 : _5["post"].$fast_context).toEqual("posts");
235
+ expect((_6 = schemaA.$defs) === null || _6 === void 0 ? void 0 : _6["post"].$fast_parent_contexts).toEqual([null, "user"]);
236
+ expect((_7 = schemaA.$defs) === null || _7 === void 0 ? void 0 : _7["post"].type).toEqual("object");
237
+ expect((_8 = schemaA.$defs) === null || _8 === void 0 ? void 0 : _8["post"].properties).toBeDefined();
238
+ expect((_9 = schemaA.$defs) === null || _9 === void 0 ? void 0 : _9["post"].properties["c"]).toBeDefined();
239
+ expect((_10 = schemaA.$defs) === null || _10 === void 0 ? void 0 : _10["post"].properties["c"].properties["d"]).toBeDefined();
240
+ expect((_11 = schemaA.$defs) === null || _11 === void 0 ? void 0 : _11["post"].properties["meta"]).toBeDefined();
241
+ expect((_12 = schemaA.$defs) === null || _12 === void 0 ? void 0 : _12["post"].properties["meta"].properties["tags"]).toBeDefined();
242
+ expect((_13 = schemaA.$defs) === null || _13 === void 0 ? void 0 : _13["post"].properties["meta"].properties["tags"].items).toBeDefined();
243
+ expect((_14 = schemaA.$defs) === null || _14 === void 0 ? void 0 : _14["post"].properties["meta"].properties["tags"].items.$ref).toEqual("#/$defs/tag");
244
+ expect((_15 = schemaA.$defs) === null || _15 === void 0 ? void 0 : _15["tag"]).toBeDefined();
245
+ expect((_16 = schemaA.$defs) === null || _16 === void 0 ? void 0 : _16["tag"].$fast_context).toEqual("tags");
246
+ expect((_17 = schemaA.$defs) === null || _17 === void 0 ? void 0 : _17["tag"].$fast_parent_contexts).toEqual([null, "user", "post"]);
247
+ }));
248
+ }));
@@ -17,7 +17,7 @@ class TemplateElement extends FASTElement {
17
17
  observerMap: value.observerMap,
18
18
  };
19
19
  }
20
- this.elementOptions = result;
20
+ TemplateElement.elementOptions = result;
21
21
  HydratableElementController.install();
22
22
  return this;
23
23
  }