@player-tools/dsl 0.5.0--canary.62.1176 → 0.5.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +973 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/index.legacy-esm.js +910 -0
- package/dist/index.mjs +910 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +27 -33
- package/src/__tests__/asset-api.test.tsx +354 -0
- package/src/__tests__/edge-cases.test.tsx +81 -0
- package/src/__tests__/helpers/asset-library.tsx +371 -0
- package/src/__tests__/helpers/mock-data-refs.ts +21 -0
- package/src/__tests__/json.test.ts +12 -0
- package/src/__tests__/jsx.test.tsx +138 -0
- package/src/__tests__/schema.test.tsx +378 -0
- package/src/__tests__/switch.test.tsx +251 -0
- package/src/__tests__/template.test.tsx +294 -0
- package/src/__tests__/view-api.test.tsx +46 -0
- package/src/auto-id.tsx +10 -10
- package/src/compiler/__tests__/compiler.test.tsx +264 -0
- package/src/compiler/__tests__/schema.test.ts +127 -0
- package/src/compiler/compiler.ts +50 -46
- package/src/compiler/index.ts +3 -3
- package/src/compiler/schema.ts +29 -25
- package/src/compiler/types.ts +15 -12
- package/src/compiler/utils.ts +7 -7
- package/src/components.tsx +17 -12
- package/src/index.ts +11 -11
- package/src/string-templates/__tests__/binding.test.ts +87 -0
- package/src/string-templates/__tests__/edge-cases.test.ts +6 -0
- package/src/string-templates/__tests__/expression.test.ts +9 -0
- package/src/string-templates/__tests__/react.test.tsx +75 -0
- package/src/string-templates/index.ts +40 -22
- package/src/switch.tsx +12 -12
- package/src/template.tsx +38 -34
- package/src/types.ts +5 -5
- package/src/utils.tsx +8 -8
- package/types/auto-id.d.ts +33 -0
- package/types/compiler/compiler.d.ts +27 -0
- package/types/compiler/index.d.ts +4 -0
- package/types/compiler/schema.d.ts +61 -0
- package/types/compiler/types.d.ts +55 -0
- package/types/compiler/utils.d.ts +4 -0
- package/types/components.d.ts +90 -0
- package/types/index.d.ts +12 -0
- package/types/string-templates/index.d.ts +50 -0
- package/types/switch.d.ts +19 -0
- package/types/template.d.ts +20 -0
- package/types/types.d.ts +42 -0
- package/types/utils.d.ts +33 -0
- package/README.md +0 -9
- package/dist/index.cjs.js +0 -990
- package/dist/index.d.ts +0 -404
- package/dist/index.esm.js +0 -923
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { test, expect } from "vitest";
|
|
2
|
+
import { SchemaGenerator } from "../schema";
|
|
3
|
+
|
|
4
|
+
const BasicDataType = {
|
|
5
|
+
type: "StringType",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
test("generates proper schema", () => {
|
|
9
|
+
const schemaGenerator = new SchemaGenerator();
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
schemaGenerator.toSchema({
|
|
13
|
+
foo: {
|
|
14
|
+
bar: {
|
|
15
|
+
baz: BasicDataType,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
other: [
|
|
19
|
+
{
|
|
20
|
+
item1: BasicDataType,
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
})
|
|
24
|
+
).toStrictEqual({
|
|
25
|
+
ROOT: {
|
|
26
|
+
foo: {
|
|
27
|
+
type: "fooType",
|
|
28
|
+
},
|
|
29
|
+
other: {
|
|
30
|
+
type: "otherType",
|
|
31
|
+
isArray: true,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
fooType: {
|
|
35
|
+
bar: {
|
|
36
|
+
type: "barType",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
barType: {
|
|
40
|
+
baz: {
|
|
41
|
+
type: "StringType",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
otherType: {
|
|
45
|
+
item1: {
|
|
46
|
+
type: "StringType",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("Edge Case - two artificial array nodes", () => {
|
|
53
|
+
const schemaGenerator = new SchemaGenerator();
|
|
54
|
+
|
|
55
|
+
expect(
|
|
56
|
+
schemaGenerator.toSchema({
|
|
57
|
+
foo: {
|
|
58
|
+
bar: [
|
|
59
|
+
{
|
|
60
|
+
baa: BasicDataType,
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
other: {
|
|
65
|
+
bar: [
|
|
66
|
+
{
|
|
67
|
+
bab: BasicDataType,
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
another: {
|
|
72
|
+
bar: [
|
|
73
|
+
{
|
|
74
|
+
bac: BasicDataType,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
).toMatchInlineSnapshot(`
|
|
80
|
+
{
|
|
81
|
+
"ROOT": {
|
|
82
|
+
"another": {
|
|
83
|
+
"type": "anotherType",
|
|
84
|
+
},
|
|
85
|
+
"foo": {
|
|
86
|
+
"type": "fooType",
|
|
87
|
+
},
|
|
88
|
+
"other": {
|
|
89
|
+
"type": "otherType",
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
"anotherType": {
|
|
93
|
+
"bar": {
|
|
94
|
+
"isArray": true,
|
|
95
|
+
"type": "barType",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
"barType": {
|
|
99
|
+
"bac": {
|
|
100
|
+
"type": "StringType",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
"barType2": {
|
|
104
|
+
"bab": {
|
|
105
|
+
"type": "StringType",
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
"barType3": {
|
|
109
|
+
"baa": {
|
|
110
|
+
"type": "StringType",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
"fooType": {
|
|
114
|
+
"bar": {
|
|
115
|
+
"isArray": true,
|
|
116
|
+
"type": "barType3",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
"otherType": {
|
|
120
|
+
"bar": {
|
|
121
|
+
"isArray": true,
|
|
122
|
+
"type": "barType2",
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
}
|
|
126
|
+
`);
|
|
127
|
+
});
|
package/src/compiler/compiler.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import type { JsonType } from
|
|
3
|
-
import { SourceMapGenerator, SourceMapConsumer } from
|
|
4
|
-
import { render } from
|
|
5
|
-
import type { Flow, View, Navigation as PlayerNav } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { JsonType } from "react-json-reconciler";
|
|
3
|
+
import { SourceMapGenerator, SourceMapConsumer } from "source-map-js";
|
|
4
|
+
import { render } from "react-json-reconciler";
|
|
5
|
+
import type { Flow, View, Navigation as PlayerNav } from "@player-ui/types";
|
|
6
6
|
import {
|
|
7
7
|
AsyncSeriesHook,
|
|
8
8
|
AsyncSeriesWaterfallHook,
|
|
9
9
|
SyncHook,
|
|
10
|
-
} from
|
|
11
|
-
import { fingerprintContent } from
|
|
10
|
+
} from "tapable-ts";
|
|
11
|
+
import { fingerprintContent } from "./utils";
|
|
12
12
|
import type {
|
|
13
13
|
LoggingInterface,
|
|
14
14
|
CompilerReturn,
|
|
15
15
|
SerializeContext,
|
|
16
|
-
} from
|
|
17
|
-
import type { Navigation } from
|
|
18
|
-
import { SchemaGenerator } from
|
|
16
|
+
} from "./types";
|
|
17
|
+
import type { Navigation } from "../types";
|
|
18
|
+
import { SchemaGenerator } from "./schema";
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Argument passed to the DSLCompiler onEnd hook
|
|
@@ -32,7 +32,7 @@ const parseNavigationExpressions = (nav: Navigation): PlayerNav => {
|
|
|
32
32
|
function replaceExpWithStr(obj: any): any {
|
|
33
33
|
/** call toValue if BindingTemplateInstance otherwise continue */
|
|
34
34
|
function convExp(value: any): any {
|
|
35
|
-
return value && typeof value ===
|
|
35
|
+
return value && typeof value === "object" && value.__type === "expression"
|
|
36
36
|
? value.toValue() // exp, onStart, and onEnd don't need to be wrapped in @[]@
|
|
37
37
|
: replaceExpWithStr(value);
|
|
38
38
|
}
|
|
@@ -41,10 +41,13 @@ const parseNavigationExpressions = (nav: Navigation): PlayerNav => {
|
|
|
41
41
|
return obj.map(convExp);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
if (typeof obj ===
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
if (typeof obj === "object") {
|
|
45
|
+
const copy = { ...obj };
|
|
46
|
+
for (const [key, value] of Object.entries(copy)) {
|
|
47
|
+
copy[key] = convExp(value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return copy;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
return obj;
|
|
@@ -74,17 +77,17 @@ const mergeSourceMaps = (
|
|
|
74
77
|
const generator = new SourceMapGenerator();
|
|
75
78
|
sourceMaps.forEach(({ sourceMap, offsetIndexSearch, source }) => {
|
|
76
79
|
const generatedLineOffset = generated
|
|
77
|
-
.split(
|
|
80
|
+
.split("\n")
|
|
78
81
|
.findIndex((line) => line.includes(offsetIndexSearch));
|
|
79
82
|
|
|
80
83
|
const sourceLineOffset = source
|
|
81
|
-
.split(
|
|
84
|
+
.split("\n")
|
|
82
85
|
.findIndex((line) => line.includes(offsetIndexSearch));
|
|
83
86
|
|
|
84
87
|
const lineOffset = generatedLineOffset - sourceLineOffset;
|
|
85
88
|
|
|
86
|
-
const generatedLine = generated.split(
|
|
87
|
-
const sourceLine = source.split(
|
|
89
|
+
const generatedLine = generated.split("\n")[generatedLineOffset];
|
|
90
|
+
const sourceLine = source.split("\n")[sourceLineOffset];
|
|
88
91
|
|
|
89
92
|
const generatedColumn = generatedLine.indexOf(offsetIndexSearch);
|
|
90
93
|
const sourceColumn = sourceLine.indexOf(offsetIndexSearch);
|
|
@@ -123,6 +126,8 @@ export class DSLCompiler {
|
|
|
123
126
|
onEnd: new AsyncSeriesHook<[OnEndArg]>(),
|
|
124
127
|
};
|
|
125
128
|
|
|
129
|
+
private schemaGenerator?: SchemaGenerator;
|
|
130
|
+
|
|
126
131
|
constructor(logger?: LoggingInterface) {
|
|
127
132
|
this.logger = logger ?? console;
|
|
128
133
|
}
|
|
@@ -131,17 +136,19 @@ export class DSLCompiler {
|
|
|
131
136
|
async serialize(
|
|
132
137
|
value: unknown,
|
|
133
138
|
context?: SerializeContext
|
|
134
|
-
): Promise<CompilerReturn
|
|
135
|
-
if (typeof value !==
|
|
136
|
-
throw new Error(
|
|
139
|
+
): Promise<CompilerReturn> {
|
|
140
|
+
if (typeof value !== "object" || value === null) {
|
|
141
|
+
throw new Error("Unable to serialize non-object");
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
const type = context?.type ? context.type : fingerprintContent(value);
|
|
140
145
|
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
if (!this.schemaGenerator) {
|
|
147
|
+
this.schemaGenerator = new SchemaGenerator(this.logger);
|
|
148
|
+
this.hooks.schemaGenerator.call(this.schemaGenerator);
|
|
149
|
+
}
|
|
143
150
|
|
|
144
|
-
if (type ===
|
|
151
|
+
if (type === "view") {
|
|
145
152
|
const { jsonValue, sourceMap } = await render(value as any, {
|
|
146
153
|
collectSourceMap: true,
|
|
147
154
|
});
|
|
@@ -152,7 +159,7 @@ export class DSLCompiler {
|
|
|
152
159
|
};
|
|
153
160
|
}
|
|
154
161
|
|
|
155
|
-
if (type ===
|
|
162
|
+
if (type === "flow") {
|
|
156
163
|
// Source maps from all the nested views
|
|
157
164
|
// Merge these together before returning
|
|
158
165
|
const allSourceMaps: SourceMapList = [];
|
|
@@ -173,7 +180,7 @@ export class DSLCompiler {
|
|
|
173
180
|
// Find the line that is the id of the view
|
|
174
181
|
// Use that as the identifier for the sourcemap offset calc
|
|
175
182
|
const searchIdLine = stringValue
|
|
176
|
-
.split(
|
|
183
|
+
.split("\n")
|
|
177
184
|
.find((line) =>
|
|
178
185
|
line.includes(
|
|
179
186
|
`"id": "${(jsonValue as Record<string, string>).id}"`
|
|
@@ -197,15 +204,15 @@ export class DSLCompiler {
|
|
|
197
204
|
)) as View[];
|
|
198
205
|
|
|
199
206
|
// Go through the flow and sub out any view refs that are react elements w/ the right id
|
|
200
|
-
if (
|
|
207
|
+
if ("navigation" in value) {
|
|
201
208
|
Object.entries((value as Flow).navigation).forEach(([navKey, node]) => {
|
|
202
|
-
if (typeof node ===
|
|
209
|
+
if (typeof node === "object") {
|
|
203
210
|
Object.entries(node).forEach(([nodeKey, flowNode]) => {
|
|
204
211
|
if (
|
|
205
212
|
flowNode &&
|
|
206
|
-
typeof flowNode ===
|
|
207
|
-
|
|
208
|
-
flowNode.state_type ===
|
|
213
|
+
typeof flowNode === "object" &&
|
|
214
|
+
"state_type" in flowNode &&
|
|
215
|
+
flowNode.state_type === "VIEW" &&
|
|
209
216
|
React.isValidElement(flowNode.ref)
|
|
210
217
|
) {
|
|
211
218
|
const actualViewIndex = (value as Flow).views?.indexOf?.(
|
|
@@ -222,16 +229,16 @@ export class DSLCompiler {
|
|
|
222
229
|
});
|
|
223
230
|
}
|
|
224
231
|
});
|
|
232
|
+
}
|
|
225
233
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
copiedValue.navigation = parseNavigationExpressions(
|
|
231
|
-
copiedValue.navigation
|
|
232
|
-
);
|
|
234
|
+
if ("schema" in copiedValue) {
|
|
235
|
+
copiedValue.schema = this.schemaGenerator.toSchema(copiedValue.schema);
|
|
233
236
|
}
|
|
234
237
|
|
|
238
|
+
copiedValue.navigation = parseNavigationExpressions(
|
|
239
|
+
copiedValue.navigation
|
|
240
|
+
);
|
|
241
|
+
|
|
235
242
|
if (value) {
|
|
236
243
|
const postProcessFlow = await this.hooks.postProcessFlow.call(
|
|
237
244
|
copiedValue
|
|
@@ -247,12 +254,9 @@ export class DSLCompiler {
|
|
|
247
254
|
}
|
|
248
255
|
}
|
|
249
256
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
throw Error('DSL Compiler Error: Unable to determine type to compile as');
|
|
257
|
+
// Type has been set to "schema"
|
|
258
|
+
return {
|
|
259
|
+
value: this.schemaGenerator.toSchema(value) as JsonType,
|
|
260
|
+
};
|
|
257
261
|
}
|
|
258
262
|
}
|
package/src/compiler/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./compiler";
|
|
2
|
+
export * from "./types";
|
|
3
|
+
export * from "./utils";
|
package/src/compiler/schema.ts
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import type { Schema, Language } from
|
|
2
|
-
import { dequal } from
|
|
3
|
-
import { SyncWaterfallHook } from
|
|
4
|
-
import type { LoggingInterface } from
|
|
5
|
-
import { binding as b } from
|
|
6
|
-
import type { BindingTemplateInstance } from
|
|
1
|
+
import type { Schema, Language } from "@player-ui/types";
|
|
2
|
+
import { dequal } from "dequal";
|
|
3
|
+
import { SyncWaterfallHook } from "tapable-ts";
|
|
4
|
+
import type { LoggingInterface } from "..";
|
|
5
|
+
import { binding as b } from "..";
|
|
6
|
+
import type { BindingTemplateInstance } from "../string-templates";
|
|
7
7
|
|
|
8
|
-
const bindingSymbol = Symbol(
|
|
8
|
+
const bindingSymbol = Symbol("binding");
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
interface GeneratedDataType {
|
|
13
|
-
/** The SchemaNode that was generated */
|
|
14
|
-
node: SchemaNode;
|
|
15
|
-
/** How many times it has been generated */
|
|
16
|
-
count: number;
|
|
17
|
-
}
|
|
10
|
+
/** Symbol to indicate that a schema node should be generated with a different name */
|
|
11
|
+
export const SchemaTypeName = Symbol("Schema Rename");
|
|
18
12
|
|
|
19
13
|
interface SchemaChildren {
|
|
20
14
|
/** Object property that will be used to create the intermediate type */
|
|
@@ -29,6 +23,13 @@ type SchemaNode = (Schema.DataType | Language.DataTypeRef) & {
|
|
|
29
23
|
[SchemaTypeName]?: string;
|
|
30
24
|
};
|
|
31
25
|
|
|
26
|
+
interface GeneratedDataType {
|
|
27
|
+
/** The SchemaNode that was generated */
|
|
28
|
+
node: SchemaNode;
|
|
29
|
+
/** How many times it has been generated */
|
|
30
|
+
count: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
32
33
|
/**
|
|
33
34
|
* Type Guard for the `Schema.DataType` and `Language.DataTypeRef` type
|
|
34
35
|
* A bit hacky but since `Schema.Schema` must have a `Schema.DataType` as
|
|
@@ -113,6 +114,7 @@ export class SchemaGenerator {
|
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
let intermediateType;
|
|
117
|
+
let child;
|
|
116
118
|
|
|
117
119
|
if (Array.isArray(subType)) {
|
|
118
120
|
if (subType.length > 1) {
|
|
@@ -123,20 +125,22 @@ export class SchemaGenerator {
|
|
|
123
125
|
|
|
124
126
|
const subTypeName = subType[0][SchemaTypeName] ?? property;
|
|
125
127
|
intermediateType = this.makePlaceholderArrayType(subTypeName);
|
|
126
|
-
|
|
128
|
+
[child] = subType;
|
|
127
129
|
} else {
|
|
128
130
|
const subTypeName = subType[SchemaTypeName] ?? property;
|
|
129
131
|
intermediateType = this.makePlaceholderType(subTypeName);
|
|
130
|
-
|
|
132
|
+
child = subType;
|
|
131
133
|
}
|
|
132
134
|
|
|
135
|
+
this.children.push({ name: intermediateType.type, child });
|
|
136
|
+
|
|
133
137
|
if (this.generatedDataTypes.has(intermediateType.type)) {
|
|
134
138
|
const generatedType = this.generatedDataTypes.get(
|
|
135
139
|
intermediateType.type
|
|
136
140
|
) as GeneratedDataType;
|
|
137
141
|
if (
|
|
138
142
|
!dequal(
|
|
139
|
-
|
|
143
|
+
child,
|
|
140
144
|
this.generatedDataTypes.get(intermediateType.type)?.node as object
|
|
141
145
|
)
|
|
142
146
|
) {
|
|
@@ -150,7 +154,7 @@ export class SchemaGenerator {
|
|
|
150
154
|
);
|
|
151
155
|
intermediateType = newIntermediateType;
|
|
152
156
|
this.children.pop();
|
|
153
|
-
this.children.push({ name: intermediateType.type, child
|
|
157
|
+
this.children.push({ name: intermediateType.type, child });
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
|
|
@@ -200,7 +204,7 @@ export type MakeBindingRefable<T> = {
|
|
|
200
204
|
*/
|
|
201
205
|
export function makeBindingsForObject<Type>(
|
|
202
206
|
obj: Type,
|
|
203
|
-
arrayAccessorKeys = [
|
|
207
|
+
arrayAccessorKeys = ["_index_"]
|
|
204
208
|
): MakeBindingRefable<Type> {
|
|
205
209
|
/** Proxy to track binding callbacks */
|
|
206
210
|
const accessor = (paths: string[]) => {
|
|
@@ -218,13 +222,13 @@ export function makeBindingsForObject<Type>(
|
|
|
218
222
|
if (
|
|
219
223
|
Array.isArray(target[key]) &&
|
|
220
224
|
target[key].length > 0 &&
|
|
221
|
-
target[key].every((it: any) => typeof it !==
|
|
225
|
+
target[key].every((it: any) => typeof it !== "object")
|
|
222
226
|
) {
|
|
223
227
|
return [...target[key]];
|
|
224
228
|
}
|
|
225
229
|
|
|
226
230
|
if (!bindingMap.has(target)) {
|
|
227
|
-
bindingMap.set(target, b`${paths.join(
|
|
231
|
+
bindingMap.set(target, b`${paths.join(".")}`);
|
|
228
232
|
}
|
|
229
233
|
|
|
230
234
|
if (key === bindingSymbol) {
|
|
@@ -233,12 +237,12 @@ export function makeBindingsForObject<Type>(
|
|
|
233
237
|
|
|
234
238
|
if (
|
|
235
239
|
Array.isArray(target) &&
|
|
236
|
-
(arrayAccessorKeys.includes(key) || typeof key ===
|
|
240
|
+
(arrayAccessorKeys.includes(key) || typeof key === "number")
|
|
237
241
|
) {
|
|
238
242
|
return new Proxy(target[0], accessor(paths.concat([key])));
|
|
239
243
|
}
|
|
240
244
|
|
|
241
|
-
if (bindingKeys.includes(key) && typeof target[key] ===
|
|
245
|
+
if (bindingKeys.includes(key) && typeof target[key] === "object") {
|
|
242
246
|
return new Proxy(target[key], accessor(paths.concat([key])));
|
|
243
247
|
}
|
|
244
248
|
|
|
@@ -260,7 +264,7 @@ export const getBindingFromObject = (obj: any) => {
|
|
|
260
264
|
throw new Error(`Unable to get binding for ${obj}`);
|
|
261
265
|
}
|
|
262
266
|
|
|
263
|
-
return b`${baseBindings.join(
|
|
267
|
+
return b`${baseBindings.join(".")}`;
|
|
264
268
|
};
|
|
265
269
|
|
|
266
270
|
/**
|
package/src/compiler/types.ts
CHANGED
|
@@ -7,13 +7,13 @@ import type {
|
|
|
7
7
|
NavigationFlow,
|
|
8
8
|
NavigationFlowState,
|
|
9
9
|
NavigationFlowViewState,
|
|
10
|
-
} from
|
|
11
|
-
import type { JsonType } from
|
|
12
|
-
import type { RemoveUnknownIndex, AddUnknownIndex } from
|
|
10
|
+
} from "@player-ui/types";
|
|
11
|
+
import type { JsonType } from "react-json-reconciler";
|
|
12
|
+
import type { RemoveUnknownIndex, AddUnknownIndex } from "../types";
|
|
13
13
|
|
|
14
14
|
export type NavigationFlowReactViewState = Omit<
|
|
15
15
|
NavigationFlowViewState,
|
|
16
|
-
|
|
16
|
+
"ref"
|
|
17
17
|
> & {
|
|
18
18
|
/** The view element */
|
|
19
19
|
ref: React.ReactElement | string;
|
|
@@ -25,7 +25,7 @@ export type NavFlowState =
|
|
|
25
25
|
|
|
26
26
|
export type NavigationFlowWithReactView = Pick<
|
|
27
27
|
NavigationFlow,
|
|
28
|
-
|
|
28
|
+
"startState" | "onStart" | "onEnd"
|
|
29
29
|
> & {
|
|
30
30
|
[key: string]:
|
|
31
31
|
| undefined
|
|
@@ -35,12 +35,12 @@ export type NavigationFlowWithReactView = Pick<
|
|
|
35
35
|
| NavFlowState;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
export type NavigationWithReactViews = Pick<Navigation,
|
|
38
|
+
export type NavigationWithReactViews = Pick<Navigation, "BEGIN"> &
|
|
39
39
|
Record<string, string | NavigationFlowWithReactView>;
|
|
40
40
|
|
|
41
41
|
export type FlowWithoutUnknown = RemoveUnknownIndex<Flow>;
|
|
42
42
|
export type FlowWithReactViews = AddUnknownIndex<
|
|
43
|
-
Omit<FlowWithoutUnknown,
|
|
43
|
+
Omit<FlowWithoutUnknown, "views" | "navigation"> & {
|
|
44
44
|
/** An array of JSX view elements */
|
|
45
45
|
views?: Array<React.ReactElement>;
|
|
46
46
|
|
|
@@ -49,13 +49,16 @@ export type FlowWithReactViews = AddUnknownIndex<
|
|
|
49
49
|
}
|
|
50
50
|
>;
|
|
51
51
|
|
|
52
|
-
export type DSLFlow = FlowWithReactViews
|
|
52
|
+
export type DSLFlow = Omit<FlowWithReactViews, "schema"> & {
|
|
53
|
+
/** A DSL compliant schema */
|
|
54
|
+
schema?: DSLSchema;
|
|
55
|
+
};
|
|
53
56
|
|
|
54
57
|
export interface DSLSchema {
|
|
55
58
|
[key: string]: Schema.DataType | DSLSchema;
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
export type SerializeType =
|
|
61
|
+
export type SerializeType = "view" | "flow" | "schema" | "navigation";
|
|
59
62
|
|
|
60
63
|
export type SerializablePlayerExportTypes =
|
|
61
64
|
| React.ReactElement
|
|
@@ -63,7 +66,7 @@ export type SerializablePlayerExportTypes =
|
|
|
63
66
|
| Schema.Schema
|
|
64
67
|
| Navigation;
|
|
65
68
|
|
|
66
|
-
export type LoggingInterface = Pick<Console,
|
|
69
|
+
export type LoggingInterface = Pick<Console, "warn" | "error" | "log">;
|
|
67
70
|
|
|
68
71
|
export type CompilationResult = {
|
|
69
72
|
/** What type of file is generated */
|
|
@@ -83,10 +86,10 @@ export type CompilerReturn = {
|
|
|
83
86
|
};
|
|
84
87
|
|
|
85
88
|
/** The different type of default content items the compiler handles */
|
|
86
|
-
const DefaultCompilerContentTypes = [
|
|
89
|
+
const DefaultCompilerContentTypes = ["view", "flow", "schema"] as const;
|
|
87
90
|
|
|
88
91
|
export type DefaultCompilerContentType =
|
|
89
|
-
typeof DefaultCompilerContentTypes[number];
|
|
92
|
+
(typeof DefaultCompilerContentTypes)[number];
|
|
90
93
|
|
|
91
94
|
/** Helper function to determine whether a content type is compiler default */
|
|
92
95
|
export function isDefaultCompilerContentType(
|
package/src/compiler/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import type { DefaultCompilerContentType } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DefaultCompilerContentType } from "./types";
|
|
3
3
|
|
|
4
4
|
/** Basic way of identifying the type of file based on the default content export */
|
|
5
5
|
export const fingerprintContent = (
|
|
@@ -8,15 +8,15 @@ export const fingerprintContent = (
|
|
|
8
8
|
): DefaultCompilerContentType | undefined => {
|
|
9
9
|
if (content !== null || content !== undefined) {
|
|
10
10
|
if (React.isValidElement(content as any)) {
|
|
11
|
-
return
|
|
11
|
+
return "view";
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
if (typeof content ===
|
|
15
|
-
return
|
|
14
|
+
if (typeof content === "object" && "navigation" in (content as any)) {
|
|
15
|
+
return "flow";
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
if (!filename || filename.includes(
|
|
19
|
-
return
|
|
18
|
+
if (!filename || filename.includes("schema")) {
|
|
19
|
+
return "schema";
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
};
|
package/src/components.tsx
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import type { ObjectNode, PropertyNode } from
|
|
3
|
-
import mergeRefs from
|
|
4
|
-
import type { View as ViewType } from
|
|
5
|
-
import type { PlayerApplicability, WithChildren } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { ObjectNode, PropertyNode } from "react-json-reconciler";
|
|
3
|
+
import mergeRefs from "react-merge-refs";
|
|
4
|
+
import type { View as ViewType } from "@player-ui/types";
|
|
5
|
+
import type { PlayerApplicability, WithChildren } from "./types";
|
|
6
6
|
import {
|
|
7
7
|
IDProvider,
|
|
8
8
|
IDSuffixProvider,
|
|
9
9
|
IndexSuffixStopContext,
|
|
10
10
|
OptionalIDSuffixProvider,
|
|
11
11
|
useGetIdPrefix,
|
|
12
|
-
} from
|
|
12
|
+
} from "./auto-id";
|
|
13
13
|
import {
|
|
14
14
|
normalizeText,
|
|
15
15
|
normalizeToCollection,
|
|
16
16
|
toJsonElement,
|
|
17
17
|
toJsonProperties,
|
|
18
18
|
flattenChildren,
|
|
19
|
-
} from
|
|
19
|
+
} from "./utils";
|
|
20
20
|
|
|
21
21
|
export type AssetProps = PlayerApplicability & {
|
|
22
22
|
/** id of the asset */
|
|
@@ -58,8 +58,8 @@ export const SlotContext = React.createContext<
|
|
|
58
58
|
*/
|
|
59
59
|
export const AssetWrapper = React.forwardRef<
|
|
60
60
|
ObjectNode,
|
|
61
|
-
WithChildren<{ [key: string]:
|
|
62
|
-
>((props, ref)
|
|
61
|
+
WithChildren<{ [key: string]: unknown }>
|
|
62
|
+
>(function AssetWrapper(props, ref) {
|
|
63
63
|
const { children, ...rest } = props;
|
|
64
64
|
|
|
65
65
|
return (
|
|
@@ -109,7 +109,7 @@ export const Asset = React.forwardRef<ObjectNode, AssetProps>((props, ref) => {
|
|
|
109
109
|
<property name="applicability">
|
|
110
110
|
<value
|
|
111
111
|
value={
|
|
112
|
-
typeof applicability ===
|
|
112
|
+
typeof applicability === "boolean"
|
|
113
113
|
? applicability
|
|
114
114
|
: applicability.toValue()
|
|
115
115
|
}
|
|
@@ -126,6 +126,8 @@ export const Asset = React.forwardRef<ObjectNode, AssetProps>((props, ref) => {
|
|
|
126
126
|
);
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
+
Asset.displayName = "Asset";
|
|
130
|
+
|
|
129
131
|
Asset.defaultProps = {
|
|
130
132
|
id: undefined,
|
|
131
133
|
children: undefined,
|
|
@@ -139,8 +141,8 @@ export const View = React.forwardRef<ObjectNode, AssetProps & ViewType>(
|
|
|
139
141
|
<Asset ref={ref} {...rest}>
|
|
140
142
|
{validation && (
|
|
141
143
|
<property key="validation" name="validation">
|
|
142
|
-
{toJsonElement(validation,
|
|
143
|
-
propertiesToSkip: [
|
|
144
|
+
{toJsonElement(validation, "validation", {
|
|
145
|
+
propertiesToSkip: ["ref"],
|
|
144
146
|
})}
|
|
145
147
|
</property>
|
|
146
148
|
)}
|
|
@@ -150,6 +152,8 @@ export const View = React.forwardRef<ObjectNode, AssetProps & ViewType>(
|
|
|
150
152
|
}
|
|
151
153
|
);
|
|
152
154
|
|
|
155
|
+
View.displayName = "View";
|
|
156
|
+
|
|
153
157
|
View.defaultProps = {
|
|
154
158
|
id: undefined,
|
|
155
159
|
children: undefined,
|
|
@@ -243,6 +247,7 @@ export function createSlot<SlotProps = unknown>(options: {
|
|
|
243
247
|
/** A component to create a collection asset is we get an array but need a single element */
|
|
244
248
|
CollectionComp?: React.ComponentType;
|
|
245
249
|
}) {
|
|
250
|
+
// eslint-disable-next-line react/display-name
|
|
246
251
|
return (
|
|
247
252
|
props: {
|
|
248
253
|
/** An object to include in this property */
|