@ankhorage/contracts 7.0.0 → 7.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/appManifest/bindings.d.ts +4 -0
- package/dist/appManifest/bindings.d.ts.map +1 -0
- package/dist/appManifest/bindings.js +96 -0
- package/dist/appManifest/bindings.js.map +1 -0
- package/dist/appManifest/dataSources.d.ts +2 -0
- package/dist/appManifest/dataSources.d.ts.map +1 -0
- package/dist/appManifest/dataSources.js +133 -0
- package/dist/appManifest/dataSources.js.map +1 -0
- package/dist/appManifest/generatedApis.d.ts +2 -0
- package/dist/appManifest/generatedApis.d.ts.map +1 -0
- package/dist/appManifest/generatedApis.js +87 -0
- package/dist/appManifest/generatedApis.js.map +1 -0
- package/dist/appManifest/infra.d.ts +2 -0
- package/dist/appManifest/infra.d.ts.map +1 -0
- package/dist/appManifest/infra.js +136 -0
- package/dist/appManifest/infra.js.map +1 -0
- package/dist/appManifest/screens.d.ts +6 -0
- package/dist/appManifest/screens.d.ts.map +1 -0
- package/dist/appManifest/screens.js +119 -0
- package/dist/appManifest/screens.js.map +1 -0
- package/dist/appManifest/shared.d.ts +8 -0
- package/dist/appManifest/shared.d.ts.map +1 -0
- package/dist/appManifest/shared.js +31 -0
- package/dist/appManifest/shared.js.map +1 -0
- package/dist/appManifest.d.ts +19 -0
- package/dist/appManifest.d.ts.map +1 -0
- package/dist/appManifest.js +64 -0
- package/dist/appManifest.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/theme.d.ts +44 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +2 -0
- package/dist/theme.js.map +1 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/appManifest/bindings.ts +135 -0
- package/src/appManifest/dataSources.ts +175 -0
- package/src/appManifest/generatedApis.ts +122 -0
- package/src/appManifest/infra.ts +199 -0
- package/src/appManifest/screens.ts +171 -0
- package/src/appManifest/shared.ts +40 -0
- package/src/appManifest.test.ts +185 -0
- package/src/appManifest.ts +86 -0
- package/src/contracts.test.ts +40 -0
- package/src/index.ts +2 -0
- package/src/theme.ts +50 -0
- package/src/types.ts +5 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { isManifestValue, isOptionalString, isRecord } from './shared';
|
|
2
|
+
|
|
3
|
+
export function isComponentDataBindingRegistry(value: unknown): boolean {
|
|
4
|
+
return isRecord(value) && Object.values(value).every(isComponentDataBinding);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function isBindingValueSource(value: unknown): boolean {
|
|
8
|
+
return (
|
|
9
|
+
isRecord(value) &&
|
|
10
|
+
typeof value.kind === 'string' &&
|
|
11
|
+
['context', 'event', 'literal', 'operation', 'state'].includes(value.kind) &&
|
|
12
|
+
(value.kind === 'literal'
|
|
13
|
+
? isManifestValue(value.value)
|
|
14
|
+
: value.kind === 'operation'
|
|
15
|
+
? isBindingOperationRef(value.operation) && isOptionalString(value.path)
|
|
16
|
+
: typeof value.path === 'string')
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isScreenDataLoaderDefinition(value: unknown): boolean {
|
|
21
|
+
return (
|
|
22
|
+
isRecord(value) &&
|
|
23
|
+
value.kind === 'operation' &&
|
|
24
|
+
isOptionalString(value.id) &&
|
|
25
|
+
isBindingOperationRef(value.operation) &&
|
|
26
|
+
(value.input === undefined || isBindingInputMap(value.input))
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isComponentDataBinding(value: unknown): boolean {
|
|
31
|
+
return (
|
|
32
|
+
isRecord(value) &&
|
|
33
|
+
typeof value.componentId === 'string' &&
|
|
34
|
+
isOptionalString(value.componentType) &&
|
|
35
|
+
(value.props === undefined ||
|
|
36
|
+
(isRecord(value.props) && Object.values(value.props).every(isPropBinding))) &&
|
|
37
|
+
(value.events === undefined ||
|
|
38
|
+
(isRecord(value.events) &&
|
|
39
|
+
Object.values(value.events).every(
|
|
40
|
+
(bindings) => Array.isArray(bindings) && bindings.every(isEventBinding),
|
|
41
|
+
)))
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isPropBinding(value: unknown): boolean {
|
|
46
|
+
return (
|
|
47
|
+
isRecord(value) &&
|
|
48
|
+
isBindingValueSource(value.source) &&
|
|
49
|
+
(value.fallback === undefined || isBindingFallback(value.fallback)) &&
|
|
50
|
+
(value.loading === undefined || isBindingLifecycleBehavior(value.loading)) &&
|
|
51
|
+
(value.error === undefined || isBindingLifecycleBehavior(value.error)) &&
|
|
52
|
+
(value.empty === undefined || isBindingLifecycleBehavior(value.empty)) &&
|
|
53
|
+
isOptionalBindingTransforms(value.transforms)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function isEventBinding(value: unknown): boolean {
|
|
58
|
+
return (
|
|
59
|
+
isRecord(value) &&
|
|
60
|
+
isEventBindingTarget(value.target) &&
|
|
61
|
+
(value.input === undefined || isBindingInputMap(value.input)) &&
|
|
62
|
+
(value.when === undefined || isBindingCondition(value.when))
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isEventBindingTarget(value: unknown): boolean {
|
|
67
|
+
return (
|
|
68
|
+
isRecord(value) &&
|
|
69
|
+
((value.kind === 'action' && typeof value.type === 'string') ||
|
|
70
|
+
(value.kind === 'operation' && isBindingOperationRef(value.operation)))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isBindingCondition(value: unknown): boolean {
|
|
75
|
+
return (
|
|
76
|
+
isRecord(value) &&
|
|
77
|
+
isBindingValueSource(value.source) &&
|
|
78
|
+
['eq', 'exists', 'neq', 'notExists'].includes(String(value.operator)) &&
|
|
79
|
+
(value.value === undefined || isManifestValue(value.value))
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function isBindingOperationRef(value: unknown): boolean {
|
|
84
|
+
return (
|
|
85
|
+
isRecord(value) &&
|
|
86
|
+
typeof value.dataSourceId === 'string' &&
|
|
87
|
+
typeof value.operationId === 'string' &&
|
|
88
|
+
isOptionalString(value.endpointId)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function isBindingFallback(value: unknown): boolean {
|
|
93
|
+
return (
|
|
94
|
+
isRecord(value) &&
|
|
95
|
+
(value.value === undefined || isManifestValue(value.value)) &&
|
|
96
|
+
(value.source === undefined || isBindingValueSource(value.source))
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function isBindingLifecycleBehavior(value: unknown): boolean {
|
|
101
|
+
return (
|
|
102
|
+
isRecord(value) &&
|
|
103
|
+
typeof value.state === 'string' &&
|
|
104
|
+
['empty', 'error', 'loading'].includes(value.state) &&
|
|
105
|
+
(value.fallback === undefined || isBindingFallback(value.fallback)) &&
|
|
106
|
+
isOptionalString(value.message)
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function isOptionalBindingTransforms(value: unknown): boolean {
|
|
111
|
+
return (
|
|
112
|
+
value === undefined ||
|
|
113
|
+
(Array.isArray(value) &&
|
|
114
|
+
value.every((transform) => ['lowercase', 'trim', 'uppercase'].includes(String(transform))))
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isBindingInputMap(value: unknown): boolean {
|
|
119
|
+
return isRecord(value) && Object.values(value).every(isBindingInputValue);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function isBindingInputValue(value: unknown): boolean {
|
|
123
|
+
return (
|
|
124
|
+
isRecord(value) &&
|
|
125
|
+
typeof value.kind === 'string' &&
|
|
126
|
+
((value.kind === 'array' &&
|
|
127
|
+
Array.isArray(value.items) &&
|
|
128
|
+
value.items.every(isBindingInputValue)) ||
|
|
129
|
+
(value.kind === 'literal' && isManifestValue(value.value)) ||
|
|
130
|
+
(value.kind === 'object' && isBindingInputMap(value.fields)) ||
|
|
131
|
+
(value.kind === 'source' &&
|
|
132
|
+
isBindingValueSource(value.source) &&
|
|
133
|
+
isOptionalBindingTransforms(value.transforms)))
|
|
134
|
+
);
|
|
135
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { isManifestValue, isOptionalBoolean, isOptionalString, isRecord } from './shared';
|
|
2
|
+
|
|
3
|
+
export function isDataSourceRegistry(value: unknown): boolean {
|
|
4
|
+
return isRecord(value) && Object.values(value).every(isDataSourceConfig);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function isDataSourceConfig(value: unknown): boolean {
|
|
8
|
+
if (!hasBaseDataSourceShape(value)) return false;
|
|
9
|
+
if (value.kind === 'database') return isDatabaseDataSource(value);
|
|
10
|
+
if (value.origin === 'generated') return isGeneratedDataSource(value);
|
|
11
|
+
if (value.origin !== 'external') return false;
|
|
12
|
+
return isExternalDataSource(value);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function hasBaseDataSourceShape(value: unknown): value is Record<string, unknown> {
|
|
16
|
+
return (
|
|
17
|
+
isRecord(value) &&
|
|
18
|
+
typeof value.id === 'string' &&
|
|
19
|
+
(value.kind === 'api' || value.kind === 'database') &&
|
|
20
|
+
isOptionalString(value.name) &&
|
|
21
|
+
isOptionalString(value.description) &&
|
|
22
|
+
(value.credential === undefined || isCredentialRef(value.credential)) &&
|
|
23
|
+
isDataEndpointRegistry(value.endpoints) &&
|
|
24
|
+
(value.schemas === undefined || isRecord(value.schemas)) &&
|
|
25
|
+
(value.metadata === undefined || isManifestValue(value.metadata))
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isDatabaseDataSource(value: Record<string, unknown>): boolean {
|
|
30
|
+
return (
|
|
31
|
+
isRecord(value.adapter) && value.adapter.kind === 'database' && isAdapterRef(value.adapter)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isGeneratedDataSource(value: Record<string, unknown>): boolean {
|
|
36
|
+
return (
|
|
37
|
+
value.protocol === 'rest' &&
|
|
38
|
+
typeof value.generatedApiId === 'string' &&
|
|
39
|
+
isRecord(value.adapter) &&
|
|
40
|
+
value.adapter.kind === 'database' &&
|
|
41
|
+
isAdapterRef(value.adapter)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isExternalDataSource(value: Record<string, unknown>): boolean {
|
|
46
|
+
if (value.protocol === 'rest') {
|
|
47
|
+
return (
|
|
48
|
+
typeof value.baseUrl === 'string' &&
|
|
49
|
+
(value.openApi === undefined || isOpenApiDocumentRef(value.openApi))
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (value.protocol === 'graphql') {
|
|
54
|
+
return (
|
|
55
|
+
typeof value.endpointUrl === 'string' &&
|
|
56
|
+
(value.introspection === undefined || isGraphQlIntrospection(value.introspection))
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isOpenApiDocumentRef(value: unknown): boolean {
|
|
64
|
+
return (
|
|
65
|
+
isRecord(value) &&
|
|
66
|
+
isOptionalString(value.url) &&
|
|
67
|
+
isOptionalString(value.documentId) &&
|
|
68
|
+
isOptionalString(value.version)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isGraphQlIntrospection(value: unknown): boolean {
|
|
73
|
+
return (
|
|
74
|
+
isRecord(value) && typeof value.enabled === 'boolean' && isOptionalString(value.schemaVersion)
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isDataEndpointRegistry(value: unknown): boolean {
|
|
79
|
+
return isRecord(value) && Object.values(value).every(isDataEndpointConfig);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function isDataEndpointConfig(value: unknown): boolean {
|
|
83
|
+
return (
|
|
84
|
+
isRecord(value) &&
|
|
85
|
+
typeof value.id === 'string' &&
|
|
86
|
+
typeof value.kind === 'string' &&
|
|
87
|
+
isOptionalString(value.name) &&
|
|
88
|
+
isOptionalString(value.description) &&
|
|
89
|
+
isOptionalString(value.baseUrl) &&
|
|
90
|
+
isOptionalString(value.path) &&
|
|
91
|
+
(value.credential === undefined || isCredentialRef(value.credential)) &&
|
|
92
|
+
isRecord(value.operations) &&
|
|
93
|
+
Object.values(value.operations).every(isDataOperationConfig) &&
|
|
94
|
+
(value.metadata === undefined || isManifestValue(value.metadata))
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function isDataOperationConfig(value: unknown): boolean {
|
|
99
|
+
return (
|
|
100
|
+
isRecord(value) &&
|
|
101
|
+
typeof value.id === 'string' &&
|
|
102
|
+
isOptionalString(value.endpointId) &&
|
|
103
|
+
isOptionalString(value.name) &&
|
|
104
|
+
isOptionalString(value.description) &&
|
|
105
|
+
typeof value.protocol === 'string' &&
|
|
106
|
+
typeof value.intent === 'string' &&
|
|
107
|
+
['action', 'create', 'delete', 'read', 'update'].includes(value.intent) &&
|
|
108
|
+
isOptionalString(value.method) &&
|
|
109
|
+
isOptionalString(value.path) &&
|
|
110
|
+
(value.request === undefined || isDataOperationRequest(value.request)) &&
|
|
111
|
+
(value.response === undefined || isDataOperationResponse(value.response)) &&
|
|
112
|
+
(value.pagination === undefined || isRecord(value.pagination)) &&
|
|
113
|
+
(value.credential === undefined || isCredentialRef(value.credential)) &&
|
|
114
|
+
(value.metadata === undefined || isManifestValue(value.metadata))
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function isDataOperationRequest(value: unknown): boolean {
|
|
119
|
+
return (
|
|
120
|
+
isRecord(value) &&
|
|
121
|
+
isDataSchemaSlot(value) &&
|
|
122
|
+
(value.parameters === undefined ||
|
|
123
|
+
(Array.isArray(value.parameters) && value.parameters.every(isDataOperationParameter)))
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isDataOperationParameter(value: unknown): boolean {
|
|
128
|
+
return (
|
|
129
|
+
isRecord(value) &&
|
|
130
|
+
isDataSchemaSlot(value) &&
|
|
131
|
+
typeof value.name === 'string' &&
|
|
132
|
+
typeof value.location === 'string' &&
|
|
133
|
+
['body', 'cookie', 'header', 'path', 'query'].includes(value.location) &&
|
|
134
|
+
isOptionalBoolean(value.required) &&
|
|
135
|
+
isOptionalString(value.description) &&
|
|
136
|
+
(value.default === undefined || isManifestValue(value.default))
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function isDataOperationResponse(value: unknown): boolean {
|
|
141
|
+
return (
|
|
142
|
+
isRecord(value) &&
|
|
143
|
+
isDataSchemaSlot(value) &&
|
|
144
|
+
(value.status === undefined ||
|
|
145
|
+
typeof value.status === 'string' ||
|
|
146
|
+
typeof value.status === 'number') &&
|
|
147
|
+
isOptionalString(value.contentType) &&
|
|
148
|
+
isOptionalString(value.description)
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function isDataSchemaSlot(value: unknown): boolean {
|
|
153
|
+
return isRecord(value) && (value.schema === undefined || isRecord(value.schema));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function isCredentialRef(value: unknown): boolean {
|
|
157
|
+
return (
|
|
158
|
+
isRecord(value) &&
|
|
159
|
+
typeof value.id === 'string' &&
|
|
160
|
+
typeof value.kind === 'string' &&
|
|
161
|
+
isOptionalString(value.label) &&
|
|
162
|
+
isOptionalString(value.scope)
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function isAdapterRef(value: unknown): boolean {
|
|
167
|
+
return (
|
|
168
|
+
isRecord(value) &&
|
|
169
|
+
typeof value.id === 'string' &&
|
|
170
|
+
typeof value.kind === 'string' &&
|
|
171
|
+
isOptionalString(value.packageName) &&
|
|
172
|
+
isOptionalString(value.exportName) &&
|
|
173
|
+
(value.config === undefined || isManifestValue(value.config))
|
|
174
|
+
);
|
|
175
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isManifestValue,
|
|
3
|
+
isOptionalBoolean,
|
|
4
|
+
isOptionalString,
|
|
5
|
+
isRecord,
|
|
6
|
+
isStringArray,
|
|
7
|
+
} from './shared';
|
|
8
|
+
|
|
9
|
+
export function isGeneratedApiRegistry(value: unknown): boolean {
|
|
10
|
+
return isRecord(value) && Object.values(value).every(isGeneratedApiDefinition);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function isGeneratedApiDefinition(value: unknown): boolean {
|
|
14
|
+
return (
|
|
15
|
+
isRecord(value) &&
|
|
16
|
+
typeof value.id === 'string' &&
|
|
17
|
+
value.protocol === 'rest' &&
|
|
18
|
+
isOptionalString(value.name) &&
|
|
19
|
+
isOptionalString(value.description) &&
|
|
20
|
+
typeof value.basePath === 'string' &&
|
|
21
|
+
isDatabaseAdapterRef(value.database) &&
|
|
22
|
+
Array.isArray(value.resources) &&
|
|
23
|
+
value.resources.every(isGeneratedApiResourceDefinition) &&
|
|
24
|
+
(value.auth === undefined || isGeneratedApiAuthRequirement(value.auth)) &&
|
|
25
|
+
(value.metadata === undefined || isManifestValue(value.metadata))
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isDatabaseAdapterRef(value: unknown): boolean {
|
|
30
|
+
return isRecord(value) && value.kind === 'database' && isAdapterRef(value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isGeneratedApiAuthRequirement(value: unknown): boolean {
|
|
34
|
+
return (
|
|
35
|
+
isRecord(value) &&
|
|
36
|
+
isOptionalBoolean(value.required) &&
|
|
37
|
+
(value.roles === undefined || isStringArray(value.roles)) &&
|
|
38
|
+
(value.permissions === undefined || isStringArray(value.permissions)) &&
|
|
39
|
+
isOptionalString(value.policy) &&
|
|
40
|
+
(value.metadata === undefined || isManifestValue(value.metadata))
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isGeneratedApiResourceDefinition(value: unknown): boolean {
|
|
45
|
+
return (
|
|
46
|
+
isRecord(value) &&
|
|
47
|
+
typeof value.id === 'string' &&
|
|
48
|
+
isOptionalString(value.name) &&
|
|
49
|
+
isOptionalString(value.description) &&
|
|
50
|
+
typeof value.path === 'string' &&
|
|
51
|
+
isDbCollectionDefinition(value.collection) &&
|
|
52
|
+
Array.isArray(value.operations) &&
|
|
53
|
+
value.operations.every(isGeneratedApiCrudOperation) &&
|
|
54
|
+
(value.seed === undefined || isSeedRecords(value.seed)) &&
|
|
55
|
+
(value.policies === undefined ||
|
|
56
|
+
(Array.isArray(value.policies) && value.policies.every(isGeneratedApiPolicyRef))) &&
|
|
57
|
+
(value.metadata === undefined || isManifestValue(value.metadata))
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isSeedRecords(value: unknown): boolean {
|
|
62
|
+
return (
|
|
63
|
+
Array.isArray(value) &&
|
|
64
|
+
value.every((record) => isRecord(record) && Object.values(record).every(isManifestValue))
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isGeneratedApiCrudOperation(value: unknown): boolean {
|
|
69
|
+
return ['create', 'delete', 'list', 'read', 'update'].includes(String(value));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isGeneratedApiPolicyRef(value: unknown): boolean {
|
|
73
|
+
return (
|
|
74
|
+
isRecord(value) &&
|
|
75
|
+
typeof value.id === 'string' &&
|
|
76
|
+
(value.operation === undefined || isGeneratedApiCrudOperation(value.operation))
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isDbCollectionDefinition(value: unknown): boolean {
|
|
81
|
+
return (
|
|
82
|
+
isRecord(value) &&
|
|
83
|
+
typeof value.name === 'string' &&
|
|
84
|
+
isOptionalString(value.schema) &&
|
|
85
|
+
Array.isArray(value.fields) &&
|
|
86
|
+
value.fields.every(isDbFieldDefinition) &&
|
|
87
|
+
isOptionalString(value.primaryKey)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function isDbFieldDefinition(value: unknown): boolean {
|
|
92
|
+
return (
|
|
93
|
+
isRecord(value) &&
|
|
94
|
+
typeof value.name === 'string' &&
|
|
95
|
+
typeof value.type === 'string' &&
|
|
96
|
+
['text', 'number', 'boolean', 'datetime', 'json', 'uuid'].includes(value.type) &&
|
|
97
|
+
isOptionalBoolean(value.required) &&
|
|
98
|
+
isOptionalBoolean(value.unique) &&
|
|
99
|
+
isDbDefaultValue(value.defaultValue)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isDbDefaultValue(value: unknown): boolean {
|
|
104
|
+
return (
|
|
105
|
+
value === undefined ||
|
|
106
|
+
value === null ||
|
|
107
|
+
typeof value === 'boolean' ||
|
|
108
|
+
typeof value === 'number' ||
|
|
109
|
+
typeof value === 'string'
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function isAdapterRef(value: unknown): boolean {
|
|
114
|
+
return (
|
|
115
|
+
isRecord(value) &&
|
|
116
|
+
typeof value.id === 'string' &&
|
|
117
|
+
typeof value.kind === 'string' &&
|
|
118
|
+
isOptionalString(value.packageName) &&
|
|
119
|
+
isOptionalString(value.exportName) &&
|
|
120
|
+
(value.config === undefined || isManifestValue(value.config))
|
|
121
|
+
);
|
|
122
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { AUTH_OAUTH_PROVIDER_IDS } from '../auth';
|
|
2
|
+
import {
|
|
3
|
+
AUTH_PROFILE_CREATE_STRATEGIES,
|
|
4
|
+
AUTH_PROFILE_PRIMARY_KEY_STRATEGIES,
|
|
5
|
+
AUTH_PROFILE_UPDATE_STRATEGIES,
|
|
6
|
+
AUTH_SCOPES,
|
|
7
|
+
AUTH_SIGN_IN_IDENTIFIERS,
|
|
8
|
+
AUTH_SIGN_UP_POLICIES,
|
|
9
|
+
AUTHZ_ENGINES,
|
|
10
|
+
AUTHZ_KINDS,
|
|
11
|
+
DATABASE_TIERS,
|
|
12
|
+
STATE_PERSISTENCE_MODES,
|
|
13
|
+
STORAGE_PROVIDERS,
|
|
14
|
+
} from '../types';
|
|
15
|
+
import {
|
|
16
|
+
isOptionalBoolean,
|
|
17
|
+
isOptionalString,
|
|
18
|
+
isRecord,
|
|
19
|
+
isStringArray,
|
|
20
|
+
isStringRecord,
|
|
21
|
+
} from './shared';
|
|
22
|
+
|
|
23
|
+
const AUTH_OAUTH_PROVIDER_SET = new Set<string>(AUTH_OAUTH_PROVIDER_IDS);
|
|
24
|
+
const AUTH_PROFILE_CREATE_STRATEGY_SET = new Set<string>(AUTH_PROFILE_CREATE_STRATEGIES);
|
|
25
|
+
const AUTH_PROFILE_PRIMARY_KEY_STRATEGY_SET = new Set<string>(AUTH_PROFILE_PRIMARY_KEY_STRATEGIES);
|
|
26
|
+
const AUTH_PROFILE_UPDATE_STRATEGY_SET = new Set<string>(AUTH_PROFILE_UPDATE_STRATEGIES);
|
|
27
|
+
const AUTH_SCOPE_SET = new Set<string>(AUTH_SCOPES);
|
|
28
|
+
const AUTH_SIGN_IN_IDENTIFIER_SET = new Set<string>(AUTH_SIGN_IN_IDENTIFIERS);
|
|
29
|
+
const AUTH_SIGN_UP_POLICY_SET = new Set<string>(AUTH_SIGN_UP_POLICIES);
|
|
30
|
+
const AUTHZ_ENGINE_SET = new Set<string>(AUTHZ_ENGINES);
|
|
31
|
+
const AUTHZ_KIND_SET = new Set<string>(AUTHZ_KINDS);
|
|
32
|
+
const DATABASE_TIER_SET = new Set<string>(DATABASE_TIERS);
|
|
33
|
+
const STATE_PERSISTENCE_MODE_SET = new Set<string>(STATE_PERSISTENCE_MODES);
|
|
34
|
+
const STORAGE_PROVIDER_SET = new Set<string>(STORAGE_PROVIDERS);
|
|
35
|
+
|
|
36
|
+
export function isInfraManifest(value: unknown): boolean {
|
|
37
|
+
return (
|
|
38
|
+
isRecord(value) &&
|
|
39
|
+
(value.deployment === undefined || isDeploymentSpec(value.deployment)) &&
|
|
40
|
+
(value.auth === undefined || isAuthSpec(value.auth)) &&
|
|
41
|
+
(value.database === undefined || isDatabaseSpec(value.database)) &&
|
|
42
|
+
(value.storage === undefined || isStorageSpec(value.storage)) &&
|
|
43
|
+
(value.state === undefined || isStateSpec(value.state)) &&
|
|
44
|
+
(value.networking === undefined || isNetworkingSpec(value.networking)) &&
|
|
45
|
+
Array.isArray(value.modules) &&
|
|
46
|
+
value.modules.every((moduleId) => typeof moduleId === 'string') &&
|
|
47
|
+
(value.modulesConfig === undefined || isRecord(value.modulesConfig)) &&
|
|
48
|
+
!('plugins' in value) &&
|
|
49
|
+
!('pluginsConfig' in value)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function isDeploymentSpec(value: unknown): boolean {
|
|
54
|
+
return (
|
|
55
|
+
isRecord(value) && typeof value.target === 'string' && typeof value.monitoring === 'boolean'
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isDatabaseSpec(value: unknown): boolean {
|
|
60
|
+
return (
|
|
61
|
+
isRecord(value) &&
|
|
62
|
+
typeof value.provider === 'string' &&
|
|
63
|
+
typeof value.tier === 'string' &&
|
|
64
|
+
DATABASE_TIER_SET.has(value.tier)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isStorageSpec(value: unknown): boolean {
|
|
69
|
+
return (
|
|
70
|
+
isRecord(value) &&
|
|
71
|
+
typeof value.provider === 'string' &&
|
|
72
|
+
STORAGE_PROVIDER_SET.has(value.provider) &&
|
|
73
|
+
isStringArray(value.buckets)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isStateSpec(value: unknown): boolean {
|
|
78
|
+
return (
|
|
79
|
+
isRecord(value) &&
|
|
80
|
+
typeof value.provider === 'string' &&
|
|
81
|
+
(value.persistence === undefined ||
|
|
82
|
+
(typeof value.persistence === 'string' && STATE_PERSISTENCE_MODE_SET.has(value.persistence)))
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function isNetworkingSpec(value: unknown): boolean {
|
|
87
|
+
return isRecord(value) && isOptionalString(value.domain) && typeof value.cdn === 'boolean';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isAuthSpec(value: unknown): boolean {
|
|
91
|
+
return (
|
|
92
|
+
isRecord(value) &&
|
|
93
|
+
typeof value.scope === 'string' &&
|
|
94
|
+
AUTH_SCOPE_SET.has(value.scope) &&
|
|
95
|
+
typeof value.provider === 'string' &&
|
|
96
|
+
(value.authorization === undefined || isAuthzSpec(value.authorization)) &&
|
|
97
|
+
(value.flow === undefined || isAuthFlow(value.flow)) &&
|
|
98
|
+
(value.signIn === undefined || isAuthSignInSpec(value.signIn)) &&
|
|
99
|
+
(value.signUp === undefined || isAuthSignUpSpec(value.signUp)) &&
|
|
100
|
+
(value.oauth === undefined || isAuthOAuthConfig(value.oauth)) &&
|
|
101
|
+
(value.profile === undefined || isAuthProfileSpec(value.profile))
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function isAuthzSpec(value: unknown): boolean {
|
|
106
|
+
return (
|
|
107
|
+
isRecord(value) &&
|
|
108
|
+
typeof value.kind === 'string' &&
|
|
109
|
+
AUTHZ_KIND_SET.has(value.kind) &&
|
|
110
|
+
typeof value.engine === 'string' &&
|
|
111
|
+
AUTHZ_ENGINE_SET.has(value.engine)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function isAuthFlow(value: unknown): boolean {
|
|
116
|
+
return (
|
|
117
|
+
isRecord(value) &&
|
|
118
|
+
typeof value.signInRoute === 'string' &&
|
|
119
|
+
isOptionalString(value.signUpRoute) &&
|
|
120
|
+
isOptionalString(value.signOutRoute) &&
|
|
121
|
+
isOptionalString(value.forgotPasswordRoute) &&
|
|
122
|
+
isOptionalString(value.otpRoute) &&
|
|
123
|
+
typeof value.postSignInRoute === 'string' &&
|
|
124
|
+
isOptionalString(value.unauthorizedRoute)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function isAuthSignInSpec(value: unknown): boolean {
|
|
129
|
+
return (
|
|
130
|
+
isRecord(value) &&
|
|
131
|
+
Array.isArray(value.identifiers) &&
|
|
132
|
+
value.identifiers.every(
|
|
133
|
+
(identifier) => typeof identifier === 'string' && AUTH_SIGN_IN_IDENTIFIER_SET.has(identifier),
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function isAuthSignUpSpec(value: unknown): boolean {
|
|
139
|
+
return (
|
|
140
|
+
isRecord(value) &&
|
|
141
|
+
isStringArray(value.requiredFields) &&
|
|
142
|
+
(value.optionalFields === undefined || isStringArray(value.optionalFields)) &&
|
|
143
|
+
(value.signUpPolicy === undefined ||
|
|
144
|
+
(typeof value.signUpPolicy === 'string' && AUTH_SIGN_UP_POLICY_SET.has(value.signUpPolicy)))
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isAuthOAuthConfig(value: unknown): boolean {
|
|
149
|
+
return (
|
|
150
|
+
isRecord(value) &&
|
|
151
|
+
typeof value.enabled === 'boolean' &&
|
|
152
|
+
typeof value.callbackRoute === 'string' &&
|
|
153
|
+
Array.isArray(value.providers) &&
|
|
154
|
+
value.providers.every(isAuthOAuthProviderConfig)
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function isAuthOAuthProviderConfig(value: unknown): boolean {
|
|
159
|
+
return (
|
|
160
|
+
isRecord(value) &&
|
|
161
|
+
typeof value.id === 'string' &&
|
|
162
|
+
(AUTH_OAUTH_PROVIDER_SET.has(value.id) || value.id.length > 0) &&
|
|
163
|
+
isOptionalString(value.label) &&
|
|
164
|
+
isOptionalBoolean(value.enabled) &&
|
|
165
|
+
(value.scopes === undefined || isStringArray(value.scopes)) &&
|
|
166
|
+
(value.queryParams === undefined || isStringRecord(value.queryParams)) &&
|
|
167
|
+
(value.icon === undefined || isIconSpec(value.icon)) &&
|
|
168
|
+
(value.credentialsRef === undefined || typeof value.credentialsRef === 'string')
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function isAuthProfileSpec(value: unknown): boolean {
|
|
173
|
+
return (
|
|
174
|
+
isRecord(value) &&
|
|
175
|
+
isStringArray(value.fields) &&
|
|
176
|
+
isOptionalString(value.table) &&
|
|
177
|
+
(value.primaryKey === undefined ||
|
|
178
|
+
(typeof value.primaryKey === 'string' &&
|
|
179
|
+
AUTH_PROFILE_PRIMARY_KEY_STRATEGY_SET.has(value.primaryKey))) &&
|
|
180
|
+
(value.createStrategy === undefined ||
|
|
181
|
+
(typeof value.createStrategy === 'string' &&
|
|
182
|
+
AUTH_PROFILE_CREATE_STRATEGY_SET.has(value.createStrategy))) &&
|
|
183
|
+
(value.updateStrategy === undefined ||
|
|
184
|
+
(typeof value.updateStrategy === 'string' &&
|
|
185
|
+
AUTH_PROFILE_UPDATE_STRATEGY_SET.has(value.updateStrategy)))
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function isIconSpec(value: unknown): boolean {
|
|
190
|
+
return (
|
|
191
|
+
isRecord(value) &&
|
|
192
|
+
typeof value.name === 'string' &&
|
|
193
|
+
isOptionalString(value.provider) &&
|
|
194
|
+
(value.size === undefined ||
|
|
195
|
+
typeof value.size === 'string' ||
|
|
196
|
+
typeof value.size === 'number') &&
|
|
197
|
+
isOptionalString(value.color)
|
|
198
|
+
);
|
|
199
|
+
}
|