@prisma-next/framework-components 0.0.1
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/LICENSE +201 -0
- package/README.md +38 -0
- package/package.json +44 -0
- package/src/codec-types.ts +46 -0
- package/src/control-capabilities.ts +31 -0
- package/src/control-descriptors.ts +69 -0
- package/src/control-instances.ts +70 -0
- package/src/control-migration-types.ts +273 -0
- package/src/control-result-types.ts +160 -0
- package/src/control-schema-view.ts +95 -0
- package/src/control-stack.ts +292 -0
- package/src/emission-types.ts +28 -0
- package/src/execution-descriptors.ts +71 -0
- package/src/execution-instances.ts +22 -0
- package/src/execution-requirements.ts +47 -0
- package/src/execution-stack.ts +143 -0
- package/src/exports/authoring.ts +22 -0
- package/src/exports/codec.ts +2 -0
- package/src/exports/components.ts +24 -0
- package/src/exports/control.ts +59 -0
- package/src/exports/emission.ts +6 -0
- package/src/exports/execution.ts +17 -0
- package/src/framework-authoring.ts +383 -0
- package/src/framework-components.ts +402 -0
- package/src/types-import-spec.ts +9 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import type { CodecLookup } from './codec-types';
|
|
2
|
+
import type {
|
|
3
|
+
ControlAdapterDescriptor,
|
|
4
|
+
ControlDriverDescriptor,
|
|
5
|
+
ControlExtensionDescriptor,
|
|
6
|
+
ControlFamilyDescriptor,
|
|
7
|
+
ControlTargetDescriptor,
|
|
8
|
+
} from './control-descriptors';
|
|
9
|
+
import type {
|
|
10
|
+
AuthoringContributions,
|
|
11
|
+
AuthoringFieldNamespace,
|
|
12
|
+
AuthoringFieldPresetDescriptor,
|
|
13
|
+
AuthoringTypeConstructorDescriptor,
|
|
14
|
+
AuthoringTypeNamespace,
|
|
15
|
+
} from './framework-authoring';
|
|
16
|
+
import type { ComponentMetadata } from './framework-components';
|
|
17
|
+
import type { TypesImportSpec } from './types-import-spec';
|
|
18
|
+
|
|
19
|
+
export interface AssembledAuthoringContributions {
|
|
20
|
+
readonly field: AuthoringFieldNamespace;
|
|
21
|
+
readonly type: AuthoringTypeNamespace;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ControlStack<
|
|
25
|
+
TFamilyId extends string = string,
|
|
26
|
+
TTargetId extends string = string,
|
|
27
|
+
> {
|
|
28
|
+
readonly family: ControlFamilyDescriptor<TFamilyId>;
|
|
29
|
+
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
|
|
30
|
+
readonly adapter?: ControlAdapterDescriptor<TFamilyId, TTargetId> | undefined;
|
|
31
|
+
readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;
|
|
32
|
+
readonly extensionPacks: readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[];
|
|
33
|
+
|
|
34
|
+
readonly codecTypeImports: ReadonlyArray<TypesImportSpec>;
|
|
35
|
+
readonly operationTypeImports: ReadonlyArray<TypesImportSpec>;
|
|
36
|
+
readonly queryOperationTypeImports: ReadonlyArray<TypesImportSpec>;
|
|
37
|
+
readonly extensionIds: ReadonlyArray<string>;
|
|
38
|
+
readonly codecLookup: CodecLookup;
|
|
39
|
+
readonly authoringContributions: AssembledAuthoringContributions;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CreateControlStackInput<
|
|
43
|
+
TFamilyId extends string = string,
|
|
44
|
+
TTargetId extends string = string,
|
|
45
|
+
> {
|
|
46
|
+
readonly family: ControlFamilyDescriptor<TFamilyId>;
|
|
47
|
+
readonly target: ControlTargetDescriptor<TFamilyId, TTargetId>;
|
|
48
|
+
readonly adapter?: ControlAdapterDescriptor<TFamilyId, TTargetId> | undefined;
|
|
49
|
+
readonly driver?: ControlDriverDescriptor<TFamilyId, TTargetId> | undefined;
|
|
50
|
+
readonly extensionPacks?:
|
|
51
|
+
| ReadonlyArray<ControlExtensionDescriptor<TFamilyId, TTargetId>>
|
|
52
|
+
| undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function addUniqueId(ids: string[], seen: Set<string>, id: string): void {
|
|
56
|
+
if (!seen.has(id)) {
|
|
57
|
+
ids.push(id);
|
|
58
|
+
seen.add(id);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function assertUniqueCodecOwner(options: {
|
|
63
|
+
readonly codecId: string;
|
|
64
|
+
readonly owners: Map<string, string>;
|
|
65
|
+
readonly descriptorId: string;
|
|
66
|
+
readonly entityLabel: string;
|
|
67
|
+
readonly entityOwnershipLabel: string;
|
|
68
|
+
}): void {
|
|
69
|
+
const existingOwner = options.owners.get(options.codecId);
|
|
70
|
+
if (existingOwner !== undefined) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Duplicate ${options.entityLabel} for codecId "${options.codecId}". ` +
|
|
73
|
+
`Descriptor "${options.descriptorId}" conflicts with "${existingOwner}". ` +
|
|
74
|
+
`Each codecId can only have one ${options.entityOwnershipLabel}.`,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function extractCodecTypeImports(
|
|
80
|
+
descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,
|
|
81
|
+
): ReadonlyArray<TypesImportSpec> {
|
|
82
|
+
const imports: TypesImportSpec[] = [];
|
|
83
|
+
|
|
84
|
+
for (const descriptor of descriptors) {
|
|
85
|
+
const codecTypes = descriptor.types?.codecTypes;
|
|
86
|
+
if (codecTypes?.import) {
|
|
87
|
+
imports.push(codecTypes.import);
|
|
88
|
+
}
|
|
89
|
+
if (codecTypes?.typeImports) {
|
|
90
|
+
imports.push(...codecTypes.typeImports);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return imports;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function extractOperationTypeImports(
|
|
98
|
+
descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,
|
|
99
|
+
): ReadonlyArray<TypesImportSpec> {
|
|
100
|
+
const imports: TypesImportSpec[] = [];
|
|
101
|
+
|
|
102
|
+
for (const descriptor of descriptors) {
|
|
103
|
+
const operationTypes = descriptor.types?.operationTypes;
|
|
104
|
+
if (operationTypes?.import) {
|
|
105
|
+
imports.push(operationTypes.import);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return imports;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function extractQueryOperationTypeImports(
|
|
113
|
+
descriptors: ReadonlyArray<Pick<ComponentMetadata, 'types'>>,
|
|
114
|
+
): ReadonlyArray<TypesImportSpec> {
|
|
115
|
+
const imports: TypesImportSpec[] = [];
|
|
116
|
+
|
|
117
|
+
for (const descriptor of descriptors) {
|
|
118
|
+
const queryOperationTypes = descriptor.types?.queryOperationTypes;
|
|
119
|
+
if (queryOperationTypes?.import) {
|
|
120
|
+
imports.push(queryOperationTypes.import);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return imports;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function extractComponentIds(
|
|
128
|
+
family: { readonly id: string },
|
|
129
|
+
target: { readonly id: string },
|
|
130
|
+
adapter: { readonly id: string } | undefined,
|
|
131
|
+
extensions: ReadonlyArray<{ readonly id: string }>,
|
|
132
|
+
): ReadonlyArray<string> {
|
|
133
|
+
const ids: string[] = [];
|
|
134
|
+
const seen = new Set<string>();
|
|
135
|
+
|
|
136
|
+
addUniqueId(ids, seen, family.id);
|
|
137
|
+
addUniqueId(ids, seen, target.id);
|
|
138
|
+
if (adapter) {
|
|
139
|
+
addUniqueId(ids, seen, adapter.id);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const ext of extensions) {
|
|
143
|
+
addUniqueId(ids, seen, ext.id);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return ids;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isTypeConstructorDescriptor(value: unknown): value is AuthoringTypeConstructorDescriptor {
|
|
150
|
+
return (
|
|
151
|
+
typeof value === 'object' &&
|
|
152
|
+
value !== null &&
|
|
153
|
+
(value as { kind?: unknown }).kind === 'typeConstructor'
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function isFieldPresetDescriptor(value: unknown): value is AuthoringFieldPresetDescriptor {
|
|
158
|
+
return (
|
|
159
|
+
typeof value === 'object' &&
|
|
160
|
+
value !== null &&
|
|
161
|
+
(value as { kind?: unknown }).kind === 'fieldPreset'
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function mergeAuthoringNamespaces(
|
|
166
|
+
target: Record<string, unknown>,
|
|
167
|
+
source: Record<string, unknown>,
|
|
168
|
+
path: readonly string[],
|
|
169
|
+
leafGuard: (value: unknown) => boolean,
|
|
170
|
+
label: string,
|
|
171
|
+
): void {
|
|
172
|
+
const assertSafePath = (currentPath: readonly string[]) => {
|
|
173
|
+
const blockedSegment = currentPath.find(
|
|
174
|
+
(segment) => segment === '__proto__' || segment === 'constructor' || segment === 'prototype',
|
|
175
|
+
);
|
|
176
|
+
if (blockedSegment) {
|
|
177
|
+
throw new Error(
|
|
178
|
+
`Invalid authoring ${label} helper "${currentPath.join('.')}". Helper path segments must not use "${blockedSegment}".`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
for (const [key, sourceValue] of Object.entries(source)) {
|
|
184
|
+
const currentPath = [...path, key];
|
|
185
|
+
assertSafePath(currentPath);
|
|
186
|
+
const hasExistingValue = Object.hasOwn(target, key);
|
|
187
|
+
const existingValue = hasExistingValue ? target[key] : undefined;
|
|
188
|
+
|
|
189
|
+
if (!hasExistingValue) {
|
|
190
|
+
target[key] = sourceValue;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const existingIsLeaf = leafGuard(existingValue);
|
|
195
|
+
const sourceIsLeaf = leafGuard(sourceValue);
|
|
196
|
+
|
|
197
|
+
if (existingIsLeaf || sourceIsLeaf) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`Duplicate authoring ${label} helper "${currentPath.join('.')}". Descriptor contributions must be unique across composed components.`,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
mergeAuthoringNamespaces(
|
|
204
|
+
existingValue as Record<string, unknown>,
|
|
205
|
+
sourceValue as Record<string, unknown>,
|
|
206
|
+
currentPath,
|
|
207
|
+
leafGuard,
|
|
208
|
+
label,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function assembleAuthoringContributions(
|
|
214
|
+
descriptors: ReadonlyArray<{ readonly authoring?: AuthoringContributions }>,
|
|
215
|
+
): AssembledAuthoringContributions {
|
|
216
|
+
const field = {} as Record<string, unknown>;
|
|
217
|
+
const type = {} as Record<string, unknown>;
|
|
218
|
+
|
|
219
|
+
for (const descriptor of descriptors) {
|
|
220
|
+
if (descriptor.authoring?.field) {
|
|
221
|
+
mergeAuthoringNamespaces(
|
|
222
|
+
field,
|
|
223
|
+
descriptor.authoring.field,
|
|
224
|
+
[],
|
|
225
|
+
isFieldPresetDescriptor,
|
|
226
|
+
'field',
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
if (!descriptor.authoring?.type) {
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
mergeAuthoringNamespaces(
|
|
233
|
+
type,
|
|
234
|
+
descriptor.authoring.type,
|
|
235
|
+
[],
|
|
236
|
+
isTypeConstructorDescriptor,
|
|
237
|
+
'type',
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
field: field as AuthoringFieldNamespace,
|
|
243
|
+
type: type as AuthoringTypeNamespace,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function extractCodecLookup(
|
|
248
|
+
descriptors: ReadonlyArray<Pick<ComponentMetadata & { id?: string }, 'types' | 'id'>>,
|
|
249
|
+
): CodecLookup {
|
|
250
|
+
const byId = new Map<string, import('./codec-types').Codec>();
|
|
251
|
+
const owners = new Map<string, string>();
|
|
252
|
+
for (const descriptor of descriptors) {
|
|
253
|
+
const codecInstances = descriptor.types?.codecTypes?.codecInstances;
|
|
254
|
+
if (!codecInstances) continue;
|
|
255
|
+
const descriptorId = descriptor.id ?? '<unknown>';
|
|
256
|
+
for (const codec of codecInstances) {
|
|
257
|
+
assertUniqueCodecOwner({
|
|
258
|
+
codecId: codec.id,
|
|
259
|
+
owners,
|
|
260
|
+
descriptorId,
|
|
261
|
+
entityLabel: 'codec instance',
|
|
262
|
+
entityOwnershipLabel: 'codec instance provider',
|
|
263
|
+
});
|
|
264
|
+
owners.set(codec.id, descriptorId);
|
|
265
|
+
byId.set(codec.id, codec);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return { get: (id) => byId.get(id) };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function createControlStack<TFamilyId extends string, TTargetId extends string>(
|
|
272
|
+
input: CreateControlStackInput<TFamilyId, TTargetId>,
|
|
273
|
+
): ControlStack<TFamilyId, TTargetId> {
|
|
274
|
+
const { family, target, adapter, driver, extensionPacks = [] } = input;
|
|
275
|
+
|
|
276
|
+
const allDescriptors = [family, target, ...(adapter ? [adapter] : []), ...extensionPacks];
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
family,
|
|
280
|
+
target,
|
|
281
|
+
adapter,
|
|
282
|
+
driver,
|
|
283
|
+
extensionPacks: extensionPacks as readonly ControlExtensionDescriptor<TFamilyId, TTargetId>[],
|
|
284
|
+
|
|
285
|
+
codecTypeImports: extractCodecTypeImports(allDescriptors),
|
|
286
|
+
operationTypeImports: extractOperationTypeImports(allDescriptors),
|
|
287
|
+
queryOperationTypeImports: extractQueryOperationTypeImports(allDescriptors),
|
|
288
|
+
extensionIds: extractComponentIds(family, target, adapter, extensionPacks),
|
|
289
|
+
codecLookup: extractCodecLookup(allDescriptors),
|
|
290
|
+
authoringContributions: assembleAuthoringContributions(allDescriptors),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Contract, ContractModel } from '@prisma-next/contract/types';
|
|
2
|
+
import type { TypesImportSpec } from './types-import-spec';
|
|
3
|
+
|
|
4
|
+
export interface GenerateContractTypesOptions {
|
|
5
|
+
readonly queryOperationTypeImports?: ReadonlyArray<TypesImportSpec>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ValidationContext {
|
|
9
|
+
readonly codecTypeImports?: ReadonlyArray<TypesImportSpec>;
|
|
10
|
+
readonly operationTypeImports?: ReadonlyArray<TypesImportSpec>;
|
|
11
|
+
readonly extensionIds?: ReadonlyArray<string>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface EmissionSpi {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
|
|
17
|
+
generateStorageType(contract: Contract, storageHashTypeName: string): string;
|
|
18
|
+
|
|
19
|
+
generateModelStorageType(modelName: string, model: ContractModel): string;
|
|
20
|
+
|
|
21
|
+
getFamilyImports(): string[];
|
|
22
|
+
|
|
23
|
+
getFamilyTypeAliases(options?: GenerateContractTypesOptions): string;
|
|
24
|
+
|
|
25
|
+
getTypeMapsExpression(): string;
|
|
26
|
+
|
|
27
|
+
getContractWrapper(contractBaseName: string, typeMapsName: string): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RuntimeAdapterInstance,
|
|
3
|
+
RuntimeDriverInstance,
|
|
4
|
+
RuntimeExtensionInstance,
|
|
5
|
+
RuntimeFamilyInstance,
|
|
6
|
+
RuntimeTargetInstance,
|
|
7
|
+
} from './execution-instances';
|
|
8
|
+
import type {
|
|
9
|
+
AdapterDescriptor,
|
|
10
|
+
DriverDescriptor,
|
|
11
|
+
ExtensionDescriptor,
|
|
12
|
+
FamilyDescriptor,
|
|
13
|
+
TargetDescriptor,
|
|
14
|
+
} from './framework-components';
|
|
15
|
+
|
|
16
|
+
export interface RuntimeFamilyDescriptor<
|
|
17
|
+
TFamilyId extends string,
|
|
18
|
+
TFamilyInstance extends RuntimeFamilyInstance<TFamilyId> = RuntimeFamilyInstance<TFamilyId>,
|
|
19
|
+
> extends FamilyDescriptor<TFamilyId> {
|
|
20
|
+
create<TTargetId extends string>(options: {
|
|
21
|
+
readonly target: RuntimeTargetDescriptor<TFamilyId, TTargetId>;
|
|
22
|
+
readonly adapter: RuntimeAdapterDescriptor<TFamilyId, TTargetId>;
|
|
23
|
+
readonly driver: RuntimeDriverDescriptor<TFamilyId, TTargetId>;
|
|
24
|
+
readonly extensionPacks: readonly RuntimeExtensionDescriptor<TFamilyId, TTargetId>[];
|
|
25
|
+
}): TFamilyInstance;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface RuntimeTargetDescriptor<
|
|
29
|
+
TFamilyId extends string,
|
|
30
|
+
TTargetId extends string,
|
|
31
|
+
TTargetInstance extends RuntimeTargetInstance<TFamilyId, TTargetId> = RuntimeTargetInstance<
|
|
32
|
+
TFamilyId,
|
|
33
|
+
TTargetId
|
|
34
|
+
>,
|
|
35
|
+
> extends TargetDescriptor<TFamilyId, TTargetId> {
|
|
36
|
+
create(): TTargetInstance;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface RuntimeAdapterDescriptor<
|
|
40
|
+
TFamilyId extends string,
|
|
41
|
+
TTargetId extends string,
|
|
42
|
+
TAdapterInstance extends RuntimeAdapterInstance<TFamilyId, TTargetId> = RuntimeAdapterInstance<
|
|
43
|
+
TFamilyId,
|
|
44
|
+
TTargetId
|
|
45
|
+
>,
|
|
46
|
+
> extends AdapterDescriptor<TFamilyId, TTargetId> {
|
|
47
|
+
create(): TAdapterInstance;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface RuntimeDriverDescriptor<
|
|
51
|
+
TFamilyId extends string,
|
|
52
|
+
TTargetId extends string,
|
|
53
|
+
TCreateOptions = void,
|
|
54
|
+
TDriverInstance extends RuntimeDriverInstance<TFamilyId, TTargetId> = RuntimeDriverInstance<
|
|
55
|
+
TFamilyId,
|
|
56
|
+
TTargetId
|
|
57
|
+
>,
|
|
58
|
+
> extends DriverDescriptor<TFamilyId, TTargetId> {
|
|
59
|
+
create(options?: TCreateOptions): TDriverInstance;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface RuntimeExtensionDescriptor<
|
|
63
|
+
TFamilyId extends string,
|
|
64
|
+
TTargetId extends string,
|
|
65
|
+
TExtensionInstance extends RuntimeExtensionInstance<
|
|
66
|
+
TFamilyId,
|
|
67
|
+
TTargetId
|
|
68
|
+
> = RuntimeExtensionInstance<TFamilyId, TTargetId>,
|
|
69
|
+
> extends ExtensionDescriptor<TFamilyId, TTargetId> {
|
|
70
|
+
create(): TExtensionInstance;
|
|
71
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AdapterInstance,
|
|
3
|
+
DriverInstance,
|
|
4
|
+
ExtensionInstance,
|
|
5
|
+
FamilyInstance,
|
|
6
|
+
TargetInstance,
|
|
7
|
+
} from './framework-components';
|
|
8
|
+
|
|
9
|
+
export interface RuntimeFamilyInstance<TFamilyId extends string>
|
|
10
|
+
extends FamilyInstance<TFamilyId> {}
|
|
11
|
+
|
|
12
|
+
export interface RuntimeTargetInstance<TFamilyId extends string, TTargetId extends string>
|
|
13
|
+
extends TargetInstance<TFamilyId, TTargetId> {}
|
|
14
|
+
|
|
15
|
+
export interface RuntimeAdapterInstance<TFamilyId extends string, TTargetId extends string>
|
|
16
|
+
extends AdapterInstance<TFamilyId, TTargetId> {}
|
|
17
|
+
|
|
18
|
+
export interface RuntimeDriverInstance<TFamilyId extends string, TTargetId extends string>
|
|
19
|
+
extends DriverInstance<TFamilyId, TTargetId> {}
|
|
20
|
+
|
|
21
|
+
export interface RuntimeExtensionInstance<TFamilyId extends string, TTargetId extends string>
|
|
22
|
+
extends ExtensionInstance<TFamilyId, TTargetId> {}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RuntimeAdapterDescriptor,
|
|
3
|
+
RuntimeExtensionDescriptor,
|
|
4
|
+
RuntimeFamilyDescriptor,
|
|
5
|
+
RuntimeTargetDescriptor,
|
|
6
|
+
} from './execution-descriptors';
|
|
7
|
+
import { checkContractComponentRequirements } from './framework-components';
|
|
8
|
+
|
|
9
|
+
export function assertRuntimeContractRequirementsSatisfied<
|
|
10
|
+
TFamilyId extends string,
|
|
11
|
+
TTargetId extends string,
|
|
12
|
+
>({
|
|
13
|
+
contract,
|
|
14
|
+
family,
|
|
15
|
+
target,
|
|
16
|
+
adapter,
|
|
17
|
+
extensionPacks,
|
|
18
|
+
}: {
|
|
19
|
+
readonly contract: { readonly target: string; readonly extensionPacks?: Record<string, unknown> };
|
|
20
|
+
readonly family: RuntimeFamilyDescriptor<TFamilyId>;
|
|
21
|
+
readonly target: RuntimeTargetDescriptor<TFamilyId, TTargetId>;
|
|
22
|
+
readonly adapter: RuntimeAdapterDescriptor<TFamilyId, TTargetId>;
|
|
23
|
+
readonly extensionPacks: readonly RuntimeExtensionDescriptor<TFamilyId, TTargetId>[];
|
|
24
|
+
}): void {
|
|
25
|
+
const providedComponentIds = new Set<string>([family.id, target.id, adapter.id]);
|
|
26
|
+
for (const extension of extensionPacks) {
|
|
27
|
+
providedComponentIds.add(extension.id);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const result = checkContractComponentRequirements({
|
|
31
|
+
contract,
|
|
32
|
+
expectedTargetId: target.targetId,
|
|
33
|
+
providedComponentIds,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (result.targetMismatch) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Contract target '${result.targetMismatch.actual}' does not match runtime target descriptor '${result.targetMismatch.expected}'.`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const packId of result.missingExtensionPackIds) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Contract requires extension pack '${packId}', but runtime descriptors do not provide a matching component.`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RuntimeAdapterDescriptor,
|
|
3
|
+
RuntimeDriverDescriptor,
|
|
4
|
+
RuntimeExtensionDescriptor,
|
|
5
|
+
RuntimeTargetDescriptor,
|
|
6
|
+
} from './execution-descriptors';
|
|
7
|
+
import type {
|
|
8
|
+
RuntimeAdapterInstance,
|
|
9
|
+
RuntimeDriverInstance,
|
|
10
|
+
RuntimeExtensionInstance,
|
|
11
|
+
RuntimeTargetInstance,
|
|
12
|
+
} from './execution-instances';
|
|
13
|
+
|
|
14
|
+
export interface ExecutionStack<
|
|
15
|
+
TFamilyId extends string,
|
|
16
|
+
TTargetId extends string,
|
|
17
|
+
TAdapterInstance extends RuntimeAdapterInstance<TFamilyId, TTargetId> = RuntimeAdapterInstance<
|
|
18
|
+
TFamilyId,
|
|
19
|
+
TTargetId
|
|
20
|
+
>,
|
|
21
|
+
TDriverInstance extends RuntimeDriverInstance<TFamilyId, TTargetId> = RuntimeDriverInstance<
|
|
22
|
+
TFamilyId,
|
|
23
|
+
TTargetId
|
|
24
|
+
>,
|
|
25
|
+
TExtensionInstance extends RuntimeExtensionInstance<
|
|
26
|
+
TFamilyId,
|
|
27
|
+
TTargetId
|
|
28
|
+
> = RuntimeExtensionInstance<TFamilyId, TTargetId>,
|
|
29
|
+
> {
|
|
30
|
+
readonly target: RuntimeTargetDescriptor<TFamilyId, TTargetId>;
|
|
31
|
+
readonly adapter: RuntimeAdapterDescriptor<TFamilyId, TTargetId, TAdapterInstance>;
|
|
32
|
+
readonly driver:
|
|
33
|
+
| RuntimeDriverDescriptor<TFamilyId, TTargetId, unknown, TDriverInstance>
|
|
34
|
+
| undefined;
|
|
35
|
+
readonly extensionPacks: readonly RuntimeExtensionDescriptor<
|
|
36
|
+
TFamilyId,
|
|
37
|
+
TTargetId,
|
|
38
|
+
TExtensionInstance
|
|
39
|
+
>[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ExecutionStackInstance<
|
|
43
|
+
TFamilyId extends string,
|
|
44
|
+
TTargetId extends string,
|
|
45
|
+
TAdapterInstance extends RuntimeAdapterInstance<TFamilyId, TTargetId> = RuntimeAdapterInstance<
|
|
46
|
+
TFamilyId,
|
|
47
|
+
TTargetId
|
|
48
|
+
>,
|
|
49
|
+
TDriverInstance extends RuntimeDriverInstance<TFamilyId, TTargetId> = RuntimeDriverInstance<
|
|
50
|
+
TFamilyId,
|
|
51
|
+
TTargetId
|
|
52
|
+
>,
|
|
53
|
+
TExtensionInstance extends RuntimeExtensionInstance<
|
|
54
|
+
TFamilyId,
|
|
55
|
+
TTargetId
|
|
56
|
+
> = RuntimeExtensionInstance<TFamilyId, TTargetId>,
|
|
57
|
+
> {
|
|
58
|
+
readonly stack: ExecutionStack<
|
|
59
|
+
TFamilyId,
|
|
60
|
+
TTargetId,
|
|
61
|
+
TAdapterInstance,
|
|
62
|
+
TDriverInstance,
|
|
63
|
+
TExtensionInstance
|
|
64
|
+
>;
|
|
65
|
+
readonly target: RuntimeTargetInstance<TFamilyId, TTargetId>;
|
|
66
|
+
readonly adapter: TAdapterInstance;
|
|
67
|
+
readonly driver: TDriverInstance | undefined;
|
|
68
|
+
readonly extensionPacks: readonly TExtensionInstance[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function createExecutionStack<
|
|
72
|
+
TFamilyId extends string,
|
|
73
|
+
TTargetId extends string,
|
|
74
|
+
TTargetInstance extends RuntimeTargetInstance<TFamilyId, TTargetId>,
|
|
75
|
+
TTargetDescriptor extends RuntimeTargetDescriptor<TFamilyId, TTargetId, TTargetInstance>,
|
|
76
|
+
TAdapterInstance extends RuntimeAdapterInstance<TFamilyId, TTargetId>,
|
|
77
|
+
TAdapterDescriptor extends RuntimeAdapterDescriptor<TFamilyId, TTargetId, TAdapterInstance>,
|
|
78
|
+
TDriverInstance extends RuntimeDriverInstance<TFamilyId, TTargetId> = RuntimeDriverInstance<
|
|
79
|
+
TFamilyId,
|
|
80
|
+
TTargetId
|
|
81
|
+
>,
|
|
82
|
+
TDriverDescriptor extends
|
|
83
|
+
| RuntimeDriverDescriptor<TFamilyId, TTargetId, unknown, TDriverInstance>
|
|
84
|
+
| undefined = undefined,
|
|
85
|
+
TExtensionInstance extends RuntimeExtensionInstance<
|
|
86
|
+
TFamilyId,
|
|
87
|
+
TTargetId
|
|
88
|
+
> = RuntimeExtensionInstance<TFamilyId, TTargetId>,
|
|
89
|
+
TExtensionDescriptor extends RuntimeExtensionDescriptor<
|
|
90
|
+
TFamilyId,
|
|
91
|
+
TTargetId,
|
|
92
|
+
TExtensionInstance
|
|
93
|
+
> = never,
|
|
94
|
+
>(input: {
|
|
95
|
+
readonly target: TTargetDescriptor;
|
|
96
|
+
readonly adapter: TAdapterDescriptor;
|
|
97
|
+
readonly driver?: TDriverDescriptor | undefined;
|
|
98
|
+
readonly extensionPacks?: readonly TExtensionDescriptor[] | undefined;
|
|
99
|
+
}): ExecutionStack<TFamilyId, TTargetId, TAdapterInstance, TDriverInstance, TExtensionInstance> & {
|
|
100
|
+
readonly target: TTargetDescriptor;
|
|
101
|
+
readonly adapter: TAdapterDescriptor;
|
|
102
|
+
readonly driver: TDriverDescriptor | undefined;
|
|
103
|
+
readonly extensionPacks: readonly TExtensionDescriptor[];
|
|
104
|
+
} {
|
|
105
|
+
return {
|
|
106
|
+
target: input.target,
|
|
107
|
+
adapter: input.adapter,
|
|
108
|
+
driver: input.driver,
|
|
109
|
+
extensionPacks: input.extensionPacks ?? [],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function instantiateExecutionStack<
|
|
114
|
+
TFamilyId extends string,
|
|
115
|
+
TTargetId extends string,
|
|
116
|
+
TAdapterInstance extends RuntimeAdapterInstance<TFamilyId, TTargetId>,
|
|
117
|
+
TDriverInstance extends RuntimeDriverInstance<TFamilyId, TTargetId>,
|
|
118
|
+
TExtensionInstance extends RuntimeExtensionInstance<TFamilyId, TTargetId>,
|
|
119
|
+
>(
|
|
120
|
+
stack: ExecutionStack<
|
|
121
|
+
TFamilyId,
|
|
122
|
+
TTargetId,
|
|
123
|
+
TAdapterInstance,
|
|
124
|
+
TDriverInstance,
|
|
125
|
+
TExtensionInstance
|
|
126
|
+
>,
|
|
127
|
+
): ExecutionStackInstance<
|
|
128
|
+
TFamilyId,
|
|
129
|
+
TTargetId,
|
|
130
|
+
TAdapterInstance,
|
|
131
|
+
TDriverInstance,
|
|
132
|
+
TExtensionInstance
|
|
133
|
+
> {
|
|
134
|
+
const driver = stack.driver ? stack.driver.create() : undefined;
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
stack,
|
|
138
|
+
target: stack.target.create(),
|
|
139
|
+
adapter: stack.adapter.create(),
|
|
140
|
+
driver,
|
|
141
|
+
extensionPacks: stack.extensionPacks.map((descriptor) => descriptor.create()),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
AuthoringArgRef,
|
|
3
|
+
AuthoringArgumentDescriptor,
|
|
4
|
+
AuthoringColumnDefaultTemplate,
|
|
5
|
+
AuthoringContributions,
|
|
6
|
+
AuthoringFieldNamespace,
|
|
7
|
+
AuthoringFieldPresetDescriptor,
|
|
8
|
+
AuthoringFieldPresetOutput,
|
|
9
|
+
AuthoringStorageTypeTemplate,
|
|
10
|
+
AuthoringTemplateValue,
|
|
11
|
+
AuthoringTypeConstructorDescriptor,
|
|
12
|
+
AuthoringTypeNamespace,
|
|
13
|
+
} from '../framework-authoring';
|
|
14
|
+
export {
|
|
15
|
+
instantiateAuthoringFieldPreset,
|
|
16
|
+
instantiateAuthoringTypeConstructor,
|
|
17
|
+
isAuthoringArgRef,
|
|
18
|
+
isAuthoringFieldPresetDescriptor,
|
|
19
|
+
isAuthoringTypeConstructorDescriptor,
|
|
20
|
+
resolveAuthoringTemplateValue,
|
|
21
|
+
validateAuthoringHelperArguments,
|
|
22
|
+
} from '../framework-authoring';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
AdapterDescriptor,
|
|
3
|
+
AdapterInstance,
|
|
4
|
+
AdapterPackRef,
|
|
5
|
+
ComponentDescriptor,
|
|
6
|
+
ComponentMetadata,
|
|
7
|
+
ContractComponentRequirementsCheckInput,
|
|
8
|
+
ContractComponentRequirementsCheckResult,
|
|
9
|
+
DriverDescriptor,
|
|
10
|
+
DriverInstance,
|
|
11
|
+
DriverPackRef,
|
|
12
|
+
ExtensionDescriptor,
|
|
13
|
+
ExtensionInstance,
|
|
14
|
+
ExtensionPackRef,
|
|
15
|
+
FamilyDescriptor,
|
|
16
|
+
FamilyInstance,
|
|
17
|
+
FamilyPackRef,
|
|
18
|
+
PackRefBase,
|
|
19
|
+
TargetBoundComponentDescriptor,
|
|
20
|
+
TargetDescriptor,
|
|
21
|
+
TargetInstance,
|
|
22
|
+
TargetPackRef,
|
|
23
|
+
} from '../framework-components';
|
|
24
|
+
export { checkContractComponentRequirements } from '../framework-components';
|