@ankhorage/contracts 1.14.0 → 1.16.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/dist/data/apis.d.ts +76 -0
- package/dist/data/apis.d.ts.map +1 -0
- package/dist/data/apis.js +20 -0
- package/dist/data/apis.js.map +1 -0
- package/dist/data/index.d.ts +1 -0
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +1 -0
- package/dist/data/index.js.map +1 -1
- package/dist/types.d.ts +12 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/contracts.test.ts +25 -0
- package/src/data/apis.test.ts +146 -0
- package/src/data/apis.ts +105 -0
- package/src/data/index.ts +1 -0
- package/src/types.ts +15 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ankhorage/contracts
|
|
2
2
|
|
|
3
|
+
## 1.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5105c41: Add API authoring contracts for generated and external APIs with explicit endpoints, generated CRUD presets, and collection-backed resources.
|
|
8
|
+
|
|
9
|
+
## 1.15.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 94d5656: Add frontend-first app dataset contracts and state provider selection to app manifests.
|
|
14
|
+
|
|
3
15
|
## 1.14.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { DbCollectionDefinition } from '../db';
|
|
2
|
+
import type { DataOperationRequest, DataOperationResponse } from './operations';
|
|
3
|
+
import type { DataContractValue } from './values';
|
|
4
|
+
export declare const APP_API_KINDS: readonly ["external", "generated"];
|
|
5
|
+
export type AppApiKind = (typeof APP_API_KINDS)[number];
|
|
6
|
+
export declare const APP_API_GENERATED_PRESETS: readonly ["crud"];
|
|
7
|
+
export type AppApiGeneratedPreset = (typeof APP_API_GENERATED_PRESETS)[number];
|
|
8
|
+
export declare const APP_API_ENDPOINT_METHODS: readonly ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"];
|
|
9
|
+
export type AppApiEndpointMethod = (typeof APP_API_ENDPOINT_METHODS)[number];
|
|
10
|
+
export declare const APP_API_ENDPOINT_INTENTS: readonly ["create", "custom", "delete", "list", "read", "update"];
|
|
11
|
+
export type AppApiEndpointIntent = (typeof APP_API_ENDPOINT_INTENTS)[number];
|
|
12
|
+
export type AppApiId = string;
|
|
13
|
+
export type AppApiEndpointId = string;
|
|
14
|
+
export type AppApiSeedRecord = Readonly<Record<string, DataContractValue>>;
|
|
15
|
+
export interface AppApiAuthRequirement {
|
|
16
|
+
readonly required?: boolean;
|
|
17
|
+
readonly roles?: readonly string[];
|
|
18
|
+
readonly permissions?: readonly string[];
|
|
19
|
+
readonly policy?: string;
|
|
20
|
+
readonly metadata?: DataContractValue;
|
|
21
|
+
}
|
|
22
|
+
export interface AppApiCollectionResourceDefinition {
|
|
23
|
+
readonly kind: 'collection';
|
|
24
|
+
readonly collection: DbCollectionDefinition;
|
|
25
|
+
readonly seed?: readonly AppApiSeedRecord[];
|
|
26
|
+
readonly metadata?: DataContractValue;
|
|
27
|
+
}
|
|
28
|
+
export type AppApiResourceDefinition = AppApiCollectionResourceDefinition;
|
|
29
|
+
export interface AppApiEndpointDefinition {
|
|
30
|
+
readonly id: AppApiEndpointId;
|
|
31
|
+
readonly label?: string;
|
|
32
|
+
readonly description?: string;
|
|
33
|
+
readonly method: AppApiEndpointMethod;
|
|
34
|
+
/**
|
|
35
|
+
* Path relative to the API base path. Use `/` for the base collection endpoint.
|
|
36
|
+
*/
|
|
37
|
+
readonly path: string;
|
|
38
|
+
readonly intent?: AppApiEndpointIntent;
|
|
39
|
+
readonly request?: DataOperationRequest;
|
|
40
|
+
readonly response?: DataOperationResponse;
|
|
41
|
+
readonly auth?: AppApiAuthRequirement;
|
|
42
|
+
readonly metadata?: DataContractValue;
|
|
43
|
+
}
|
|
44
|
+
interface AppApiDefinitionBase {
|
|
45
|
+
readonly id: AppApiId;
|
|
46
|
+
readonly kind: AppApiKind;
|
|
47
|
+
readonly label?: string;
|
|
48
|
+
readonly description?: string;
|
|
49
|
+
readonly basePath: string;
|
|
50
|
+
readonly endpoints: readonly AppApiEndpointDefinition[];
|
|
51
|
+
readonly auth?: AppApiAuthRequirement;
|
|
52
|
+
readonly metadata?: DataContractValue;
|
|
53
|
+
}
|
|
54
|
+
export interface AppGeneratedApiDefinition extends AppApiDefinitionBase {
|
|
55
|
+
readonly kind: 'generated';
|
|
56
|
+
/**
|
|
57
|
+
* Preset used by authoring tools to seed standard endpoints. The resulting
|
|
58
|
+
* serialized API still stores concrete `endpoints[]` so custom endpoints can
|
|
59
|
+
* live next to generated CRUD operations.
|
|
60
|
+
*/
|
|
61
|
+
readonly preset?: AppApiGeneratedPreset;
|
|
62
|
+
readonly resource?: AppApiResourceDefinition;
|
|
63
|
+
}
|
|
64
|
+
export interface AppExternalApiDefinition extends AppApiDefinitionBase {
|
|
65
|
+
readonly kind: 'external';
|
|
66
|
+
readonly baseUrl?: string;
|
|
67
|
+
readonly openApiUrl?: string;
|
|
68
|
+
}
|
|
69
|
+
export type AppApiDefinition = AppExternalApiDefinition | AppGeneratedApiDefinition;
|
|
70
|
+
export type AppApiRegistry = Readonly<Record<AppApiId, AppApiDefinition>>;
|
|
71
|
+
export interface AppDataManifest {
|
|
72
|
+
readonly apis?: AppApiRegistry;
|
|
73
|
+
}
|
|
74
|
+
export type AppApiManifest = AppDataManifest;
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=apis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apis.d.ts","sourceRoot":"","sources":["../../src/data/apis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const APP_API_KINDS = ['external', 'generated'];
|
|
2
|
+
export const APP_API_GENERATED_PRESETS = ['crud'];
|
|
3
|
+
export const APP_API_ENDPOINT_METHODS = [
|
|
4
|
+
'DELETE',
|
|
5
|
+
'GET',
|
|
6
|
+
'HEAD',
|
|
7
|
+
'OPTIONS',
|
|
8
|
+
'PATCH',
|
|
9
|
+
'POST',
|
|
10
|
+
'PUT',
|
|
11
|
+
];
|
|
12
|
+
export const APP_API_ENDPOINT_INTENTS = [
|
|
13
|
+
'create',
|
|
14
|
+
'custom',
|
|
15
|
+
'delete',
|
|
16
|
+
'list',
|
|
17
|
+
'read',
|
|
18
|
+
'update',
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=apis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apis.js","sourceRoot":"","sources":["../../src/data/apis.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,WAAW,CAAU,CAAC;AAGhE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,MAAM,CAAU,CAAC;AAG3D,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,QAAQ;IACR,KAAK;IACL,MAAM;IACN,SAAS;IACT,OAAO;IACP,MAAM;IACN,KAAK;CACG,CAAC;AAGX,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,MAAM;IACN,QAAQ;CACA,CAAC","sourcesContent":["import type { DbCollectionDefinition } from '../db';\nimport type { DataOperationRequest, DataOperationResponse } from './operations';\nimport type { DataContractValue } from './values';\n\nexport const APP_API_KINDS = ['external', 'generated'] as const;\nexport type AppApiKind = (typeof APP_API_KINDS)[number];\n\nexport const APP_API_GENERATED_PRESETS = ['crud'] as const;\nexport type AppApiGeneratedPreset = (typeof APP_API_GENERATED_PRESETS)[number];\n\nexport const APP_API_ENDPOINT_METHODS = [\n 'DELETE',\n 'GET',\n 'HEAD',\n 'OPTIONS',\n 'PATCH',\n 'POST',\n 'PUT',\n] as const;\nexport type AppApiEndpointMethod = (typeof APP_API_ENDPOINT_METHODS)[number];\n\nexport const APP_API_ENDPOINT_INTENTS = [\n 'create',\n 'custom',\n 'delete',\n 'list',\n 'read',\n 'update',\n] as const;\nexport type AppApiEndpointIntent = (typeof APP_API_ENDPOINT_INTENTS)[number];\n\nexport type AppApiId = string;\nexport type AppApiEndpointId = string;\nexport type AppApiSeedRecord = Readonly<Record<string, DataContractValue>>;\n\nexport interface AppApiAuthRequirement {\n readonly required?: boolean;\n readonly roles?: readonly string[];\n readonly permissions?: readonly string[];\n readonly policy?: string;\n readonly metadata?: DataContractValue;\n}\n\nexport interface AppApiCollectionResourceDefinition {\n readonly kind: 'collection';\n readonly collection: DbCollectionDefinition;\n readonly seed?: readonly AppApiSeedRecord[];\n readonly metadata?: DataContractValue;\n}\n\nexport type AppApiResourceDefinition = AppApiCollectionResourceDefinition;\n\nexport interface AppApiEndpointDefinition {\n readonly id: AppApiEndpointId;\n readonly label?: string;\n readonly description?: string;\n readonly method: AppApiEndpointMethod;\n /**\n * Path relative to the API base path. Use `/` for the base collection endpoint.\n */\n readonly path: string;\n readonly intent?: AppApiEndpointIntent;\n readonly request?: DataOperationRequest;\n readonly response?: DataOperationResponse;\n readonly auth?: AppApiAuthRequirement;\n readonly metadata?: DataContractValue;\n}\n\ninterface AppApiDefinitionBase {\n readonly id: AppApiId;\n readonly kind: AppApiKind;\n readonly label?: string;\n readonly description?: string;\n readonly basePath: string;\n readonly endpoints: readonly AppApiEndpointDefinition[];\n readonly auth?: AppApiAuthRequirement;\n readonly metadata?: DataContractValue;\n}\n\nexport interface AppGeneratedApiDefinition extends AppApiDefinitionBase {\n readonly kind: 'generated';\n /**\n * Preset used by authoring tools to seed standard endpoints. The resulting\n * serialized API still stores concrete `endpoints[]` so custom endpoints can\n * live next to generated CRUD operations.\n */\n readonly preset?: AppApiGeneratedPreset;\n readonly resource?: AppApiResourceDefinition;\n}\n\nexport interface AppExternalApiDefinition extends AppApiDefinitionBase {\n readonly kind: 'external';\n readonly baseUrl?: string;\n readonly openApiUrl?: string;\n}\n\nexport type AppApiDefinition = AppExternalApiDefinition | AppGeneratedApiDefinition;\n\nexport type AppApiRegistry = Readonly<Record<AppApiId, AppApiDefinition>>;\n\nexport interface AppDataManifest {\n readonly apis?: AppApiRegistry;\n}\n\nexport type AppApiManifest = AppDataManifest;\n"]}
|
package/dist/data/index.d.ts
CHANGED
package/dist/data/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
|
package/dist/data/index.js
CHANGED
package/dist/data/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC","sourcesContent":["export * from './diagnostics';\nexport * from './endpoints';\nexport * from './ids';\nexport * from './operations';\nexport * from './refs';\nexport * from './schemas';\nexport * from './sources';\nexport * from './values';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC","sourcesContent":["export * from './apis';\nexport * from './diagnostics';\nexport * from './endpoints';\nexport * from './ids';\nexport * from './operations';\nexport * from './refs';\nexport * from './schemas';\nexport * from './sources';\nexport * from './values';\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ColorHarmony } from '@ankhorage/color-theory';
|
|
2
2
|
import type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';
|
|
3
3
|
import type { ComponentDataBindingRegistry } from './bindings';
|
|
4
|
-
import type { DataSourceRegistry } from './data';
|
|
4
|
+
import type { AppDataManifest, DataSourceRegistry } from './data';
|
|
5
5
|
export interface ThemeModeConfig {
|
|
6
6
|
primaryColor: string;
|
|
7
7
|
harmony: ColorHarmony;
|
|
@@ -90,6 +90,11 @@ export declare const DATABASE_TIERS: readonly ["dev", "prod"];
|
|
|
90
90
|
export type DatabaseTier = (typeof DATABASE_TIERS)[number];
|
|
91
91
|
export declare const STORAGE_PROVIDERS: readonly ["auto", "s3", "r2"];
|
|
92
92
|
export type StorageProvider = (typeof STORAGE_PROVIDERS)[number];
|
|
93
|
+
export declare const STATE_PROVIDERS: readonly ["legend"];
|
|
94
|
+
export type KnownStateProvider = (typeof STATE_PROVIDERS)[number];
|
|
95
|
+
export type StateProvider = KnownStateProvider | (string & {});
|
|
96
|
+
export declare const STATE_PERSISTENCE_MODES: readonly ["none", "local", "secure", "database"];
|
|
97
|
+
export type StatePersistenceMode = (typeof STATE_PERSISTENCE_MODES)[number];
|
|
93
98
|
export declare const AUTHZ_KINDS: readonly ["RBAC", "ABAC"];
|
|
94
99
|
export type AuthzKind = (typeof AUTHZ_KINDS)[number];
|
|
95
100
|
export declare const AUTHZ_ENGINES: readonly ["cerbos", "native"];
|
|
@@ -167,6 +172,10 @@ export interface StorageSpec {
|
|
|
167
172
|
provider: StorageProvider;
|
|
168
173
|
buckets: string[];
|
|
169
174
|
}
|
|
175
|
+
export interface StateSpec {
|
|
176
|
+
readonly provider: StateProvider;
|
|
177
|
+
readonly persistence?: StatePersistenceMode;
|
|
178
|
+
}
|
|
170
179
|
export interface AuthzSpec {
|
|
171
180
|
kind: AuthzKind;
|
|
172
181
|
engine: AuthzEngine;
|
|
@@ -201,6 +210,7 @@ export interface InfraManifest {
|
|
|
201
210
|
auth?: AuthSpec;
|
|
202
211
|
database?: DatabaseSpec;
|
|
203
212
|
storage?: StorageSpec;
|
|
213
|
+
state?: StateSpec;
|
|
204
214
|
networking?: NetworkingSpec;
|
|
205
215
|
plugins: string[];
|
|
206
216
|
pluginsConfig?: Record<string, unknown>;
|
|
@@ -221,6 +231,7 @@ export interface AppManifest {
|
|
|
221
231
|
infra: InfraManifest;
|
|
222
232
|
navigator: NavigatorSpec;
|
|
223
233
|
screens: Record<string, ScreenSpec>;
|
|
234
|
+
data?: AppDataManifest;
|
|
224
235
|
dataSources?: DataSourceRegistry;
|
|
225
236
|
dataBindings?: ComponentDataBindingRegistry;
|
|
226
237
|
settings: {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACnG,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -28,6 +28,8 @@ export const DEPLOYMENT_TARGETS = ['minikube'];
|
|
|
28
28
|
export const DATABASE_PROVIDERS = ['supabase'];
|
|
29
29
|
export const DATABASE_TIERS = ['dev', 'prod'];
|
|
30
30
|
export const STORAGE_PROVIDERS = ['auto', 's3', 'r2'];
|
|
31
|
+
export const STATE_PROVIDERS = ['legend'];
|
|
32
|
+
export const STATE_PERSISTENCE_MODES = ['none', 'local', 'secure', 'database'];
|
|
31
33
|
export const AUTHZ_KINDS = ['RBAC', 'ABAC'];
|
|
32
34
|
export const AUTHZ_ENGINES = ['cerbos', 'native'];
|
|
33
35
|
export const AUTH_SCOPES = ['global', 'none', 'integrated'];
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsIA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAGpE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe;IACf,uBAAuB;IACvB,iBAAiB;IACjB,oBAAoB;IACpB,qBAAqB;IACrB,eAAe;IACf,YAAY;IACZ,OAAO;IACP,iBAAiB;IACjB,gBAAgB;IAChB,aAAa;IACb,WAAW;IACX,SAAS;IACT,aAAa;IACb,mBAAmB;IACnB,gBAAgB;IAChB,aAAa;IACb,WAAW;IACX,mBAAmB;IACnB,kBAAkB;IAClB,QAAQ;IACR,iBAAiB;IACjB,SAAS;CACD,CAAC;AAGX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,CAAU,CAAC;AAIxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,CAAU,CAAC;AAIxD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAC;AAGvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAG/D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAU,CAAC;AAGrD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAG3D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAU,CAAC;AAGrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAU,CAAU,CAAC;AAIpD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AAGhF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,YAAY,EAAE,qBAAqB,CAAU,CAAC;AAGpF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,wBAAwB;IAC3B,WAAW;IACX,UAAU;IACV,aAAa;IACb,WAAW;CACH,CAAC","sourcesContent":["import type { ColorHarmony } from '@ankhorage/color-theory';\n\nimport type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';\nimport type { ComponentDataBindingRegistry } from './bindings';\nimport type { DataSourceRegistry } from './data';\n\nexport interface ThemeModeConfig {\n primaryColor: string;\n harmony: ColorHarmony;\n}\n\nexport interface ThemeConfig {\n id: string;\n name: string;\n light: ThemeModeConfig;\n dark: ThemeModeConfig;\n}\n\nexport type ActionType =\n | 'navigate'\n | 'alert'\n | 'console'\n | 'toggleDarkMode'\n | 'setLanguage'\n | 'search'\n | 'filter';\n\nexport interface NavigateAction {\n type: 'navigate';\n payload: {\n route: string;\n params?: Record<string, number | string>;\n };\n}\n\nexport interface AlertAction {\n type: 'alert';\n payload?: {\n message?: string;\n };\n}\n\nexport interface ConsoleAction {\n type: 'console';\n payload?: Record<string, unknown>;\n}\n\nexport interface ToggleDarkModeAction {\n type: 'toggleDarkMode';\n payload?: never;\n}\n\nexport interface SetLanguageAction {\n type: 'setLanguage';\n payload: {\n locale: string;\n };\n}\n\nexport interface SearchAction {\n type: 'search';\n payload: {\n query: string;\n scope?: string;\n };\n}\n\nexport interface FilterAction {\n type: 'filter';\n payload: {\n filterKey: string;\n filterValue: string;\n };\n}\n\nexport type Action =\n | AlertAction\n | ConsoleAction\n | FilterAction\n | NavigateAction\n | SearchAction\n | SetLanguageAction\n | ToggleDarkModeAction;\n\nexport type ManifestValue =\n | string\n | number\n | boolean\n | null\n | readonly ManifestValue[]\n | { readonly [key: string]: ManifestValue };\n\nexport type ComponentEventPayloadValue = ManifestValue;\n\nexport interface ComponentEventDto<\n TType extends string = string,\n TPayload extends object = Record<string, ComponentEventPayloadValue>,\n> {\n readonly type: TType;\n readonly sourceNodeId: string;\n readonly payload: TPayload;\n}\n\nexport type FormSubmitValues = Record<string, ComponentEventPayloadValue>;\n\nexport type FormSubmitEventDto = ComponentEventDto<\n 'form.submit',\n {\n readonly values: FormSubmitValues;\n }\n>;\n\nexport type ButtonPressEventDto = ComponentEventDto<'button.press', Record<string, never>>;\n\nexport interface CollectionItemPressPayload {\n readonly itemId: string | number;\n readonly item: Record<string, ComponentEventPayloadValue>;\n}\n\nexport type CollectionItemPressEventDto = ComponentEventDto<\n 'collection.itemPress',\n CollectionItemPressPayload\n>;\n\nexport type ComponentEventDtoKind =\n | ButtonPressEventDto['type']\n | CollectionItemPressEventDto['type']\n | FormSubmitEventDto['type'];\n\nexport type KnownComponentEventDto =\n | ButtonPressEventDto\n | CollectionItemPressEventDto\n | FormSubmitEventDto;\n\nexport const NAVIGATOR_TYPES = ['stack', 'tabs', 'drawer'] as const;\nexport type NavigatorType = (typeof NAVIGATOR_TYPES)[number];\n\nexport const APP_CATEGORIES = [\n 'books_reading',\n 'business_productivity',\n 'developer_tools',\n 'education_learning',\n 'entertainment_media',\n 'finance_money',\n 'food_drink',\n 'games',\n 'graphics_design',\n 'health_fitness',\n 'kids_family',\n 'lifestyle',\n 'medical',\n 'music_audio',\n 'navigation_travel',\n 'news_magazines',\n 'photo_video',\n 'reference',\n 'shopping_commerce',\n 'social_community',\n 'sports',\n 'utilities_tools',\n 'weather',\n] as const;\nexport type AppCategory = (typeof APP_CATEGORIES)[number];\n\nexport const DEPLOYMENT_TARGETS = ['minikube'] as const;\nexport type KnownDeploymentTarget = (typeof DEPLOYMENT_TARGETS)[number];\nexport type DeploymentTarget = KnownDeploymentTarget | (string & {});\n\nexport const DATABASE_PROVIDERS = ['supabase'] as const;\nexport type KnownDatabaseProvider = (typeof DATABASE_PROVIDERS)[number];\nexport type DatabaseProvider = KnownDatabaseProvider | (string & {});\n\nexport const DATABASE_TIERS = ['dev', 'prod'] as const;\nexport type DatabaseTier = (typeof DATABASE_TIERS)[number];\n\nexport const STORAGE_PROVIDERS = ['auto', 's3', 'r2'] as const;\nexport type StorageProvider = (typeof STORAGE_PROVIDERS)[number];\n\nexport const AUTHZ_KINDS = ['RBAC', 'ABAC'] as const;\nexport type AuthzKind = (typeof AUTHZ_KINDS)[number];\n\nexport const AUTHZ_ENGINES = ['cerbos', 'native'] as const;\nexport type AuthzEngine = (typeof AUTHZ_ENGINES)[number];\n\nexport const AUTH_SCOPES = ['global', 'none', 'integrated'] as const;\nexport type AuthScope = (typeof AUTH_SCOPES)[number];\n\nexport const AUTH_PROVIDERS = ['supabase'] as const;\nexport type KnownAuthProvider = (typeof AUTH_PROVIDERS)[number];\nexport type AuthProvider = KnownAuthProvider | (string & {});\n\nexport const AUTH_SIGN_IN_IDENTIFIERS = ['email', 'username', 'phone'] as const;\nexport type AuthSignInIdentifier = AuthIdentifierKind;\n\nexport const AUTH_SIGN_UP_POLICIES = ['autoSignIn', 'requireVerification'] as const;\nexport type AuthSignUpPolicy = (typeof AUTH_SIGN_UP_POLICIES)[number];\n\nexport const AUTH_PROFILE_FIELDS = [\n ...AUTH_SIGN_IN_IDENTIFIERS,\n 'firstName',\n 'lastName',\n 'displayName',\n 'avatarUrl',\n] as const;\nexport type KnownAuthProfileField = (typeof AUTH_PROFILE_FIELDS)[number];\nexport type AuthProfileField = KnownAuthProfileField | (string & {});\n\nexport interface IconSpec {\n name: string;\n provider?: string;\n size?: number | string;\n color?: string;\n}\n\nexport interface UiNode {\n id: string;\n type: string;\n alias?: string;\n props?: Record<string, unknown>;\n children?: UiNode[];\n style?: Record<string, number | string>;\n}\n\nexport interface ScreenSpec {\n id: string;\n name: string;\n title?: string;\n description?: string;\n root: UiNode;\n}\n\nexport interface NavigatorSpec {\n type: NavigatorType;\n initialRouteName?: string;\n routes: RouteDefinition[];\n options?: Record<string, unknown>;\n}\n\nexport interface RouteDefinition {\n name: string;\n path?: string;\n label?: string;\n icon?: IconSpec;\n hideInTabBar?: boolean;\n guards?: string[];\n screenId?: string;\n navigator?: NavigatorSpec;\n}\n\nexport type SplashScreenResizeMode = 'contain' | 'cover' | 'native';\n\nexport interface SplashScreenAssetSpec {\n readonly image?: string;\n readonly imageWidth?: number;\n readonly resizeMode?: SplashScreenResizeMode;\n}\n\nexport interface SplashScreenModeSpec extends SplashScreenAssetSpec {\n readonly backgroundColor?: string;\n}\n\nexport interface SplashScreenSpec extends SplashScreenModeSpec {\n readonly dark?: SplashScreenModeSpec;\n}\n\nexport interface DeploymentSpec {\n target: DeploymentTarget;\n monitoring: boolean;\n}\n\nexport interface DatabaseSpec {\n provider: DatabaseProvider;\n tier: DatabaseTier;\n}\n\nexport interface StorageSpec {\n provider: StorageProvider;\n buckets: string[];\n}\n\nexport interface AuthzSpec {\n kind: AuthzKind;\n engine: AuthzEngine;\n}\n\nexport interface AuthSignInSpec {\n identifiers: AuthSignInIdentifier[];\n}\n\nexport interface AuthSignUpSpec {\n requiredFields: AuthSignUpField[];\n optionalFields?: AuthSignUpField[];\n signUpPolicy?: AuthSignUpPolicy;\n}\n\nexport interface AuthProfileSpec {\n fields: AuthProfileField[];\n}\n\nexport interface AuthSpec {\n scope: AuthScope;\n provider: AuthProvider;\n authorization: AuthzSpec;\n flow?: AuthFlowConfig;\n signIn?: AuthSignInSpec;\n signUp?: AuthSignUpSpec;\n oauth?: AuthOAuthConfig;\n profile?: AuthProfileSpec;\n}\n\nexport interface NetworkingSpec {\n domain?: string;\n cdn: boolean;\n}\n\nexport interface InfraManifest {\n deployment?: DeploymentSpec;\n auth?: AuthSpec;\n database?: DatabaseSpec;\n storage?: StorageSpec;\n networking?: NetworkingSpec;\n plugins: string[];\n pluginsConfig?: Record<string, unknown>;\n}\n\nexport interface AppManifest {\n metadata: {\n name: string;\n slug: string;\n version: string;\n themeId: string;\n created?: string;\n updated?: string;\n };\n themes: ThemeConfig[];\n activeThemeId: string;\n activeThemeMode?: 'dark' | 'light';\n splashScreen?: SplashScreenSpec;\n infra: InfraManifest;\n navigator: NavigatorSpec;\n screens: Record<string, ScreenSpec>;\n dataSources?: DataSourceRegistry;\n dataBindings?: ComponentDataBindingRegistry;\n settings: {\n apiBaseUrl?: string;\n localization: {\n defaultLocale: string;\n locales: string[];\n };\n authFlow: AuthFlowConfig;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsIA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAGpE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe;IACf,uBAAuB;IACvB,iBAAiB;IACjB,oBAAoB;IACpB,qBAAqB;IACrB,eAAe;IACf,YAAY;IACZ,OAAO;IACP,iBAAiB;IACjB,gBAAgB;IAChB,aAAa;IACb,WAAW;IACX,SAAS;IACT,aAAa;IACb,mBAAmB;IACnB,gBAAgB;IAChB,aAAa;IACb,WAAW;IACX,mBAAmB;IACnB,kBAAkB;IAClB,QAAQ;IACR,iBAAiB;IACjB,SAAS;CACD,CAAC;AAGX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,CAAU,CAAC;AAIxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAU,CAAU,CAAC;AAIxD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAC;AAGvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAG/D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAQ,CAAU,CAAC;AAInD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAGxF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAU,CAAC;AAGrD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAG3D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAU,CAAC;AAGrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAU,CAAU,CAAC;AAIpD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AAGhF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,YAAY,EAAE,qBAAqB,CAAU,CAAC;AAGpF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,wBAAwB;IAC3B,WAAW;IACX,UAAU;IACV,aAAa;IACb,WAAW;CACH,CAAC","sourcesContent":["import type { ColorHarmony } from '@ankhorage/color-theory';\n\nimport type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';\nimport type { ComponentDataBindingRegistry } from './bindings';\nimport type { AppDataManifest, DataSourceRegistry } from './data';\n\nexport interface ThemeModeConfig {\n primaryColor: string;\n harmony: ColorHarmony;\n}\n\nexport interface ThemeConfig {\n id: string;\n name: string;\n light: ThemeModeConfig;\n dark: ThemeModeConfig;\n}\n\nexport type ActionType =\n | 'navigate'\n | 'alert'\n | 'console'\n | 'toggleDarkMode'\n | 'setLanguage'\n | 'search'\n | 'filter';\n\nexport interface NavigateAction {\n type: 'navigate';\n payload: {\n route: string;\n params?: Record<string, number | string>;\n };\n}\n\nexport interface AlertAction {\n type: 'alert';\n payload?: {\n message?: string;\n };\n}\n\nexport interface ConsoleAction {\n type: 'console';\n payload?: Record<string, unknown>;\n}\n\nexport interface ToggleDarkModeAction {\n type: 'toggleDarkMode';\n payload?: never;\n}\n\nexport interface SetLanguageAction {\n type: 'setLanguage';\n payload: {\n locale: string;\n };\n}\n\nexport interface SearchAction {\n type: 'search';\n payload: {\n query: string;\n scope?: string;\n };\n}\n\nexport interface FilterAction {\n type: 'filter';\n payload: {\n filterKey: string;\n filterValue: string;\n };\n}\n\nexport type Action =\n | AlertAction\n | ConsoleAction\n | FilterAction\n | NavigateAction\n | SearchAction\n | SetLanguageAction\n | ToggleDarkModeAction;\n\nexport type ManifestValue =\n | string\n | number\n | boolean\n | null\n | readonly ManifestValue[]\n | { readonly [key: string]: ManifestValue };\n\nexport type ComponentEventPayloadValue = ManifestValue;\n\nexport interface ComponentEventDto<\n TType extends string = string,\n TPayload extends object = Record<string, ComponentEventPayloadValue>,\n> {\n readonly type: TType;\n readonly sourceNodeId: string;\n readonly payload: TPayload;\n}\n\nexport type FormSubmitValues = Record<string, ComponentEventPayloadValue>;\n\nexport type FormSubmitEventDto = ComponentEventDto<\n 'form.submit',\n {\n readonly values: FormSubmitValues;\n }\n>;\n\nexport type ButtonPressEventDto = ComponentEventDto<'button.press', Record<string, never>>;\n\nexport interface CollectionItemPressPayload {\n readonly itemId: string | number;\n readonly item: Record<string, ComponentEventPayloadValue>;\n}\n\nexport type CollectionItemPressEventDto = ComponentEventDto<\n 'collection.itemPress',\n CollectionItemPressPayload\n>;\n\nexport type ComponentEventDtoKind =\n | ButtonPressEventDto['type']\n | CollectionItemPressEventDto['type']\n | FormSubmitEventDto['type'];\n\nexport type KnownComponentEventDto =\n | ButtonPressEventDto\n | CollectionItemPressEventDto\n | FormSubmitEventDto;\n\nexport const NAVIGATOR_TYPES = ['stack', 'tabs', 'drawer'] as const;\nexport type NavigatorType = (typeof NAVIGATOR_TYPES)[number];\n\nexport const APP_CATEGORIES = [\n 'books_reading',\n 'business_productivity',\n 'developer_tools',\n 'education_learning',\n 'entertainment_media',\n 'finance_money',\n 'food_drink',\n 'games',\n 'graphics_design',\n 'health_fitness',\n 'kids_family',\n 'lifestyle',\n 'medical',\n 'music_audio',\n 'navigation_travel',\n 'news_magazines',\n 'photo_video',\n 'reference',\n 'shopping_commerce',\n 'social_community',\n 'sports',\n 'utilities_tools',\n 'weather',\n] as const;\nexport type AppCategory = (typeof APP_CATEGORIES)[number];\n\nexport const DEPLOYMENT_TARGETS = ['minikube'] as const;\nexport type KnownDeploymentTarget = (typeof DEPLOYMENT_TARGETS)[number];\nexport type DeploymentTarget = KnownDeploymentTarget | (string & {});\n\nexport const DATABASE_PROVIDERS = ['supabase'] as const;\nexport type KnownDatabaseProvider = (typeof DATABASE_PROVIDERS)[number];\nexport type DatabaseProvider = KnownDatabaseProvider | (string & {});\n\nexport const DATABASE_TIERS = ['dev', 'prod'] as const;\nexport type DatabaseTier = (typeof DATABASE_TIERS)[number];\n\nexport const STORAGE_PROVIDERS = ['auto', 's3', 'r2'] as const;\nexport type StorageProvider = (typeof STORAGE_PROVIDERS)[number];\n\nexport const STATE_PROVIDERS = ['legend'] as const;\nexport type KnownStateProvider = (typeof STATE_PROVIDERS)[number];\nexport type StateProvider = KnownStateProvider | (string & {});\n\nexport const STATE_PERSISTENCE_MODES = ['none', 'local', 'secure', 'database'] as const;\nexport type StatePersistenceMode = (typeof STATE_PERSISTENCE_MODES)[number];\n\nexport const AUTHZ_KINDS = ['RBAC', 'ABAC'] as const;\nexport type AuthzKind = (typeof AUTHZ_KINDS)[number];\n\nexport const AUTHZ_ENGINES = ['cerbos', 'native'] as const;\nexport type AuthzEngine = (typeof AUTHZ_ENGINES)[number];\n\nexport const AUTH_SCOPES = ['global', 'none', 'integrated'] as const;\nexport type AuthScope = (typeof AUTH_SCOPES)[number];\n\nexport const AUTH_PROVIDERS = ['supabase'] as const;\nexport type KnownAuthProvider = (typeof AUTH_PROVIDERS)[number];\nexport type AuthProvider = KnownAuthProvider | (string & {});\n\nexport const AUTH_SIGN_IN_IDENTIFIERS = ['email', 'username', 'phone'] as const;\nexport type AuthSignInIdentifier = AuthIdentifierKind;\n\nexport const AUTH_SIGN_UP_POLICIES = ['autoSignIn', 'requireVerification'] as const;\nexport type AuthSignUpPolicy = (typeof AUTH_SIGN_UP_POLICIES)[number];\n\nexport const AUTH_PROFILE_FIELDS = [\n ...AUTH_SIGN_IN_IDENTIFIERS,\n 'firstName',\n 'lastName',\n 'displayName',\n 'avatarUrl',\n] as const;\nexport type KnownAuthProfileField = (typeof AUTH_PROFILE_FIELDS)[number];\nexport type AuthProfileField = KnownAuthProfileField | (string & {});\n\nexport interface IconSpec {\n name: string;\n provider?: string;\n size?: number | string;\n color?: string;\n}\n\nexport interface UiNode {\n id: string;\n type: string;\n alias?: string;\n props?: Record<string, unknown>;\n children?: UiNode[];\n style?: Record<string, number | string>;\n}\n\nexport interface ScreenSpec {\n id: string;\n name: string;\n title?: string;\n description?: string;\n root: UiNode;\n}\n\nexport interface NavigatorSpec {\n type: NavigatorType;\n initialRouteName?: string;\n routes: RouteDefinition[];\n options?: Record<string, unknown>;\n}\n\nexport interface RouteDefinition {\n name: string;\n path?: string;\n label?: string;\n icon?: IconSpec;\n hideInTabBar?: boolean;\n guards?: string[];\n screenId?: string;\n navigator?: NavigatorSpec;\n}\n\nexport type SplashScreenResizeMode = 'contain' | 'cover' | 'native';\n\nexport interface SplashScreenAssetSpec {\n readonly image?: string;\n readonly imageWidth?: number;\n readonly resizeMode?: SplashScreenResizeMode;\n}\n\nexport interface SplashScreenModeSpec extends SplashScreenAssetSpec {\n readonly backgroundColor?: string;\n}\n\nexport interface SplashScreenSpec extends SplashScreenModeSpec {\n readonly dark?: SplashScreenModeSpec;\n}\n\nexport interface DeploymentSpec {\n target: DeploymentTarget;\n monitoring: boolean;\n}\n\nexport interface DatabaseSpec {\n provider: DatabaseProvider;\n tier: DatabaseTier;\n}\n\nexport interface StorageSpec {\n provider: StorageProvider;\n buckets: string[];\n}\n\nexport interface StateSpec {\n readonly provider: StateProvider;\n readonly persistence?: StatePersistenceMode;\n}\n\nexport interface AuthzSpec {\n kind: AuthzKind;\n engine: AuthzEngine;\n}\n\nexport interface AuthSignInSpec {\n identifiers: AuthSignInIdentifier[];\n}\n\nexport interface AuthSignUpSpec {\n requiredFields: AuthSignUpField[];\n optionalFields?: AuthSignUpField[];\n signUpPolicy?: AuthSignUpPolicy;\n}\n\nexport interface AuthProfileSpec {\n fields: AuthProfileField[];\n}\n\nexport interface AuthSpec {\n scope: AuthScope;\n provider: AuthProvider;\n authorization: AuthzSpec;\n flow?: AuthFlowConfig;\n signIn?: AuthSignInSpec;\n signUp?: AuthSignUpSpec;\n oauth?: AuthOAuthConfig;\n profile?: AuthProfileSpec;\n}\n\nexport interface NetworkingSpec {\n domain?: string;\n cdn: boolean;\n}\n\nexport interface InfraManifest {\n deployment?: DeploymentSpec;\n auth?: AuthSpec;\n database?: DatabaseSpec;\n storage?: StorageSpec;\n state?: StateSpec;\n networking?: NetworkingSpec;\n plugins: string[];\n pluginsConfig?: Record<string, unknown>;\n}\n\nexport interface AppManifest {\n metadata: {\n name: string;\n slug: string;\n version: string;\n themeId: string;\n created?: string;\n updated?: string;\n };\n themes: ThemeConfig[];\n activeThemeId: string;\n activeThemeMode?: 'dark' | 'light';\n splashScreen?: SplashScreenSpec;\n infra: InfraManifest;\n navigator: NavigatorSpec;\n screens: Record<string, ScreenSpec>;\n data?: AppDataManifest;\n dataSources?: DataSourceRegistry;\n dataBindings?: ComponentDataBindingRegistry;\n settings: {\n apiBaseUrl?: string;\n localization: {\n defaultLocale: string;\n locales: string[];\n };\n authFlow: AuthFlowConfig;\n };\n}\n"]}
|
package/package.json
CHANGED
package/src/contracts.test.ts
CHANGED
|
@@ -26,6 +26,9 @@ import {
|
|
|
26
26
|
type ImageAssetSource,
|
|
27
27
|
NAVIGATOR_TYPES,
|
|
28
28
|
type SplashScreenSpec,
|
|
29
|
+
STATE_PERSISTENCE_MODES,
|
|
30
|
+
STATE_PROVIDERS,
|
|
31
|
+
type StateSpec,
|
|
29
32
|
type StoragePublicUrlResult,
|
|
30
33
|
type StorageResult,
|
|
31
34
|
type StorageUploadResult,
|
|
@@ -82,6 +85,8 @@ describe('contracts', () => {
|
|
|
82
85
|
]);
|
|
83
86
|
expect(DEPLOYMENT_TARGETS).toEqual(['minikube']);
|
|
84
87
|
expect(AUTH_PROVIDERS).toEqual(['supabase']);
|
|
88
|
+
expect(STATE_PROVIDERS).toEqual(['legend']);
|
|
89
|
+
expect(STATE_PERSISTENCE_MODES).toEqual(['none', 'local', 'secure', 'database']);
|
|
85
90
|
});
|
|
86
91
|
|
|
87
92
|
it('exports the app category union for template packages', () => {
|
|
@@ -126,6 +131,26 @@ describe('contracts', () => {
|
|
|
126
131
|
expect(JSON.parse(JSON.stringify(manifest))).toEqual({ splashScreen });
|
|
127
132
|
});
|
|
128
133
|
|
|
134
|
+
it('accepts provider-neutral state infra selection on app manifests', () => {
|
|
135
|
+
const state: StateSpec = {
|
|
136
|
+
provider: 'legend',
|
|
137
|
+
persistence: 'none',
|
|
138
|
+
};
|
|
139
|
+
const manifest: Pick<AppManifest, 'infra'> = {
|
|
140
|
+
infra: {
|
|
141
|
+
state,
|
|
142
|
+
plugins: [],
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
expect(JSON.parse(JSON.stringify(manifest))).toEqual({
|
|
147
|
+
infra: {
|
|
148
|
+
state,
|
|
149
|
+
plugins: [],
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
129
154
|
it('ThemeModeConfig.harmony accepts all ColorHarmony values', () => {
|
|
130
155
|
for (const harmony of COLOR_HARMONIES) {
|
|
131
156
|
const config: ThemeModeConfig = { primaryColor: '#ff0000', harmony };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AppApiDefinition,
|
|
5
|
+
AppApiEndpointDefinition,
|
|
6
|
+
AppApiManifest,
|
|
7
|
+
AppGeneratedApiDefinition,
|
|
8
|
+
} from './apis';
|
|
9
|
+
import { APP_API_ENDPOINT_INTENTS, APP_API_ENDPOINT_METHODS, APP_API_KINDS } from './apis';
|
|
10
|
+
|
|
11
|
+
const crudEndpoints = [
|
|
12
|
+
{
|
|
13
|
+
id: 'players.list',
|
|
14
|
+
method: 'GET',
|
|
15
|
+
path: '/',
|
|
16
|
+
intent: 'list',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'players.create',
|
|
20
|
+
method: 'POST',
|
|
21
|
+
path: '/',
|
|
22
|
+
intent: 'create',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'players.read',
|
|
26
|
+
method: 'GET',
|
|
27
|
+
path: '/{id}',
|
|
28
|
+
intent: 'read',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'players.update',
|
|
32
|
+
method: 'PATCH',
|
|
33
|
+
path: '/{id}',
|
|
34
|
+
intent: 'update',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'players.delete',
|
|
38
|
+
method: 'DELETE',
|
|
39
|
+
path: '/{id}',
|
|
40
|
+
intent: 'delete',
|
|
41
|
+
},
|
|
42
|
+
] satisfies readonly AppApiEndpointDefinition[];
|
|
43
|
+
|
|
44
|
+
describe('app API authoring contracts', () => {
|
|
45
|
+
test('exports stable API authoring constants', () => {
|
|
46
|
+
expect(APP_API_KINDS).toEqual(['external', 'generated']);
|
|
47
|
+
expect(APP_API_ENDPOINT_METHODS).toEqual([
|
|
48
|
+
'DELETE',
|
|
49
|
+
'GET',
|
|
50
|
+
'HEAD',
|
|
51
|
+
'OPTIONS',
|
|
52
|
+
'PATCH',
|
|
53
|
+
'POST',
|
|
54
|
+
'PUT',
|
|
55
|
+
]);
|
|
56
|
+
expect(APP_API_ENDPOINT_INTENTS).toEqual([
|
|
57
|
+
'create',
|
|
58
|
+
'custom',
|
|
59
|
+
'delete',
|
|
60
|
+
'list',
|
|
61
|
+
'read',
|
|
62
|
+
'update',
|
|
63
|
+
]);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('serializes generated APIs with a CRUD preset and explicit custom endpoints', () => {
|
|
67
|
+
const generatedApi: AppGeneratedApiDefinition = {
|
|
68
|
+
id: 'players',
|
|
69
|
+
kind: 'generated',
|
|
70
|
+
label: 'Players',
|
|
71
|
+
basePath: '/api/players',
|
|
72
|
+
preset: 'crud',
|
|
73
|
+
resource: {
|
|
74
|
+
kind: 'collection',
|
|
75
|
+
collection: {
|
|
76
|
+
name: 'players',
|
|
77
|
+
primaryKey: 'id',
|
|
78
|
+
fields: [
|
|
79
|
+
{ name: 'id', type: 'uuid', required: true },
|
|
80
|
+
{ name: 'name', type: 'text', required: true },
|
|
81
|
+
{ name: 'score', type: 'number' },
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
seed: [
|
|
85
|
+
{
|
|
86
|
+
id: 'player-1',
|
|
87
|
+
name: 'Ada',
|
|
88
|
+
score: 42,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
endpoints: [
|
|
93
|
+
...crudEndpoints,
|
|
94
|
+
{
|
|
95
|
+
id: 'players.leaderboard',
|
|
96
|
+
method: 'GET',
|
|
97
|
+
path: '/leaderboard',
|
|
98
|
+
intent: 'custom',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
const manifest: AppApiManifest = {
|
|
103
|
+
apis: {
|
|
104
|
+
players: generatedApi,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
expect(JSON.parse(JSON.stringify(manifest))).toEqual({
|
|
109
|
+
apis: {
|
|
110
|
+
players: generatedApi,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
expect(manifest.apis?.players?.endpoints.map((endpoint) => endpoint.path)).toEqual([
|
|
114
|
+
'/',
|
|
115
|
+
'/',
|
|
116
|
+
'/{id}',
|
|
117
|
+
'/{id}',
|
|
118
|
+
'/{id}',
|
|
119
|
+
'/leaderboard',
|
|
120
|
+
]);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('serializes external APIs without generated resource definitions', () => {
|
|
124
|
+
const externalApi: AppApiDefinition = {
|
|
125
|
+
id: 'stripe',
|
|
126
|
+
kind: 'external',
|
|
127
|
+
label: 'Stripe',
|
|
128
|
+
basePath: '/api/stripe',
|
|
129
|
+
baseUrl: 'https://api.stripe.com',
|
|
130
|
+
endpoints: [
|
|
131
|
+
{
|
|
132
|
+
id: 'stripe.createCheckoutSession',
|
|
133
|
+
method: 'POST',
|
|
134
|
+
path: '/checkout/sessions',
|
|
135
|
+
intent: 'custom',
|
|
136
|
+
auth: {
|
|
137
|
+
required: true,
|
|
138
|
+
permissions: ['payments:create'],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
expect(JSON.parse(JSON.stringify(externalApi))).toEqual(externalApi);
|
|
145
|
+
});
|
|
146
|
+
});
|
package/src/data/apis.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { DbCollectionDefinition } from '../db';
|
|
2
|
+
import type { DataOperationRequest, DataOperationResponse } from './operations';
|
|
3
|
+
import type { DataContractValue } from './values';
|
|
4
|
+
|
|
5
|
+
export const APP_API_KINDS = ['external', 'generated'] as const;
|
|
6
|
+
export type AppApiKind = (typeof APP_API_KINDS)[number];
|
|
7
|
+
|
|
8
|
+
export const APP_API_GENERATED_PRESETS = ['crud'] as const;
|
|
9
|
+
export type AppApiGeneratedPreset = (typeof APP_API_GENERATED_PRESETS)[number];
|
|
10
|
+
|
|
11
|
+
export const APP_API_ENDPOINT_METHODS = [
|
|
12
|
+
'DELETE',
|
|
13
|
+
'GET',
|
|
14
|
+
'HEAD',
|
|
15
|
+
'OPTIONS',
|
|
16
|
+
'PATCH',
|
|
17
|
+
'POST',
|
|
18
|
+
'PUT',
|
|
19
|
+
] as const;
|
|
20
|
+
export type AppApiEndpointMethod = (typeof APP_API_ENDPOINT_METHODS)[number];
|
|
21
|
+
|
|
22
|
+
export const APP_API_ENDPOINT_INTENTS = [
|
|
23
|
+
'create',
|
|
24
|
+
'custom',
|
|
25
|
+
'delete',
|
|
26
|
+
'list',
|
|
27
|
+
'read',
|
|
28
|
+
'update',
|
|
29
|
+
] as const;
|
|
30
|
+
export type AppApiEndpointIntent = (typeof APP_API_ENDPOINT_INTENTS)[number];
|
|
31
|
+
|
|
32
|
+
export type AppApiId = string;
|
|
33
|
+
export type AppApiEndpointId = string;
|
|
34
|
+
export type AppApiSeedRecord = Readonly<Record<string, DataContractValue>>;
|
|
35
|
+
|
|
36
|
+
export interface AppApiAuthRequirement {
|
|
37
|
+
readonly required?: boolean;
|
|
38
|
+
readonly roles?: readonly string[];
|
|
39
|
+
readonly permissions?: readonly string[];
|
|
40
|
+
readonly policy?: string;
|
|
41
|
+
readonly metadata?: DataContractValue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface AppApiCollectionResourceDefinition {
|
|
45
|
+
readonly kind: 'collection';
|
|
46
|
+
readonly collection: DbCollectionDefinition;
|
|
47
|
+
readonly seed?: readonly AppApiSeedRecord[];
|
|
48
|
+
readonly metadata?: DataContractValue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type AppApiResourceDefinition = AppApiCollectionResourceDefinition;
|
|
52
|
+
|
|
53
|
+
export interface AppApiEndpointDefinition {
|
|
54
|
+
readonly id: AppApiEndpointId;
|
|
55
|
+
readonly label?: string;
|
|
56
|
+
readonly description?: string;
|
|
57
|
+
readonly method: AppApiEndpointMethod;
|
|
58
|
+
/**
|
|
59
|
+
* Path relative to the API base path. Use `/` for the base collection endpoint.
|
|
60
|
+
*/
|
|
61
|
+
readonly path: string;
|
|
62
|
+
readonly intent?: AppApiEndpointIntent;
|
|
63
|
+
readonly request?: DataOperationRequest;
|
|
64
|
+
readonly response?: DataOperationResponse;
|
|
65
|
+
readonly auth?: AppApiAuthRequirement;
|
|
66
|
+
readonly metadata?: DataContractValue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface AppApiDefinitionBase {
|
|
70
|
+
readonly id: AppApiId;
|
|
71
|
+
readonly kind: AppApiKind;
|
|
72
|
+
readonly label?: string;
|
|
73
|
+
readonly description?: string;
|
|
74
|
+
readonly basePath: string;
|
|
75
|
+
readonly endpoints: readonly AppApiEndpointDefinition[];
|
|
76
|
+
readonly auth?: AppApiAuthRequirement;
|
|
77
|
+
readonly metadata?: DataContractValue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface AppGeneratedApiDefinition extends AppApiDefinitionBase {
|
|
81
|
+
readonly kind: 'generated';
|
|
82
|
+
/**
|
|
83
|
+
* Preset used by authoring tools to seed standard endpoints. The resulting
|
|
84
|
+
* serialized API still stores concrete `endpoints[]` so custom endpoints can
|
|
85
|
+
* live next to generated CRUD operations.
|
|
86
|
+
*/
|
|
87
|
+
readonly preset?: AppApiGeneratedPreset;
|
|
88
|
+
readonly resource?: AppApiResourceDefinition;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface AppExternalApiDefinition extends AppApiDefinitionBase {
|
|
92
|
+
readonly kind: 'external';
|
|
93
|
+
readonly baseUrl?: string;
|
|
94
|
+
readonly openApiUrl?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type AppApiDefinition = AppExternalApiDefinition | AppGeneratedApiDefinition;
|
|
98
|
+
|
|
99
|
+
export type AppApiRegistry = Readonly<Record<AppApiId, AppApiDefinition>>;
|
|
100
|
+
|
|
101
|
+
export interface AppDataManifest {
|
|
102
|
+
readonly apis?: AppApiRegistry;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type AppApiManifest = AppDataManifest;
|
package/src/data/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ColorHarmony } from '@ankhorage/color-theory';
|
|
|
2
2
|
|
|
3
3
|
import type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';
|
|
4
4
|
import type { ComponentDataBindingRegistry } from './bindings';
|
|
5
|
-
import type { DataSourceRegistry } from './data';
|
|
5
|
+
import type { AppDataManifest, DataSourceRegistry } from './data';
|
|
6
6
|
|
|
7
7
|
export interface ThemeModeConfig {
|
|
8
8
|
primaryColor: string;
|
|
@@ -176,6 +176,13 @@ export type DatabaseTier = (typeof DATABASE_TIERS)[number];
|
|
|
176
176
|
export const STORAGE_PROVIDERS = ['auto', 's3', 'r2'] as const;
|
|
177
177
|
export type StorageProvider = (typeof STORAGE_PROVIDERS)[number];
|
|
178
178
|
|
|
179
|
+
export const STATE_PROVIDERS = ['legend'] as const;
|
|
180
|
+
export type KnownStateProvider = (typeof STATE_PROVIDERS)[number];
|
|
181
|
+
export type StateProvider = KnownStateProvider | (string & {});
|
|
182
|
+
|
|
183
|
+
export const STATE_PERSISTENCE_MODES = ['none', 'local', 'secure', 'database'] as const;
|
|
184
|
+
export type StatePersistenceMode = (typeof STATE_PERSISTENCE_MODES)[number];
|
|
185
|
+
|
|
179
186
|
export const AUTHZ_KINDS = ['RBAC', 'ABAC'] as const;
|
|
180
187
|
export type AuthzKind = (typeof AUTHZ_KINDS)[number];
|
|
181
188
|
|
|
@@ -278,6 +285,11 @@ export interface StorageSpec {
|
|
|
278
285
|
buckets: string[];
|
|
279
286
|
}
|
|
280
287
|
|
|
288
|
+
export interface StateSpec {
|
|
289
|
+
readonly provider: StateProvider;
|
|
290
|
+
readonly persistence?: StatePersistenceMode;
|
|
291
|
+
}
|
|
292
|
+
|
|
281
293
|
export interface AuthzSpec {
|
|
282
294
|
kind: AuthzKind;
|
|
283
295
|
engine: AuthzEngine;
|
|
@@ -318,6 +330,7 @@ export interface InfraManifest {
|
|
|
318
330
|
auth?: AuthSpec;
|
|
319
331
|
database?: DatabaseSpec;
|
|
320
332
|
storage?: StorageSpec;
|
|
333
|
+
state?: StateSpec;
|
|
321
334
|
networking?: NetworkingSpec;
|
|
322
335
|
plugins: string[];
|
|
323
336
|
pluginsConfig?: Record<string, unknown>;
|
|
@@ -339,6 +352,7 @@ export interface AppManifest {
|
|
|
339
352
|
infra: InfraManifest;
|
|
340
353
|
navigator: NavigatorSpec;
|
|
341
354
|
screens: Record<string, ScreenSpec>;
|
|
355
|
+
data?: AppDataManifest;
|
|
342
356
|
dataSources?: DataSourceRegistry;
|
|
343
357
|
dataBindings?: ComponentDataBindingRegistry;
|
|
344
358
|
settings: {
|