@living-architecture/riviere-schema 0.2.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/CLAUDE.md +9 -0
- package/README.md +11 -0
- package/dist/component-id.d.ts +74 -0
- package/dist/component-id.d.ts.map +1 -0
- package/dist/component-id.js +82 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/schema.d.ts +144 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/validation.d.ts +10 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +21 -0
- package/examples/ecommerce-complete-v2.json +2633 -0
- package/examples/ecommerce-complete.json +2486 -0
- package/package.json +26 -0
- package/project.json +3 -0
- package/riviere.schema.json +581 -0
- package/src/component-id.spec.ts +65 -0
- package/src/component-id.ts +97 -0
- package/src/index.ts +3 -0
- package/src/schema.spec.ts +169 -0
- package/src/schema.ts +184 -0
- package/src/validation.ts +32 -0
- package/tsconfig.json +13 -0
- package/tsconfig.lib.json +28 -0
- package/tsconfig.spec.json +34 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vite.config.ts +20 -0
- package/vitest.config.mts +24 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parts that make up a component ID.
|
|
3
|
+
*/
|
|
4
|
+
export interface ComponentIdParts {
|
|
5
|
+
domain: string
|
|
6
|
+
module: string
|
|
7
|
+
type: string
|
|
8
|
+
name: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents a structured component identifier.
|
|
13
|
+
*
|
|
14
|
+
* Component IDs follow the format `{domain}:{module}:{type}:{name}` in kebab-case.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const id = ComponentId.create({
|
|
19
|
+
* domain: 'orders',
|
|
20
|
+
* module: 'checkout',
|
|
21
|
+
* type: 'api',
|
|
22
|
+
* name: 'Create Order'
|
|
23
|
+
* })
|
|
24
|
+
* id.toString() // 'orders:checkout:api:create-order'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export class ComponentId {
|
|
28
|
+
private readonly _name: string
|
|
29
|
+
private readonly value: string
|
|
30
|
+
|
|
31
|
+
private constructor(name: string, value: string) {
|
|
32
|
+
this._name = name
|
|
33
|
+
this.value = value
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates a ComponentId from individual parts.
|
|
38
|
+
*
|
|
39
|
+
* @param parts - Domain, module, type, and name segments
|
|
40
|
+
* @returns A new ComponentId instance
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const id = ComponentId.create({
|
|
45
|
+
* domain: 'orders',
|
|
46
|
+
* module: 'checkout',
|
|
47
|
+
* type: 'api',
|
|
48
|
+
* name: 'Create Order'
|
|
49
|
+
* })
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
static create(parts: ComponentIdParts): ComponentId {
|
|
53
|
+
const nameSegment = parts.name.toLowerCase().replace(/\s+/g, '-')
|
|
54
|
+
const value = `${parts.domain}:${parts.module}:${parts.type}:${nameSegment}`
|
|
55
|
+
return new ComponentId(nameSegment, value)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Parses a string ID into a ComponentId instance.
|
|
60
|
+
*
|
|
61
|
+
* @param id - String in format `domain:module:type:name`
|
|
62
|
+
* @returns A ComponentId instance
|
|
63
|
+
* @throws If the format is invalid
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const id = ComponentId.parse('orders:checkout:api:create-order')
|
|
68
|
+
* id.name() // 'create-order'
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
static parse(id: string): ComponentId {
|
|
72
|
+
const parts = id.split(':')
|
|
73
|
+
const name = parts[3]
|
|
74
|
+
if (parts.length !== 4 || name === undefined) {
|
|
75
|
+
throw new Error(`Invalid component ID format: '${id}'. Expected 'domain:module:type:name'`)
|
|
76
|
+
}
|
|
77
|
+
return new ComponentId(name, id)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Returns the full component ID string.
|
|
82
|
+
*
|
|
83
|
+
* @returns Full ID in format `domain:module:type:name`
|
|
84
|
+
*/
|
|
85
|
+
toString(): string {
|
|
86
|
+
return this.value
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Returns the name segment of the component ID.
|
|
91
|
+
*
|
|
92
|
+
* @returns The kebab-case name portion
|
|
93
|
+
*/
|
|
94
|
+
name(): string {
|
|
95
|
+
return this._name
|
|
96
|
+
}
|
|
97
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RiviereGraph,
|
|
3
|
+
Component,
|
|
4
|
+
UIComponent,
|
|
5
|
+
APIComponent,
|
|
6
|
+
Link,
|
|
7
|
+
GraphMetadata,
|
|
8
|
+
} from './schema'
|
|
9
|
+
import { parseRiviereGraph, formatValidationErrors } from './validation'
|
|
10
|
+
|
|
11
|
+
describe('formatValidationErrors()', () => {
|
|
12
|
+
it('returns generic message when errors is null', () => {
|
|
13
|
+
const result = formatValidationErrors(null)
|
|
14
|
+
expect(result).toBe('validation failed without specific errors')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('returns generic message when errors is empty array', () => {
|
|
18
|
+
const result = formatValidationErrors([])
|
|
19
|
+
expect(result).toBe('validation failed without specific errors')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('formats single error with path and message', () => {
|
|
23
|
+
const errors = [{ instancePath: '/version', message: 'must match pattern' }]
|
|
24
|
+
const result = formatValidationErrors(errors)
|
|
25
|
+
expect(result).toBe('/version: must match pattern')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('formats multiple errors joined by newlines', () => {
|
|
29
|
+
const errors = [
|
|
30
|
+
{ instancePath: '/version', message: 'must match pattern' },
|
|
31
|
+
{ instancePath: '/components/0/type', message: 'must be equal to one of the allowed values' },
|
|
32
|
+
]
|
|
33
|
+
const result = formatValidationErrors(errors)
|
|
34
|
+
expect(result).toBe('/version: must match pattern\n/components/0/type: must be equal to one of the allowed values')
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe('parseRiviereGraph()', () => {
|
|
39
|
+
it('parses valid graph and returns typed RiviereGraph', () => {
|
|
40
|
+
const input = {
|
|
41
|
+
version: '1.0',
|
|
42
|
+
metadata: { domains: { test: { description: 'Test', systemType: 'domain' } } },
|
|
43
|
+
components: [],
|
|
44
|
+
links: [],
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result = parseRiviereGraph(input)
|
|
48
|
+
|
|
49
|
+
expect(result.version).toBe('1.0')
|
|
50
|
+
expect(result.components).toHaveLength(0)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('throws on invalid component type', () => {
|
|
54
|
+
const input = {
|
|
55
|
+
version: '1.0',
|
|
56
|
+
metadata: { domains: { test: { description: 'Test', systemType: 'domain' } } },
|
|
57
|
+
components: [{ id: 'x', type: 'InvalidType', name: 'X', domain: 'test', module: 'mod', sourceLocation: { repository: 'r', filePath: 'f' } }],
|
|
58
|
+
links: [],
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
expect(() => parseRiviereGraph(input)).toThrow()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('throws on missing required field with error details', () => {
|
|
65
|
+
const input = {
|
|
66
|
+
metadata: { domains: { test: { description: 'Test', systemType: 'domain' } } },
|
|
67
|
+
components: [],
|
|
68
|
+
links: [],
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
expect(() => parseRiviereGraph(input)).toThrow(/Invalid RiviereGraph/)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('throws on invalid version format', () => {
|
|
75
|
+
const input = {
|
|
76
|
+
version: 'not-a-version',
|
|
77
|
+
metadata: { domains: { test: { description: 'Test', systemType: 'domain' } } },
|
|
78
|
+
components: [],
|
|
79
|
+
links: [],
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
expect(() => parseRiviereGraph(input)).toThrow()
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
describe('riviere-schema types', () => {
|
|
87
|
+
it('compiles a minimal valid graph structure', () => {
|
|
88
|
+
const graph: RiviereGraph = {
|
|
89
|
+
version: '1.0',
|
|
90
|
+
metadata: {
|
|
91
|
+
domains: {
|
|
92
|
+
test: {
|
|
93
|
+
description: 'Test domain',
|
|
94
|
+
systemType: 'domain',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
components: [
|
|
99
|
+
{
|
|
100
|
+
id: 'test:mod:ui:page',
|
|
101
|
+
type: 'UI',
|
|
102
|
+
name: 'Test Page',
|
|
103
|
+
domain: 'test',
|
|
104
|
+
module: 'mod',
|
|
105
|
+
route: '/test',
|
|
106
|
+
sourceLocation: {
|
|
107
|
+
repository: 'test-repo',
|
|
108
|
+
filePath: 'src/page.tsx',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
links: [],
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
expect(graph.version).toBe('1.0')
|
|
116
|
+
expect(graph.components).toHaveLength(1)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('enforces discriminated union for component types', () => {
|
|
120
|
+
const uiComponent: UIComponent = {
|
|
121
|
+
id: 'test:mod:ui:page',
|
|
122
|
+
type: 'UI',
|
|
123
|
+
name: 'Page',
|
|
124
|
+
domain: 'test',
|
|
125
|
+
module: 'mod',
|
|
126
|
+
route: '/page',
|
|
127
|
+
sourceLocation: { repository: 'repo', filePath: 'file.ts' },
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const apiComponent: APIComponent = {
|
|
131
|
+
id: 'test:mod:api:endpoint',
|
|
132
|
+
type: 'API',
|
|
133
|
+
name: 'Endpoint',
|
|
134
|
+
domain: 'test',
|
|
135
|
+
module: 'mod',
|
|
136
|
+
apiType: 'REST',
|
|
137
|
+
httpMethod: 'POST',
|
|
138
|
+
path: '/api/test',
|
|
139
|
+
sourceLocation: { repository: 'repo', filePath: 'api.ts' },
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const components: Component[] = [uiComponent, apiComponent]
|
|
143
|
+
expect(components).toHaveLength(2)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('enforces link structure', () => {
|
|
147
|
+
const link: Link = {
|
|
148
|
+
source: 'component-a',
|
|
149
|
+
target: 'component-b',
|
|
150
|
+
type: 'sync',
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
expect(link.source).toBe('component-a')
|
|
154
|
+
expect(link.target).toBe('component-b')
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('enforces metadata structure with required domains', () => {
|
|
158
|
+
const metadata: GraphMetadata = {
|
|
159
|
+
domains: {
|
|
160
|
+
orders: {
|
|
161
|
+
description: 'Order management',
|
|
162
|
+
systemType: 'domain',
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
expect(metadata.domains['orders']?.systemType).toBe('domain')
|
|
168
|
+
})
|
|
169
|
+
})
|
package/src/schema.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
export interface SourceLocation {
|
|
2
|
+
repository: string
|
|
3
|
+
filePath: string
|
|
4
|
+
lineNumber?: number
|
|
5
|
+
endLineNumber?: number
|
|
6
|
+
methodName?: string
|
|
7
|
+
url?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface OperationParameter {
|
|
11
|
+
name: string
|
|
12
|
+
type: string
|
|
13
|
+
description?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface OperationSignature {
|
|
17
|
+
parameters?: OperationParameter[]
|
|
18
|
+
returnType?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OperationBehavior {
|
|
22
|
+
reads?: string[]
|
|
23
|
+
validates?: string[]
|
|
24
|
+
modifies?: string[]
|
|
25
|
+
emits?: string[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface StateTransition {
|
|
29
|
+
from: string
|
|
30
|
+
to: string
|
|
31
|
+
trigger?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ComponentType =
|
|
35
|
+
| 'UI'
|
|
36
|
+
| 'API'
|
|
37
|
+
| 'UseCase'
|
|
38
|
+
| 'DomainOp'
|
|
39
|
+
| 'Event'
|
|
40
|
+
| 'EventHandler'
|
|
41
|
+
| 'Custom'
|
|
42
|
+
|
|
43
|
+
interface ComponentBase {
|
|
44
|
+
id: string
|
|
45
|
+
name: string
|
|
46
|
+
domain: string
|
|
47
|
+
module: string
|
|
48
|
+
description?: string
|
|
49
|
+
sourceLocation: SourceLocation
|
|
50
|
+
metadata?: Record<string, unknown>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface UIComponent extends ComponentBase {
|
|
54
|
+
type: 'UI'
|
|
55
|
+
route: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type ApiType = 'REST' | 'GraphQL' | 'other'
|
|
59
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
|
|
60
|
+
|
|
61
|
+
export interface APIComponent extends ComponentBase {
|
|
62
|
+
type: 'API'
|
|
63
|
+
apiType: ApiType
|
|
64
|
+
httpMethod?: HttpMethod
|
|
65
|
+
path?: string
|
|
66
|
+
operationName?: string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface UseCaseComponent extends ComponentBase {
|
|
70
|
+
type: 'UseCase'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface DomainOpComponent extends ComponentBase {
|
|
74
|
+
type: 'DomainOp'
|
|
75
|
+
operationName: string
|
|
76
|
+
entity?: string
|
|
77
|
+
signature?: OperationSignature
|
|
78
|
+
behavior?: OperationBehavior
|
|
79
|
+
stateChanges?: StateTransition[]
|
|
80
|
+
businessRules?: string[]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface EventComponent extends ComponentBase {
|
|
84
|
+
type: 'Event'
|
|
85
|
+
eventName: string
|
|
86
|
+
eventSchema?: string
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface EventHandlerComponent extends ComponentBase {
|
|
90
|
+
type: 'EventHandler'
|
|
91
|
+
subscribedEvents: string[]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface CustomComponent extends ComponentBase {
|
|
95
|
+
type: 'Custom'
|
|
96
|
+
customTypeName: string
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type Component =
|
|
100
|
+
| UIComponent
|
|
101
|
+
| APIComponent
|
|
102
|
+
| UseCaseComponent
|
|
103
|
+
| DomainOpComponent
|
|
104
|
+
| EventComponent
|
|
105
|
+
| EventHandlerComponent
|
|
106
|
+
| CustomComponent
|
|
107
|
+
|
|
108
|
+
export type LinkType = 'sync' | 'async'
|
|
109
|
+
|
|
110
|
+
export interface PayloadDefinition {
|
|
111
|
+
type?: string
|
|
112
|
+
schema?: Record<string, unknown>
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface Link {
|
|
116
|
+
id?: string
|
|
117
|
+
source: string
|
|
118
|
+
target: string
|
|
119
|
+
type?: LinkType
|
|
120
|
+
payload?: PayloadDefinition
|
|
121
|
+
sourceLocation?: SourceLocation
|
|
122
|
+
metadata?: Record<string, unknown>
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ExternalTarget {
|
|
126
|
+
name: string
|
|
127
|
+
domain?: string
|
|
128
|
+
repository?: string
|
|
129
|
+
url?: string
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface ExternalLink {
|
|
133
|
+
id?: string
|
|
134
|
+
source: string
|
|
135
|
+
target: ExternalTarget
|
|
136
|
+
type?: LinkType
|
|
137
|
+
description?: string
|
|
138
|
+
sourceLocation?: SourceLocation
|
|
139
|
+
metadata?: Record<string, unknown>
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export type SystemType = 'domain' | 'bff' | 'ui' | 'other'
|
|
143
|
+
|
|
144
|
+
export interface DomainMetadata {
|
|
145
|
+
description: string
|
|
146
|
+
systemType: SystemType
|
|
147
|
+
[key: string]: unknown
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export type CustomPropertyType = 'string' | 'number' | 'boolean' | 'array' | 'object'
|
|
151
|
+
|
|
152
|
+
export interface CustomPropertyDefinition {
|
|
153
|
+
type: CustomPropertyType
|
|
154
|
+
description?: string
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface CustomTypeDefinition {
|
|
158
|
+
description?: string
|
|
159
|
+
requiredProperties?: Record<string, CustomPropertyDefinition>
|
|
160
|
+
optionalProperties?: Record<string, CustomPropertyDefinition>
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface SourceInfo {
|
|
164
|
+
repository: string
|
|
165
|
+
commit?: string
|
|
166
|
+
extractedAt?: string
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface GraphMetadata {
|
|
170
|
+
name?: string
|
|
171
|
+
description?: string
|
|
172
|
+
generated?: string
|
|
173
|
+
sources?: SourceInfo[]
|
|
174
|
+
domains: Record<string, DomainMetadata>
|
|
175
|
+
customTypes?: Record<string, CustomTypeDefinition>
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface RiviereGraph {
|
|
179
|
+
version: string
|
|
180
|
+
metadata: GraphMetadata
|
|
181
|
+
components: Component[]
|
|
182
|
+
links: Link[]
|
|
183
|
+
externalLinks?: ExternalLink[]
|
|
184
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Ajv from 'ajv'
|
|
2
|
+
import addFormats from 'ajv-formats'
|
|
3
|
+
import type { RiviereGraph } from './schema'
|
|
4
|
+
import rawSchema from '../riviere.schema.json' with { type: 'json' }
|
|
5
|
+
|
|
6
|
+
const ajv = new Ajv({ allErrors: true })
|
|
7
|
+
addFormats(ajv)
|
|
8
|
+
|
|
9
|
+
const validate = ajv.compile(rawSchema)
|
|
10
|
+
|
|
11
|
+
export function isRiviereGraph(data: unknown): data is RiviereGraph {
|
|
12
|
+
return validate(data) === true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ValidationErrorLike {
|
|
16
|
+
instancePath: string
|
|
17
|
+
message?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function formatValidationErrors(errors: ValidationErrorLike[] | null | undefined): string {
|
|
21
|
+
if (!errors || errors.length === 0) {
|
|
22
|
+
return 'validation failed without specific errors'
|
|
23
|
+
}
|
|
24
|
+
return errors.map((e) => `${e.instancePath}: ${e.message}`).join('\n')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function parseRiviereGraph(data: unknown): RiviereGraph {
|
|
28
|
+
if (isRiviereGraph(data)) {
|
|
29
|
+
return data
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`Invalid RiviereGraph:\n${formatValidationErrors(validate.errors)}`)
|
|
32
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": ".",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
|
|
8
|
+
"emitDeclarationOnly": false,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"types": ["node"]
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*.ts"],
|
|
13
|
+
"references": [],
|
|
14
|
+
"exclude": [
|
|
15
|
+
"vite.config.ts",
|
|
16
|
+
"vite.config.mts",
|
|
17
|
+
"vitest.config.ts",
|
|
18
|
+
"vitest.config.mts",
|
|
19
|
+
"src/**/*.test.ts",
|
|
20
|
+
"src/**/*.spec.ts",
|
|
21
|
+
"src/**/*.test.tsx",
|
|
22
|
+
"src/**/*.spec.tsx",
|
|
23
|
+
"src/**/*.test.js",
|
|
24
|
+
"src/**/*.spec.js",
|
|
25
|
+
"src/**/*.test.jsx",
|
|
26
|
+
"src/**/*.spec.jsx"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./out-tsc/vitest",
|
|
5
|
+
"types": [
|
|
6
|
+
"vitest/globals",
|
|
7
|
+
"vitest/importMeta",
|
|
8
|
+
"vite/client",
|
|
9
|
+
"node",
|
|
10
|
+
"vitest"
|
|
11
|
+
],
|
|
12
|
+
"forceConsistentCasingInFileNames": true
|
|
13
|
+
},
|
|
14
|
+
"include": [
|
|
15
|
+
"vite.config.ts",
|
|
16
|
+
"vite.config.mts",
|
|
17
|
+
"vitest.config.ts",
|
|
18
|
+
"vitest.config.mts",
|
|
19
|
+
"src/**/*.test.ts",
|
|
20
|
+
"src/**/*.spec.ts",
|
|
21
|
+
"src/**/*.test.tsx",
|
|
22
|
+
"src/**/*.spec.tsx",
|
|
23
|
+
"src/**/*.test.js",
|
|
24
|
+
"src/**/*.spec.js",
|
|
25
|
+
"src/**/*.test.jsx",
|
|
26
|
+
"src/**/*.spec.jsx",
|
|
27
|
+
"src/**/*.d.ts"
|
|
28
|
+
],
|
|
29
|
+
"references": [
|
|
30
|
+
{
|
|
31
|
+
"path": "./tsconfig.lib.json"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":[],"fileInfos":[],"root":[],"options":{"composite":true,"declarationMap":true,"emitDeclarationOnly":true,"exactOptionalPropertyTypes":true,"importHelpers":true,"module":199,"noEmitOnError":true,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noImplicitReturns":true,"noPropertyAccessFromIndexSignature":true,"noUncheckedIndexedAccess":true,"noUnusedLocals":true,"noUnusedParameters":true,"skipLibCheck":true,"strict":true,"target":9,"verbatimModuleSyntax":true},"version":"5.9.3"}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types='vitest' />
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
|
|
4
|
+
export default defineConfig(() => ({
|
|
5
|
+
root: import.meta.dirname,
|
|
6
|
+
cacheDir: '../node_modules/.vite/riviere-schema',
|
|
7
|
+
plugins: [],
|
|
8
|
+
test: {
|
|
9
|
+
name: '@living-architecture/riviere-schema',
|
|
10
|
+
watch: false,
|
|
11
|
+
globals: true,
|
|
12
|
+
environment: 'node',
|
|
13
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
14
|
+
reporters: ['default'],
|
|
15
|
+
coverage: {
|
|
16
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
17
|
+
provider: 'v8' as const,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
}));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig(() => ({
|
|
4
|
+
root: __dirname,
|
|
5
|
+
cacheDir: '../../node_modules/.vite/packages/riviere-schema',
|
|
6
|
+
test: {
|
|
7
|
+
name: '@living-architecture/riviere-schema',
|
|
8
|
+
watch: false,
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: 'node',
|
|
11
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
12
|
+
reporters: ['default'],
|
|
13
|
+
coverage: {
|
|
14
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
15
|
+
provider: 'v8' as const,
|
|
16
|
+
thresholds: {
|
|
17
|
+
lines: 100,
|
|
18
|
+
statements: 100,
|
|
19
|
+
functions: 100,
|
|
20
|
+
branches: 100,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
}));
|