@ankhorage/contracts 7.9.0 → 8.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/appManifest/apis.d.ts +3 -0
- package/dist/appManifest/apis.d.ts.map +1 -0
- package/dist/appManifest/apis.js +81 -0
- package/dist/appManifest/apis.js.map +1 -0
- package/dist/appManifest/bindings.js +1 -1
- package/dist/appManifest/bindings.js.map +1 -1
- package/dist/appManifest/data.d.ts +5 -0
- package/dist/appManifest/data.d.ts.map +1 -0
- package/dist/appManifest/data.js +140 -0
- package/dist/appManifest/data.js.map +1 -0
- package/dist/appManifest/dataSources.d.ts.map +1 -1
- package/dist/appManifest/dataSources.js +23 -120
- package/dist/appManifest/dataSources.js.map +1 -1
- package/dist/appManifest/infra.d.ts.map +1 -1
- package/dist/appManifest/infra.js +2 -0
- package/dist/appManifest/infra.js.map +1 -1
- package/dist/appManifest.d.ts.map +1 -1
- package/dist/appManifest.js +4 -6
- package/dist/appManifest.js.map +1 -1
- package/dist/bindings.d.ts +2 -2
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js.map +1 -1
- package/dist/data/apis.d.ts +42 -38
- package/dist/data/apis.d.ts.map +1 -1
- package/dist/data/apis.js +1 -7
- package/dist/data/apis.js.map +1 -1
- package/dist/data/diagnostics.d.ts +3 -2
- package/dist/data/diagnostics.d.ts.map +1 -1
- package/dist/data/diagnostics.js.map +1 -1
- package/dist/data/ids.d.ts +1 -0
- package/dist/data/ids.d.ts.map +1 -1
- package/dist/data/ids.js.map +1 -1
- package/dist/data/sources.d.ts +5 -42
- package/dist/data/sources.d.ts.map +1 -1
- package/dist/data/sources.js.map +1 -1
- package/dist/requirements.d.ts +1 -1
- package/dist/requirements.d.ts.map +1 -1
- package/dist/requirements.js +1 -0
- package/dist/requirements.js.map +1 -1
- package/dist/types.d.ts +2 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/appManifest/apis.ts +98 -0
- package/src/appManifest/bindings.ts +1 -1
- package/src/appManifest/data.ts +179 -0
- package/src/appManifest/dataSources.ts +30 -157
- package/src/appManifest/infra.ts +2 -0
- package/src/appManifest.test.ts +96 -40
- package/src/appManifest.ts +4 -6
- package/src/bindings.test.ts +36 -43
- package/src/bindings.ts +2 -2
- package/src/data/apis.test.ts +55 -45
- package/src/data/apis.ts +49 -46
- package/src/data/data.test.ts +19 -160
- package/src/data/diagnostics.ts +3 -1
- package/src/data/ids.ts +1 -0
- package/src/data/sources.ts +5 -53
- package/src/requirements.test.ts +23 -0
- package/src/requirements.ts +1 -0
- package/src/types.ts +2 -3
- package/dist/appManifest/generatedApis.d.ts +0 -2
- package/dist/appManifest/generatedApis.d.ts.map +0 -1
- package/dist/appManifest/generatedApis.js +0 -87
- package/dist/appManifest/generatedApis.js.map +0 -1
- package/src/appManifest/generatedApis.ts +0 -122
package/src/data/data.test.ts
CHANGED
|
@@ -1,160 +1,13 @@
|
|
|
1
1
|
import { describe, expect, it } from 'bun:test';
|
|
2
2
|
|
|
3
|
-
import type {
|
|
4
|
-
DatabaseDataSourceConfig,
|
|
5
|
-
DataSourceConfig,
|
|
6
|
-
DataSourceDiagnostic,
|
|
7
|
-
ExternalGraphQlApiDataSourceConfig,
|
|
8
|
-
ExternalRestApiDataSourceConfig,
|
|
9
|
-
GeneratedRestApiDataSourceConfig,
|
|
10
|
-
} from './index';
|
|
3
|
+
import type { DatabaseDataSourceConfig, DataSourceConfig, DataSourceDiagnostic } from './index';
|
|
11
4
|
|
|
12
5
|
function assertSerializable<TValue>(value: TValue): void {
|
|
13
6
|
expect(JSON.parse(JSON.stringify(value))).toEqual(value);
|
|
14
7
|
}
|
|
15
8
|
|
|
16
9
|
describe('data source contracts', () => {
|
|
17
|
-
it('
|
|
18
|
-
const source: ExternalRestApiDataSourceConfig = {
|
|
19
|
-
id: 'cms-rest',
|
|
20
|
-
kind: 'api',
|
|
21
|
-
origin: 'external',
|
|
22
|
-
protocol: 'rest',
|
|
23
|
-
name: 'CMS REST API',
|
|
24
|
-
baseUrl: 'https://cms.example.com',
|
|
25
|
-
credential: {
|
|
26
|
-
id: 'cms-api-key',
|
|
27
|
-
kind: 'apiKey',
|
|
28
|
-
label: 'CMS API key',
|
|
29
|
-
},
|
|
30
|
-
endpoints: {
|
|
31
|
-
posts: {
|
|
32
|
-
id: 'posts',
|
|
33
|
-
kind: 'http',
|
|
34
|
-
path: '/posts',
|
|
35
|
-
operations: {
|
|
36
|
-
'posts.list': {
|
|
37
|
-
id: 'posts.list',
|
|
38
|
-
endpointId: 'posts',
|
|
39
|
-
protocol: 'http',
|
|
40
|
-
intent: 'read',
|
|
41
|
-
method: 'GET',
|
|
42
|
-
path: '/posts',
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
assertSerializable(source);
|
|
50
|
-
expect(source.endpoints.posts?.operations['posts.list']?.intent).toBe('read');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('models OpenAPI as optional metadata on an external REST API', () => {
|
|
54
|
-
const source: ExternalRestApiDataSourceConfig = {
|
|
55
|
-
id: 'shop-api',
|
|
56
|
-
kind: 'api',
|
|
57
|
-
origin: 'external',
|
|
58
|
-
protocol: 'rest',
|
|
59
|
-
name: 'Shop API',
|
|
60
|
-
baseUrl: 'https://shop.example.com/api',
|
|
61
|
-
openApi: {
|
|
62
|
-
url: 'https://shop.example.com/openapi.json',
|
|
63
|
-
version: '2026-08-06',
|
|
64
|
-
},
|
|
65
|
-
endpoints: {},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
assertSerializable(source);
|
|
69
|
-
expect(source.openApi?.url).toContain('openapi.json');
|
|
70
|
-
expect(source.kind).toBe('api');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('serializes an external GraphQL API independently of origin', () => {
|
|
74
|
-
const source: ExternalGraphQlApiDataSourceConfig = {
|
|
75
|
-
id: 'content-graphql',
|
|
76
|
-
kind: 'api',
|
|
77
|
-
origin: 'external',
|
|
78
|
-
protocol: 'graphql',
|
|
79
|
-
endpointUrl: 'https://content.example.com/graphql',
|
|
80
|
-
introspection: {
|
|
81
|
-
enabled: true,
|
|
82
|
-
schemaVersion: '2026-08-06',
|
|
83
|
-
},
|
|
84
|
-
endpoints: {
|
|
85
|
-
graphql: {
|
|
86
|
-
id: 'graphql',
|
|
87
|
-
kind: 'graphql',
|
|
88
|
-
operations: {
|
|
89
|
-
PostsQuery: {
|
|
90
|
-
id: 'PostsQuery',
|
|
91
|
-
endpointId: 'graphql',
|
|
92
|
-
protocol: 'graphql',
|
|
93
|
-
intent: 'read',
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
assertSerializable(source);
|
|
101
|
-
expect(source.protocol).toBe('graphql');
|
|
102
|
-
expect(source.endpoints.graphql?.operations.PostsQuery?.intent).toBe('read');
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('serializes a normalized generated REST API projection', () => {
|
|
106
|
-
const source: GeneratedRestApiDataSourceConfig = {
|
|
107
|
-
id: 'catalog-api',
|
|
108
|
-
kind: 'api',
|
|
109
|
-
origin: 'generated',
|
|
110
|
-
protocol: 'rest',
|
|
111
|
-
generatedApiId: 'catalog-api',
|
|
112
|
-
name: 'Catalog API',
|
|
113
|
-
adapter: {
|
|
114
|
-
id: 'primary-db',
|
|
115
|
-
kind: 'database',
|
|
116
|
-
packageName: '@ankhorage/supabase-db',
|
|
117
|
-
},
|
|
118
|
-
schemas: {
|
|
119
|
-
products: {
|
|
120
|
-
type: 'object',
|
|
121
|
-
required: ['id', 'name'],
|
|
122
|
-
properties: {
|
|
123
|
-
id: { type: 'string', format: 'uuid' },
|
|
124
|
-
name: { type: 'string' },
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
endpoints: {
|
|
129
|
-
products: {
|
|
130
|
-
id: 'products',
|
|
131
|
-
kind: 'database',
|
|
132
|
-
path: '/products',
|
|
133
|
-
operations: {
|
|
134
|
-
'products.list': {
|
|
135
|
-
id: 'products.list',
|
|
136
|
-
endpointId: 'products',
|
|
137
|
-
protocol: 'database',
|
|
138
|
-
intent: 'read',
|
|
139
|
-
},
|
|
140
|
-
'products.create': {
|
|
141
|
-
id: 'products.create',
|
|
142
|
-
endpointId: 'products',
|
|
143
|
-
protocol: 'database',
|
|
144
|
-
intent: 'create',
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
assertSerializable(source);
|
|
152
|
-
expect(source.adapter.kind).toBe('database');
|
|
153
|
-
expect(source.origin).toBe('generated');
|
|
154
|
-
expect(source.endpoints.products?.operations['products.create']?.intent).toBe('create');
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('keeps database sources separate from API origin and protocol', () => {
|
|
10
|
+
it('keeps database sources separate from canonical APIs', () => {
|
|
158
11
|
const source: DatabaseDataSourceConfig = {
|
|
159
12
|
id: 'primary-db',
|
|
160
13
|
kind: 'database',
|
|
@@ -164,27 +17,33 @@ describe('data source contracts', () => {
|
|
|
164
17
|
|
|
165
18
|
assertSerializable(source);
|
|
166
19
|
expect(source.kind).toBe('database');
|
|
20
|
+
expect('origin' in source).toBe(false);
|
|
21
|
+
expect('protocol' in source).toBe(false);
|
|
167
22
|
});
|
|
168
23
|
|
|
169
|
-
it('
|
|
24
|
+
it('keeps the data-source union database-specific', () => {
|
|
170
25
|
const source: DataSourceConfig = {
|
|
171
|
-
id: '
|
|
172
|
-
kind: '
|
|
173
|
-
|
|
174
|
-
protocol: 'rest',
|
|
175
|
-
baseUrl: 'https://public.example.com',
|
|
26
|
+
id: 'primary-db',
|
|
27
|
+
kind: 'database',
|
|
28
|
+
adapter: { id: 'database-adapter', kind: 'database' },
|
|
176
29
|
endpoints: {},
|
|
177
30
|
};
|
|
31
|
+
|
|
32
|
+
assertSerializable(source);
|
|
33
|
+
expect(source.adapter.kind).toBe('database');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('supports API identity on shared data diagnostics', () => {
|
|
178
37
|
const diagnostic: DataSourceDiagnostic = {
|
|
179
38
|
code: 'missing-operation',
|
|
180
39
|
severity: 'error',
|
|
181
40
|
message: 'Operation not found.',
|
|
182
|
-
|
|
183
|
-
endpointId: '
|
|
184
|
-
operationId: '
|
|
41
|
+
apiId: 'nutrition',
|
|
42
|
+
endpointId: 'products',
|
|
43
|
+
operationId: 'products.list',
|
|
185
44
|
};
|
|
186
45
|
|
|
187
|
-
assertSerializable(
|
|
188
|
-
expect(diagnostic.
|
|
46
|
+
assertSerializable(diagnostic);
|
|
47
|
+
expect(diagnostic.apiId).toBe('nutrition');
|
|
189
48
|
});
|
|
190
49
|
});
|
package/src/data/diagnostics.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataSourceId, EndpointId, OperationId } from './ids';
|
|
1
|
+
import type { ApiId, DataSourceId, EndpointId, OperationId } from './ids';
|
|
2
2
|
|
|
3
3
|
export type DataDiagnosticSeverity = 'error' | 'info' | 'warning';
|
|
4
4
|
|
|
@@ -7,6 +7,7 @@ export type DataDiagnosticCode =
|
|
|
7
7
|
| 'duplicate-operation-id'
|
|
8
8
|
| 'invalid-config'
|
|
9
9
|
| 'missing-adapter'
|
|
10
|
+
| 'missing-api'
|
|
10
11
|
| 'missing-credential'
|
|
11
12
|
| 'missing-data-source'
|
|
12
13
|
| 'missing-endpoint'
|
|
@@ -22,6 +23,7 @@ export interface DataSourceDiagnostic {
|
|
|
22
23
|
readonly code: DataDiagnosticCode;
|
|
23
24
|
readonly message: string;
|
|
24
25
|
readonly severity: DataDiagnosticSeverity;
|
|
26
|
+
readonly apiId?: ApiId;
|
|
25
27
|
readonly dataSourceId?: DataSourceId;
|
|
26
28
|
readonly endpointId?: EndpointId;
|
|
27
29
|
readonly operationId?: OperationId;
|
package/src/data/ids.ts
CHANGED
package/src/data/sources.ts
CHANGED
|
@@ -4,67 +4,19 @@ import type { CredentialRef, DatabaseAdapterRef } from './refs';
|
|
|
4
4
|
import type { DataSchemaRegistry } from './schemas';
|
|
5
5
|
import type { DataContractValue } from './values';
|
|
6
6
|
|
|
7
|
-
export type DataSourceKind = '
|
|
8
|
-
export type ApiOrigin = 'external' | 'generated';
|
|
9
|
-
export type ApiProtocol = 'graphql' | 'rest';
|
|
7
|
+
export type DataSourceKind = 'database';
|
|
10
8
|
|
|
11
|
-
export interface
|
|
9
|
+
export interface DatabaseDataSourceConfig {
|
|
12
10
|
readonly id: DataSourceId;
|
|
13
|
-
readonly kind:
|
|
11
|
+
readonly kind: 'database';
|
|
14
12
|
readonly name?: string;
|
|
15
13
|
readonly description?: string;
|
|
16
14
|
readonly credential?: CredentialRef;
|
|
15
|
+
readonly adapter: DatabaseAdapterRef;
|
|
17
16
|
readonly endpoints: DataEndpointRegistry;
|
|
18
17
|
readonly schemas?: DataSchemaRegistry;
|
|
19
18
|
readonly metadata?: DataContractValue;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export
|
|
23
|
-
readonly kind: 'api';
|
|
24
|
-
readonly origin: ApiOrigin;
|
|
25
|
-
readonly protocol: ApiProtocol;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface OpenApiDocumentRef {
|
|
29
|
-
readonly url?: string;
|
|
30
|
-
readonly documentId?: string;
|
|
31
|
-
readonly version?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface ExternalRestApiDataSourceConfig extends ApiDataSourceBaseConfig {
|
|
35
|
-
readonly origin: 'external';
|
|
36
|
-
readonly protocol: 'rest';
|
|
37
|
-
readonly baseUrl: string;
|
|
38
|
-
readonly openApi?: OpenApiDocumentRef;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface ExternalGraphQlApiDataSourceConfig extends ApiDataSourceBaseConfig {
|
|
42
|
-
readonly origin: 'external';
|
|
43
|
-
readonly protocol: 'graphql';
|
|
44
|
-
readonly endpointUrl: string;
|
|
45
|
-
readonly introspection?: {
|
|
46
|
-
readonly enabled: boolean;
|
|
47
|
-
readonly schemaVersion?: string;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface GeneratedRestApiDataSourceConfig extends ApiDataSourceBaseConfig {
|
|
52
|
-
readonly origin: 'generated';
|
|
53
|
-
readonly protocol: 'rest';
|
|
54
|
-
readonly generatedApiId: string;
|
|
55
|
-
readonly adapter: DatabaseAdapterRef;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export type ApiDataSourceConfig =
|
|
59
|
-
| ExternalGraphQlApiDataSourceConfig
|
|
60
|
-
| ExternalRestApiDataSourceConfig
|
|
61
|
-
| GeneratedRestApiDataSourceConfig;
|
|
62
|
-
|
|
63
|
-
export interface DatabaseDataSourceConfig extends DataSourceBaseConfig {
|
|
64
|
-
readonly kind: 'database';
|
|
65
|
-
readonly adapter: DatabaseAdapterRef;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export type DataSourceConfig = ApiDataSourceConfig | DatabaseDataSourceConfig;
|
|
69
|
-
|
|
21
|
+
export type DataSourceConfig = DatabaseDataSourceConfig;
|
|
70
22
|
export type DataSourceRegistry = Readonly<Record<DataSourceId, DataSourceConfig>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ANKHORAGE_CAPABILITY_NAMES,
|
|
5
|
+
type AnkhorageCapabilityName,
|
|
6
|
+
type ComponentRequirements,
|
|
7
|
+
type ScreenRequirements,
|
|
8
|
+
} from './index';
|
|
9
|
+
|
|
10
|
+
describe('platform requirements', () => {
|
|
11
|
+
it('exports ebookReader as the canonical reader capability', () => {
|
|
12
|
+
const capability: AnkhorageCapabilityName = 'ebookReader';
|
|
13
|
+
const componentRequirements: ComponentRequirements = {
|
|
14
|
+
capabilities: [{ capability }],
|
|
15
|
+
};
|
|
16
|
+
const screenRequirements: ScreenRequirements = {
|
|
17
|
+
capabilities: [{ capability }],
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
expect(ANKHORAGE_CAPABILITY_NAMES).toContain(capability);
|
|
21
|
+
expect(componentRequirements).toEqual(screenRequirements);
|
|
22
|
+
});
|
|
23
|
+
});
|
package/src/requirements.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ComponentDataBindingRegistry,
|
|
7
7
|
ScreenDataLoaderDefinition,
|
|
8
8
|
} from './bindings';
|
|
9
|
-
import type {
|
|
9
|
+
import type { ApiDefinitionList, DataSourceRegistry } from './data';
|
|
10
10
|
import type { AppDeployManifest } from './deploy';
|
|
11
11
|
import type { MediaManifest } from './media';
|
|
12
12
|
import type { ScreenRequirements } from './requirements';
|
|
@@ -374,12 +374,12 @@ export interface InfraManifest {
|
|
|
374
374
|
storage?: StorageSpec;
|
|
375
375
|
state?: StateSpec;
|
|
376
376
|
networking?: NetworkingSpec;
|
|
377
|
+
apis?: ApiDefinitionList;
|
|
377
378
|
modules: string[];
|
|
378
379
|
modulesConfig?: Record<string, unknown>;
|
|
379
380
|
}
|
|
380
381
|
|
|
381
382
|
export interface AppSettings {
|
|
382
|
-
apiBaseUrl?: string;
|
|
383
383
|
localization: {
|
|
384
384
|
defaultLocale: string;
|
|
385
385
|
locales: string[];
|
|
@@ -407,7 +407,6 @@ export interface AppManifest {
|
|
|
407
407
|
infra: InfraManifest;
|
|
408
408
|
navigator: NavigatorSpec;
|
|
409
409
|
screens: Record<string, ScreenSpec>;
|
|
410
|
-
generatedApis?: GeneratedApiRegistry;
|
|
411
410
|
dataSources?: DataSourceRegistry;
|
|
412
411
|
dataBindings?: ComponentDataBindingRegistry;
|
|
413
412
|
settings: AppSettings;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generatedApis.d.ts","sourceRoot":"","sources":["../../src/appManifest/generatedApis.ts"],"names":[],"mappings":"AAQA,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9D"}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { isManifestValue, isOptionalBoolean, isOptionalString, isRecord, isStringArray, } from './shared';
|
|
2
|
-
export function isGeneratedApiRegistry(value) {
|
|
3
|
-
return isRecord(value) && Object.values(value).every(isGeneratedApiDefinition);
|
|
4
|
-
}
|
|
5
|
-
function isGeneratedApiDefinition(value) {
|
|
6
|
-
return (isRecord(value) &&
|
|
7
|
-
typeof value.id === 'string' &&
|
|
8
|
-
value.protocol === 'rest' &&
|
|
9
|
-
isOptionalString(value.name) &&
|
|
10
|
-
isOptionalString(value.description) &&
|
|
11
|
-
typeof value.basePath === 'string' &&
|
|
12
|
-
isDatabaseAdapterRef(value.database) &&
|
|
13
|
-
Array.isArray(value.resources) &&
|
|
14
|
-
value.resources.every(isGeneratedApiResourceDefinition) &&
|
|
15
|
-
(value.auth === undefined || isGeneratedApiAuthRequirement(value.auth)) &&
|
|
16
|
-
(value.metadata === undefined || isManifestValue(value.metadata)));
|
|
17
|
-
}
|
|
18
|
-
function isDatabaseAdapterRef(value) {
|
|
19
|
-
return isRecord(value) && value.kind === 'database' && isAdapterRef(value);
|
|
20
|
-
}
|
|
21
|
-
function isGeneratedApiAuthRequirement(value) {
|
|
22
|
-
return (isRecord(value) &&
|
|
23
|
-
isOptionalBoolean(value.required) &&
|
|
24
|
-
(value.roles === undefined || isStringArray(value.roles)) &&
|
|
25
|
-
(value.permissions === undefined || isStringArray(value.permissions)) &&
|
|
26
|
-
isOptionalString(value.policy) &&
|
|
27
|
-
(value.metadata === undefined || isManifestValue(value.metadata)));
|
|
28
|
-
}
|
|
29
|
-
function isGeneratedApiResourceDefinition(value) {
|
|
30
|
-
return (isRecord(value) &&
|
|
31
|
-
typeof value.id === 'string' &&
|
|
32
|
-
isOptionalString(value.name) &&
|
|
33
|
-
isOptionalString(value.description) &&
|
|
34
|
-
typeof value.path === 'string' &&
|
|
35
|
-
isDbCollectionDefinition(value.collection) &&
|
|
36
|
-
Array.isArray(value.operations) &&
|
|
37
|
-
value.operations.every(isGeneratedApiCrudOperation) &&
|
|
38
|
-
(value.seed === undefined || isSeedRecords(value.seed)) &&
|
|
39
|
-
(value.policies === undefined ||
|
|
40
|
-
(Array.isArray(value.policies) && value.policies.every(isGeneratedApiPolicyRef))) &&
|
|
41
|
-
(value.metadata === undefined || isManifestValue(value.metadata)));
|
|
42
|
-
}
|
|
43
|
-
function isSeedRecords(value) {
|
|
44
|
-
return (Array.isArray(value) &&
|
|
45
|
-
value.every((record) => isRecord(record) && Object.values(record).every(isManifestValue)));
|
|
46
|
-
}
|
|
47
|
-
function isGeneratedApiCrudOperation(value) {
|
|
48
|
-
return ['create', 'delete', 'list', 'read', 'update'].includes(String(value));
|
|
49
|
-
}
|
|
50
|
-
function isGeneratedApiPolicyRef(value) {
|
|
51
|
-
return (isRecord(value) &&
|
|
52
|
-
typeof value.id === 'string' &&
|
|
53
|
-
(value.operation === undefined || isGeneratedApiCrudOperation(value.operation)));
|
|
54
|
-
}
|
|
55
|
-
function isDbCollectionDefinition(value) {
|
|
56
|
-
return (isRecord(value) &&
|
|
57
|
-
typeof value.name === 'string' &&
|
|
58
|
-
isOptionalString(value.schema) &&
|
|
59
|
-
Array.isArray(value.fields) &&
|
|
60
|
-
value.fields.every(isDbFieldDefinition) &&
|
|
61
|
-
isOptionalString(value.primaryKey));
|
|
62
|
-
}
|
|
63
|
-
function isDbFieldDefinition(value) {
|
|
64
|
-
return (isRecord(value) &&
|
|
65
|
-
typeof value.name === 'string' &&
|
|
66
|
-
typeof value.type === 'string' &&
|
|
67
|
-
['text', 'number', 'boolean', 'datetime', 'json', 'uuid'].includes(value.type) &&
|
|
68
|
-
isOptionalBoolean(value.required) &&
|
|
69
|
-
isOptionalBoolean(value.unique) &&
|
|
70
|
-
isDbDefaultValue(value.defaultValue));
|
|
71
|
-
}
|
|
72
|
-
function isDbDefaultValue(value) {
|
|
73
|
-
return (value === undefined ||
|
|
74
|
-
value === null ||
|
|
75
|
-
typeof value === 'boolean' ||
|
|
76
|
-
typeof value === 'number' ||
|
|
77
|
-
typeof value === 'string');
|
|
78
|
-
}
|
|
79
|
-
function isAdapterRef(value) {
|
|
80
|
-
return (isRecord(value) &&
|
|
81
|
-
typeof value.id === 'string' &&
|
|
82
|
-
typeof value.kind === 'string' &&
|
|
83
|
-
isOptionalString(value.packageName) &&
|
|
84
|
-
isOptionalString(value.exportName) &&
|
|
85
|
-
(value.config === undefined || isManifestValue(value.config)));
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=generatedApis.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generatedApis.js","sourceRoot":"","sources":["../../src/appManifest/generatedApis.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isManifestValue,\n isOptionalBoolean,\n isOptionalString,\n isRecord,\n isStringArray,\n} from './shared';\n\nexport function isGeneratedApiRegistry(value: unknown): boolean {\n return isRecord(value) && Object.values(value).every(isGeneratedApiDefinition);\n}\n\nfunction isGeneratedApiDefinition(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.id === 'string' &&\n value.protocol === 'rest' &&\n isOptionalString(value.name) &&\n isOptionalString(value.description) &&\n typeof value.basePath === 'string' &&\n isDatabaseAdapterRef(value.database) &&\n Array.isArray(value.resources) &&\n value.resources.every(isGeneratedApiResourceDefinition) &&\n (value.auth === undefined || isGeneratedApiAuthRequirement(value.auth)) &&\n (value.metadata === undefined || isManifestValue(value.metadata))\n );\n}\n\nfunction isDatabaseAdapterRef(value: unknown): boolean {\n return isRecord(value) && value.kind === 'database' && isAdapterRef(value);\n}\n\nfunction isGeneratedApiAuthRequirement(value: unknown): boolean {\n return (\n isRecord(value) &&\n isOptionalBoolean(value.required) &&\n (value.roles === undefined || isStringArray(value.roles)) &&\n (value.permissions === undefined || isStringArray(value.permissions)) &&\n isOptionalString(value.policy) &&\n (value.metadata === undefined || isManifestValue(value.metadata))\n );\n}\n\nfunction isGeneratedApiResourceDefinition(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.id === 'string' &&\n isOptionalString(value.name) &&\n isOptionalString(value.description) &&\n typeof value.path === 'string' &&\n isDbCollectionDefinition(value.collection) &&\n Array.isArray(value.operations) &&\n value.operations.every(isGeneratedApiCrudOperation) &&\n (value.seed === undefined || isSeedRecords(value.seed)) &&\n (value.policies === undefined ||\n (Array.isArray(value.policies) && value.policies.every(isGeneratedApiPolicyRef))) &&\n (value.metadata === undefined || isManifestValue(value.metadata))\n );\n}\n\nfunction isSeedRecords(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every((record) => isRecord(record) && Object.values(record).every(isManifestValue))\n );\n}\n\nfunction isGeneratedApiCrudOperation(value: unknown): boolean {\n return ['create', 'delete', 'list', 'read', 'update'].includes(String(value));\n}\n\nfunction isGeneratedApiPolicyRef(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.id === 'string' &&\n (value.operation === undefined || isGeneratedApiCrudOperation(value.operation))\n );\n}\n\nfunction isDbCollectionDefinition(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n isOptionalString(value.schema) &&\n Array.isArray(value.fields) &&\n value.fields.every(isDbFieldDefinition) &&\n isOptionalString(value.primaryKey)\n );\n}\n\nfunction isDbFieldDefinition(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n typeof value.type === 'string' &&\n ['text', 'number', 'boolean', 'datetime', 'json', 'uuid'].includes(value.type) &&\n isOptionalBoolean(value.required) &&\n isOptionalBoolean(value.unique) &&\n isDbDefaultValue(value.defaultValue)\n );\n}\n\nfunction isDbDefaultValue(value: unknown): boolean {\n return (\n value === undefined ||\n value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string'\n );\n}\n\nfunction isAdapterRef(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.id === 'string' &&\n typeof value.kind === 'string' &&\n isOptionalString(value.packageName) &&\n isOptionalString(value.exportName) &&\n (value.config === undefined || isManifestValue(value.config))\n );\n}\n"]}
|
|
@@ -1,122 +0,0 @@
|
|
|
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
|
-
}
|