mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-01-18 16:54:00 +08:00
impl spec types and basic runtime
This commit is contained in:
parent
cd8014c4eb
commit
0a4199bde8
68
packages/core/__tests__/application.spec.ts
Normal file
68
packages/core/__tests__/application.spec.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { createApplication } from "../src/application";
|
||||
|
||||
describe("application", () => {
|
||||
it("can create runtime application", () => {
|
||||
expect(
|
||||
createApplication({
|
||||
version: "demo/v1",
|
||||
metadata: {
|
||||
name: "test-app",
|
||||
description: "first application",
|
||||
},
|
||||
|
||||
spec: {
|
||||
components: [
|
||||
{
|
||||
id: "input1",
|
||||
type: "core/v1/test-component",
|
||||
properties: {
|
||||
x: "foo",
|
||||
},
|
||||
|
||||
traits: [
|
||||
{
|
||||
type: "core/v1/test-trait",
|
||||
properties: {
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"kind": "Application",
|
||||
"metadata": Object {
|
||||
"description": "first application",
|
||||
"name": "test-app",
|
||||
},
|
||||
"parsedVersion": Object {
|
||||
"category": "demo",
|
||||
"value": "v1",
|
||||
},
|
||||
"spec": Object {
|
||||
"components": Array [
|
||||
Object {
|
||||
"id": "input1",
|
||||
"properties": Object {
|
||||
"x": "foo",
|
||||
},
|
||||
"traits": Array [
|
||||
Object {
|
||||
"properties": Object {
|
||||
"width": 2,
|
||||
},
|
||||
"type": "core/v1/test-trait",
|
||||
},
|
||||
],
|
||||
"type": "core/v1/test-component",
|
||||
},
|
||||
],
|
||||
},
|
||||
"version": "demo/v1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
84
packages/core/__tests__/component.spec.ts
Normal file
84
packages/core/__tests__/component.spec.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { createComponent } from "../src/component";
|
||||
|
||||
describe("component", () => {
|
||||
it("can create runtime component", () => {
|
||||
expect(
|
||||
createComponent({
|
||||
version: "core/v1",
|
||||
metadata: {
|
||||
name: "test-component",
|
||||
},
|
||||
spec: {
|
||||
properties: [
|
||||
{
|
||||
name: "x",
|
||||
type: "string",
|
||||
},
|
||||
],
|
||||
|
||||
acceptTraits: [
|
||||
{
|
||||
name: "t1",
|
||||
},
|
||||
],
|
||||
|
||||
state: {
|
||||
type: "string",
|
||||
},
|
||||
|
||||
methods: [
|
||||
{
|
||||
name: "reset",
|
||||
},
|
||||
|
||||
{
|
||||
name: "add",
|
||||
parameters: {
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"kind": "Component",
|
||||
"metadata": Object {
|
||||
"name": "test-component",
|
||||
},
|
||||
"parsedVersion": Object {
|
||||
"category": "core",
|
||||
"value": "v1",
|
||||
},
|
||||
"spec": Object {
|
||||
"acceptTraits": Array [
|
||||
Object {
|
||||
"name": "t1",
|
||||
},
|
||||
],
|
||||
"methods": Array [
|
||||
Object {
|
||||
"name": "reset",
|
||||
},
|
||||
Object {
|
||||
"name": "add",
|
||||
"parameters": Object {
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
],
|
||||
"properties": Array [
|
||||
Object {
|
||||
"name": "x",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"state": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"version": "core/v1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
26
packages/core/__tests__/scope.spec.ts
Normal file
26
packages/core/__tests__/scope.spec.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { createScope } from "../src/scope";
|
||||
|
||||
describe("scope", () => {
|
||||
it("can create runtime scope", () => {
|
||||
expect(
|
||||
createScope({
|
||||
version: "core/v1",
|
||||
metadata: {
|
||||
name: "test-scope",
|
||||
},
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"kind": "Scope",
|
||||
"metadata": Object {
|
||||
"name": "test-scope",
|
||||
},
|
||||
"parsedVersion": Object {
|
||||
"category": "core",
|
||||
"value": "v1",
|
||||
},
|
||||
"version": "core/v1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
61
packages/core/__tests__/trait.spec.ts
Normal file
61
packages/core/__tests__/trait.spec.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { createTrait } from "../src/trait";
|
||||
|
||||
describe("trait", () => {
|
||||
it("can create runtime trait", () => {
|
||||
expect(
|
||||
createTrait({
|
||||
version: "core/v1",
|
||||
metadata: {
|
||||
name: "test-trait",
|
||||
},
|
||||
|
||||
spec: {
|
||||
properties: [{ name: "width", type: "number" }],
|
||||
state: {
|
||||
type: "string",
|
||||
},
|
||||
|
||||
methods: [
|
||||
{
|
||||
name: "times",
|
||||
parameters: {
|
||||
type: "number",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"kind": "Trait",
|
||||
"metadata": Object {
|
||||
"name": "test-trait",
|
||||
},
|
||||
"parsedVersion": Object {
|
||||
"category": "core",
|
||||
"value": "v1",
|
||||
},
|
||||
"spec": Object {
|
||||
"methods": Array [
|
||||
Object {
|
||||
"name": "times",
|
||||
"parameters": Object {
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
],
|
||||
"properties": Array [
|
||||
Object {
|
||||
"name": "width",
|
||||
"type": "number",
|
||||
},
|
||||
],
|
||||
"state": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"version": "core/v1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
@ -37,5 +37,8 @@
|
||||
"prettier": "^2.3.2",
|
||||
"ts-jest": "^27.0.3",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.7"
|
||||
}
|
||||
}
|
||||
|
45
packages/core/src/application.ts
Normal file
45
packages/core/src/application.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { Metadata } from "./metadata";
|
||||
import { parseVersion, Version } from "./version";
|
||||
|
||||
// spec
|
||||
|
||||
export type Application = {
|
||||
version: string;
|
||||
kind: "Application";
|
||||
metadata: Metadata;
|
||||
spec: ApplicationSpec;
|
||||
};
|
||||
|
||||
type ApplicationSpec = {
|
||||
components: ApplicationComponent[];
|
||||
};
|
||||
|
||||
type ApplicationComponent = {
|
||||
id: string;
|
||||
type: string;
|
||||
// do runtime type check
|
||||
properties: object;
|
||||
traits: ComponentTrait[];
|
||||
// scopes TBD
|
||||
};
|
||||
|
||||
type ComponentTrait = {
|
||||
type: string;
|
||||
// do runtime type check
|
||||
properties: object;
|
||||
};
|
||||
|
||||
// extended runtime
|
||||
export type RuntimeApplication = Application & {
|
||||
parsedVersion: Version;
|
||||
};
|
||||
|
||||
export function createApplication(
|
||||
options: Omit<Application, "kind">
|
||||
): RuntimeApplication {
|
||||
return {
|
||||
...options,
|
||||
kind: "Application",
|
||||
parsedVersion: parseVersion(options.version),
|
||||
};
|
||||
}
|
40
packages/core/src/component.ts
Normal file
40
packages/core/src/component.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { JSONSchema4 } from "json-schema";
|
||||
import { parseVersion } from "./version";
|
||||
import { Metadata } from "./metadata";
|
||||
import { MethodSchema } from "./method";
|
||||
import { Version } from "./version";
|
||||
|
||||
// spec
|
||||
|
||||
export type Component = {
|
||||
version: string;
|
||||
kind: "Component";
|
||||
metadata: Metadata;
|
||||
spec: ComponentSpec;
|
||||
};
|
||||
|
||||
type ComponentSpec = {
|
||||
properties: Array<JSONSchema4 & { name: string }>;
|
||||
acceptTraits: TraitSchema[];
|
||||
state: JSONSchema4;
|
||||
methods: MethodSchema[];
|
||||
};
|
||||
|
||||
type TraitSchema = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
// extended runtime
|
||||
export type RuntimeComponent = Component & {
|
||||
parsedVersion: Version;
|
||||
};
|
||||
|
||||
export function createComponent(
|
||||
options: Omit<Component, "kind">
|
||||
): RuntimeComponent {
|
||||
return {
|
||||
...options,
|
||||
kind: "Component",
|
||||
parsedVersion: parseVersion(options.version),
|
||||
};
|
||||
}
|
4
packages/core/src/metadata.ts
Normal file
4
packages/core/src/metadata.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export type Metadata = {
|
||||
name: string;
|
||||
description?: string;
|
||||
};
|
6
packages/core/src/method.ts
Normal file
6
packages/core/src/method.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { JSONSchema4 } from "json-schema";
|
||||
|
||||
export type MethodSchema = {
|
||||
name: string;
|
||||
parameters?: JSONSchema4;
|
||||
};
|
23
packages/core/src/scope.ts
Normal file
23
packages/core/src/scope.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Metadata } from "./metadata";
|
||||
import { parseVersion, Version } from "./version";
|
||||
|
||||
// spec
|
||||
|
||||
export type Scope = {
|
||||
version: string;
|
||||
kind: "Scope";
|
||||
metadata: Metadata;
|
||||
};
|
||||
|
||||
// extended runtime
|
||||
export type RuntimeScope = Scope & {
|
||||
parsedVersion: Version;
|
||||
};
|
||||
|
||||
export function createScope(options: Omit<Scope, "kind">): RuntimeScope {
|
||||
return {
|
||||
...options,
|
||||
kind: "Scope",
|
||||
parsedVersion: parseVersion(options.version),
|
||||
};
|
||||
}
|
32
packages/core/src/trait.ts
Normal file
32
packages/core/src/trait.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { JSONSchema4 } from "json-schema";
|
||||
import { Metadata } from "./metadata";
|
||||
import { MethodSchema } from "./method";
|
||||
import { parseVersion, Version } from "./version";
|
||||
|
||||
// spec
|
||||
|
||||
export type Trait = {
|
||||
version: string;
|
||||
kind: "Trait";
|
||||
metadata: Metadata;
|
||||
spec: TraitSpec;
|
||||
};
|
||||
|
||||
type TraitSpec = {
|
||||
properties: Array<JSONSchema4 & { name: string }>;
|
||||
state: JSONSchema4;
|
||||
methods: MethodSchema[];
|
||||
};
|
||||
|
||||
// extended runtime
|
||||
export type RuntimeTrait = Trait & {
|
||||
parsedVersion: Version;
|
||||
};
|
||||
|
||||
export function createTrait(options: Omit<Trait, "kind">): RuntimeTrait {
|
||||
return {
|
||||
...options,
|
||||
kind: "Trait",
|
||||
parsedVersion: parseVersion(options.version),
|
||||
};
|
||||
}
|
22
packages/core/src/version.ts
Normal file
22
packages/core/src/version.ts
Normal file
@ -0,0 +1,22 @@
|
||||
const VERSION_REG = /^([a-zA-Z-_\d]+)\/([a-zA-Z-_\d]+)$/;
|
||||
|
||||
export function isValidVersion(v: string): boolean {
|
||||
return VERSION_REG.test(v);
|
||||
}
|
||||
|
||||
export type Version = {
|
||||
category: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export function parseVersion(v: string): Version {
|
||||
if (!isValidVersion(v)) {
|
||||
throw new Error(`Invalid version string: "${v}"`);
|
||||
}
|
||||
|
||||
const [, category, value] = v.match(VERSION_REG)!;
|
||||
return {
|
||||
category,
|
||||
value,
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user