@ankhorage/contracts 7.2.0 → 7.4.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ankhorage/contracts
2
2
 
3
+ ## 7.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 06223da: Add provider-neutral object listing and readable URL resolution capabilities for app-authoring media storage adapters.
8
+
9
+ ## 7.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 09d62a0: Add the canonical app-authoring media catalog, stable media references, provider-neutral storage/URL/bundled media sources, and manifest validation that rejects transient local media URLs.
14
+
3
15
  ## 7.2.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # CONTRACTS
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v7.0.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v7.3.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
7
7
 
8
8
  Serializable app, action, theme, auth, and secret-store contracts for Ankhorage.
9
9
 
@@ -0,0 +1,3 @@
1
+ import { type MediaManifest } from '../media';
2
+ export declare function isMediaManifest(value: unknown): value is MediaManifest;
3
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/appManifest/media.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAKlB,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAMtE"}
@@ -0,0 +1,75 @@
1
+ import { MEDIA_ASSET_KINDS, } from '../media';
2
+ import { isOptionalString, isRecord } from './shared';
3
+ const MEDIA_ASSET_KIND_SET = new Set(MEDIA_ASSET_KINDS);
4
+ export function isMediaManifest(value) {
5
+ if (!isRecord(value) || !hasOnlyKeys(value, ['assets']) || !isRecord(value.assets))
6
+ return false;
7
+ return Object.entries(value.assets).every(([assetId, asset]) => isMediaAsset(asset) && asset.id === assetId);
8
+ }
9
+ function isMediaAsset(value) {
10
+ return (isRecord(value) &&
11
+ hasOnlyKeys(value, ['id', 'name', 'kind', 'source', 'contentType', 'metadata']) &&
12
+ isNonEmptyString(value.id) &&
13
+ isNonEmptyString(value.name) &&
14
+ typeof value.kind === 'string' &&
15
+ MEDIA_ASSET_KIND_SET.has(value.kind) &&
16
+ isMediaAssetSource(value.source) &&
17
+ isOptionalString(value.contentType) &&
18
+ (value.metadata === undefined || isMediaAssetMetadata(value.metadata)));
19
+ }
20
+ function isMediaAssetSource(value) {
21
+ if (!isRecord(value) || typeof value.kind !== 'string')
22
+ return false;
23
+ if (value.kind === 'storage') {
24
+ return (hasOnlyKeys(value, ['kind', 'storageId', 'bucket', 'path']) &&
25
+ isOptionalString(value.storageId) &&
26
+ isNonEmptyString(value.bucket) &&
27
+ isNonEmptyString(value.path));
28
+ }
29
+ if (value.kind === 'url') {
30
+ return hasOnlyKeys(value, ['kind', 'url']) && isStableRemoteUrl(value.url);
31
+ }
32
+ return (value.kind === 'bundled' && hasOnlyKeys(value, ['kind', 'path']) && isBundledPath(value.path));
33
+ }
34
+ function isMediaAssetMetadata(value) {
35
+ return (isRecord(value) &&
36
+ hasOnlyKeys(value, [
37
+ 'originalFileName',
38
+ 'sizeBytes',
39
+ 'createdAt',
40
+ 'width',
41
+ 'height',
42
+ 'durationMs',
43
+ ]) &&
44
+ isOptionalString(value.originalFileName) &&
45
+ isOptionalString(value.createdAt) &&
46
+ isOptionalFiniteNonNegativeNumber(value.sizeBytes) &&
47
+ isOptionalFinitePositiveNumber(value.width) &&
48
+ isOptionalFinitePositiveNumber(value.height) &&
49
+ isOptionalFiniteNonNegativeNumber(value.durationMs));
50
+ }
51
+ function isStableRemoteUrl(value) {
52
+ return typeof value === 'string' && /^https?:\/\//iu.test(value.trim());
53
+ }
54
+ function isBundledPath(value) {
55
+ if (!isNonEmptyString(value))
56
+ return false;
57
+ const path = value.trim();
58
+ if (path.startsWith('/') || /^[a-z][a-z0-9+.-]*:/iu.test(path))
59
+ return false;
60
+ return !path.split('/').includes('..');
61
+ }
62
+ function isNonEmptyString(value) {
63
+ return typeof value === 'string' && value.trim().length > 0;
64
+ }
65
+ function isOptionalFiniteNonNegativeNumber(value) {
66
+ return value === undefined || (typeof value === 'number' && Number.isFinite(value) && value >= 0);
67
+ }
68
+ function isOptionalFinitePositiveNumber(value) {
69
+ return value === undefined || (typeof value === 'number' && Number.isFinite(value) && value > 0);
70
+ }
71
+ function hasOnlyKeys(value, allowedKeys) {
72
+ const allowed = new Set(allowedKeys);
73
+ return Object.keys(value).every((key) => allowed.has(key));
74
+ }
75
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/appManifest/media.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n MEDIA_ASSET_KINDS,\n type MediaAsset,\n type MediaAssetMetadata,\n type MediaAssetSource,\n type MediaManifest,\n} from '../media';\nimport { isOptionalString, isRecord } from './shared';\n\nconst MEDIA_ASSET_KIND_SET = new Set<string>(MEDIA_ASSET_KINDS);\n\nexport function isMediaManifest(value: unknown): value is MediaManifest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['assets']) || !isRecord(value.assets)) return false;\n\n return Object.entries(value.assets).every(\n ([assetId, asset]) => isMediaAsset(asset) && asset.id === assetId,\n );\n}\n\nfunction isMediaAsset(value: unknown): value is MediaAsset {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['id', 'name', 'kind', 'source', 'contentType', 'metadata']) &&\n isNonEmptyString(value.id) &&\n isNonEmptyString(value.name) &&\n typeof value.kind === 'string' &&\n MEDIA_ASSET_KIND_SET.has(value.kind) &&\n isMediaAssetSource(value.source) &&\n isOptionalString(value.contentType) &&\n (value.metadata === undefined || isMediaAssetMetadata(value.metadata))\n );\n}\n\nfunction isMediaAssetSource(value: unknown): value is MediaAssetSource {\n if (!isRecord(value) || typeof value.kind !== 'string') return false;\n\n if (value.kind === 'storage') {\n return (\n hasOnlyKeys(value, ['kind', 'storageId', 'bucket', 'path']) &&\n isOptionalString(value.storageId) &&\n isNonEmptyString(value.bucket) &&\n isNonEmptyString(value.path)\n );\n }\n\n if (value.kind === 'url') {\n return hasOnlyKeys(value, ['kind', 'url']) && isStableRemoteUrl(value.url);\n }\n\n return (\n value.kind === 'bundled' && hasOnlyKeys(value, ['kind', 'path']) && isBundledPath(value.path)\n );\n}\n\nfunction isMediaAssetMetadata(value: unknown): value is MediaAssetMetadata {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, [\n 'originalFileName',\n 'sizeBytes',\n 'createdAt',\n 'width',\n 'height',\n 'durationMs',\n ]) &&\n isOptionalString(value.originalFileName) &&\n isOptionalString(value.createdAt) &&\n isOptionalFiniteNonNegativeNumber(value.sizeBytes) &&\n isOptionalFinitePositiveNumber(value.width) &&\n isOptionalFinitePositiveNumber(value.height) &&\n isOptionalFiniteNonNegativeNumber(value.durationMs)\n );\n}\n\nfunction isStableRemoteUrl(value: unknown): boolean {\n return typeof value === 'string' && /^https?:\\/\\//iu.test(value.trim());\n}\n\nfunction isBundledPath(value: unknown): boolean {\n if (!isNonEmptyString(value)) return false;\n const path = value.trim();\n if (path.startsWith('/') || /^[a-z][a-z0-9+.-]*:/iu.test(path)) return false;\n return !path.split('/').includes('..');\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction isOptionalFiniteNonNegativeNumber(value: unknown): boolean {\n return value === undefined || (typeof value === 'number' && Number.isFinite(value) && value >= 0);\n}\n\nfunction isOptionalFinitePositiveNumber(value: unknown): boolean {\n return value === undefined || (typeof value === 'number' && Number.isFinite(value) && value > 0);\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, allowedKeys: readonly string[]): boolean {\n const allowed = new Set(allowedKeys);\n return Object.keys(value).every((key) => allowed.has(key));\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"appManifest.d.ts","sourceRoot":"","sources":["../src/appManifest.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAiBrD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAIvE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAkBlE"}
1
+ {"version":3,"file":"appManifest.d.ts","sourceRoot":"","sources":["../src/appManifest.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAkBrD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAIvE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAmBlE"}
@@ -2,6 +2,7 @@ import { isComponentDataBindingRegistry } from './appManifest/bindings';
2
2
  import { isDataSourceRegistry } from './appManifest/dataSources';
3
3
  import { isGeneratedApiRegistry } from './appManifest/generatedApis';
4
4
  import { isInfraManifest } from './appManifest/infra';
5
+ import { isMediaManifest } from './appManifest/media';
5
6
  import { isManifestMetadata, isNavigatorSpec, isScreenRegistry, isSplashScreenSpec, isThemeConfig, } from './appManifest/screens';
6
7
  import { isOptionalString, isRecord, isStringArray } from './appManifest/shared';
7
8
  const APP_MANIFEST_KEY_POLICY = {
@@ -10,6 +11,7 @@ const APP_MANIFEST_KEY_POLICY = {
10
11
  activeThemeId: 'required',
11
12
  activeThemeMode: 'optional',
12
13
  splashScreen: 'optional',
14
+ media: 'optional',
13
15
  infra: 'required',
14
16
  navigator: 'required',
15
17
  screens: 'required',
@@ -40,6 +42,7 @@ export function isAppManifest(value) {
40
42
  typeof value.activeThemeId === 'string' &&
41
43
  isActiveThemeMode(value.activeThemeMode) &&
42
44
  (value.splashScreen === undefined || isSplashScreenSpec(value.splashScreen)) &&
45
+ (value.media === undefined || isMediaManifest(value.media)) &&
43
46
  isInfraManifest(value.infra) &&
44
47
  isNavigatorSpec(value.navigator) &&
45
48
  isScreenRegistry(value.screens) &&
@@ -1 +1 @@
1
- {"version":3,"file":"appManifest.js","sourceRoot":"","sources":["../src/appManifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { isComponentDataBindingRegistry } from './appManifest/bindings';\nimport { isDataSourceRegistry } from './appManifest/dataSources';\nimport { isGeneratedApiRegistry } from './appManifest/generatedApis';\nimport { isInfraManifest } from './appManifest/infra';\nimport {\n isManifestMetadata,\n isNavigatorSpec,\n isScreenRegistry,\n isSplashScreenSpec,\n isThemeConfig,\n} from './appManifest/screens';\nimport { isOptionalString, isRecord, isStringArray } from './appManifest/shared';\nimport type { AppManifest } from './types';\n\nexport type AppManifestParseResult =\n | { readonly ok: true; readonly manifest: AppManifest }\n | { readonly ok: false; readonly message: string };\n\nconst APP_MANIFEST_KEY_POLICY = {\n metadata: 'required',\n themes: 'required',\n activeThemeId: 'required',\n activeThemeMode: 'optional',\n splashScreen: 'optional',\n infra: 'required',\n navigator: 'required',\n screens: 'required',\n generatedApis: 'optional',\n dataSources: 'optional',\n dataBindings: 'optional',\n settings: 'required',\n} as const satisfies Record<keyof AppManifest, 'optional' | 'required'>;\n\n/**\n * Parse unknown JSON-compatible input at the canonical AppManifest boundary.\n *\n * Contracts owns structural manifest validation. Consumers may add semantic\n * diagnostics after this parser succeeds, but should not reconstruct the\n * AppManifest shape in their own packages.\n */\nexport function parseAppManifest(value: unknown): AppManifestParseResult {\n return isAppManifest(value)\n ? { ok: true, manifest: value }\n : { ok: false, message: 'Value is not a canonical AppManifest.' };\n}\n\n/** Return whether an unknown value satisfies the canonical AppManifest shape. */\nexport function isAppManifest(value: unknown): value is AppManifest {\n return (\n isRecord(value) &&\n hasRequiredManifestKeys(value) &&\n isManifestMetadata(value.metadata) &&\n Array.isArray(value.themes) &&\n value.themes.every(isThemeConfig) &&\n typeof value.activeThemeId === 'string' &&\n isActiveThemeMode(value.activeThemeMode) &&\n (value.splashScreen === undefined || isSplashScreenSpec(value.splashScreen)) &&\n isInfraManifest(value.infra) &&\n isNavigatorSpec(value.navigator) &&\n isScreenRegistry(value.screens) &&\n (value.generatedApis === undefined || isGeneratedApiRegistry(value.generatedApis)) &&\n (value.dataSources === undefined || isDataSourceRegistry(value.dataSources)) &&\n (value.dataBindings === undefined || isComponentDataBindingRegistry(value.dataBindings)) &&\n isAppSettings(value.settings)\n );\n}\n\nfunction hasRequiredManifestKeys(value: Record<string, unknown>): boolean {\n return Object.entries(APP_MANIFEST_KEY_POLICY).every(\n ([key, policy]) => policy === 'optional' || key in value,\n );\n}\n\nfunction isActiveThemeMode(value: unknown): boolean {\n return value === undefined || value === 'dark' || value === 'light';\n}\n\nfunction isAppSettings(value: unknown): boolean {\n return (\n isRecord(value) &&\n isRecord(value.localization) &&\n typeof value.localization.defaultLocale === 'string' &&\n isStringArray(value.localization.locales) &&\n isOptionalString(value.apiBaseUrl)\n );\n}\n"]}
1
+ {"version":3,"file":"appManifest.js","sourceRoot":"","sources":["../src/appManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAOjF,MAAM,uBAAuB,GAAG;IAC9B,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,UAAU;IAClB,aAAa,EAAE,UAAU;IACzB,eAAe,EAAE,UAAU;IAC3B,YAAY,EAAE,UAAU;IACxB,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;IACjB,SAAS,EAAE,UAAU;IACrB,OAAO,EAAE,UAAU;IACnB,aAAa,EAAE,UAAU;IACzB,WAAW,EAAE,UAAU;IACvB,YAAY,EAAE,UAAU;IACxB,QAAQ,EAAE,UAAU;CACiD,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,aAAa,CAAC,KAAK,CAAC;QACzB,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC/B,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,uCAAuC,EAAE,CAAC;AACtE,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,uBAAuB,CAAC,KAAK,CAAC;QAC9B,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC;QAClC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QACjC,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ;QACvC,iBAAiB,CAAC,KAAK,CAAC,eAAe,CAAC;QACxC,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5E,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3D,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC;QAC5B,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC;QAChC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC;QAC/B,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,sBAAsB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAClF,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,oBAAoB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC5E,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,8BAA8B,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxF,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC9B,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,KAA8B;IAC7D,OAAO,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,KAAK,CAClD,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,KAAK,UAAU,IAAI,GAAG,IAAI,KAAK,CACzD,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,CAAC;AACtE,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC;QAC5B,OAAO,KAAK,CAAC,YAAY,CAAC,aAAa,KAAK,QAAQ;QACpD,aAAa,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC;QACzC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CACnC,CAAC;AACJ,CAAC","sourcesContent":["import { isComponentDataBindingRegistry } from './appManifest/bindings';\nimport { isDataSourceRegistry } from './appManifest/dataSources';\nimport { isGeneratedApiRegistry } from './appManifest/generatedApis';\nimport { isInfraManifest } from './appManifest/infra';\nimport { isMediaManifest } from './appManifest/media';\nimport {\n isManifestMetadata,\n isNavigatorSpec,\n isScreenRegistry,\n isSplashScreenSpec,\n isThemeConfig,\n} from './appManifest/screens';\nimport { isOptionalString, isRecord, isStringArray } from './appManifest/shared';\nimport type { AppManifest } from './types';\n\nexport type AppManifestParseResult =\n | { readonly ok: true; readonly manifest: AppManifest }\n | { readonly ok: false; readonly message: string };\n\nconst APP_MANIFEST_KEY_POLICY = {\n metadata: 'required',\n themes: 'required',\n activeThemeId: 'required',\n activeThemeMode: 'optional',\n splashScreen: 'optional',\n media: 'optional',\n infra: 'required',\n navigator: 'required',\n screens: 'required',\n generatedApis: 'optional',\n dataSources: 'optional',\n dataBindings: 'optional',\n settings: 'required',\n} as const satisfies Record<keyof AppManifest, 'optional' | 'required'>;\n\n/**\n * Parse unknown JSON-compatible input at the canonical AppManifest boundary.\n *\n * Contracts owns structural manifest validation. Consumers may add semantic\n * diagnostics after this parser succeeds, but should not reconstruct the\n * AppManifest shape in their own packages.\n */\nexport function parseAppManifest(value: unknown): AppManifestParseResult {\n return isAppManifest(value)\n ? { ok: true, manifest: value }\n : { ok: false, message: 'Value is not a canonical AppManifest.' };\n}\n\n/** Return whether an unknown value satisfies the canonical AppManifest shape. */\nexport function isAppManifest(value: unknown): value is AppManifest {\n return (\n isRecord(value) &&\n hasRequiredManifestKeys(value) &&\n isManifestMetadata(value.metadata) &&\n Array.isArray(value.themes) &&\n value.themes.every(isThemeConfig) &&\n typeof value.activeThemeId === 'string' &&\n isActiveThemeMode(value.activeThemeMode) &&\n (value.splashScreen === undefined || isSplashScreenSpec(value.splashScreen)) &&\n (value.media === undefined || isMediaManifest(value.media)) &&\n isInfraManifest(value.infra) &&\n isNavigatorSpec(value.navigator) &&\n isScreenRegistry(value.screens) &&\n (value.generatedApis === undefined || isGeneratedApiRegistry(value.generatedApis)) &&\n (value.dataSources === undefined || isDataSourceRegistry(value.dataSources)) &&\n (value.dataBindings === undefined || isComponentDataBindingRegistry(value.dataBindings)) &&\n isAppSettings(value.settings)\n );\n}\n\nfunction hasRequiredManifestKeys(value: Record<string, unknown>): boolean {\n return Object.entries(APP_MANIFEST_KEY_POLICY).every(\n ([key, policy]) => policy === 'optional' || key in value,\n );\n}\n\nfunction isActiveThemeMode(value: unknown): boolean {\n return value === undefined || value === 'dark' || value === 'light';\n}\n\nfunction isAppSettings(value: unknown): boolean {\n return (\n isRecord(value) &&\n isRecord(value.localization) &&\n typeof value.localization.defaultLocale === 'string' &&\n isStringArray(value.localization.locales) &&\n isOptionalString(value.apiBaseUrl)\n );\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './bindings';
4
4
  export * from './cli';
5
5
  export * from './data';
6
6
  export * from './db';
7
+ export * from './media';
7
8
  export * from './requirements';
8
9
  export * from './runtimeCallbacks';
9
10
  export * from './secretManifest';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export * from './bindings';
4
4
  export * from './cli';
5
5
  export * from './data';
6
6
  export * from './db';
7
+ export * from './media';
7
8
  export * from './requirements';
8
9
  export * from './runtimeCallbacks';
9
10
  export * from './secretManifest';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC","sourcesContent":["export * from './appManifest';\nexport * from './auth';\nexport * from './bindings';\nexport * from './cli';\nexport * from './data';\nexport * from './db';\nexport * from './requirements';\nexport * from './runtimeCallbacks';\nexport * from './secretManifest';\nexport * from './secrets';\nexport * from './state';\nexport * from './storage';\nexport * from './theme';\nexport * from './types';\nexport * from './ui';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,MAAM,CAAC","sourcesContent":["export * from './appManifest';\nexport * from './auth';\nexport * from './bindings';\nexport * from './cli';\nexport * from './data';\nexport * from './db';\nexport * from './media';\nexport * from './requirements';\nexport * from './runtimeCallbacks';\nexport * from './secretManifest';\nexport * from './secrets';\nexport * from './state';\nexport * from './storage';\nexport * from './theme';\nexport * from './types';\nexport * from './ui';\n"]}
@@ -0,0 +1,48 @@
1
+ export declare const MEDIA_ASSET_KINDS: readonly ["image", "audio", "video", "font", "file"];
2
+ export type MediaAssetKind = (typeof MEDIA_ASSET_KINDS)[number];
3
+ export interface MediaStorageSource {
4
+ readonly kind: 'storage';
5
+ /** Optional logical storage connection identifier for future multi-storage apps. */
6
+ readonly storageId?: string;
7
+ readonly bucket: string;
8
+ readonly path: string;
9
+ }
10
+ export interface MediaUrlSource {
11
+ readonly kind: 'url';
12
+ /** Stable remote URL. Transient/local URL schemes are not canonical media sources. */
13
+ readonly url: string;
14
+ }
15
+ export interface MediaBundledSource {
16
+ readonly kind: 'bundled';
17
+ /** App-relative bundled asset path resolved by the generated/runtime host. */
18
+ readonly path: string;
19
+ }
20
+ export type MediaAssetSource = MediaStorageSource | MediaUrlSource | MediaBundledSource;
21
+ export interface MediaAssetMetadata {
22
+ readonly originalFileName?: string;
23
+ readonly sizeBytes?: number;
24
+ readonly createdAt?: string;
25
+ readonly width?: number;
26
+ readonly height?: number;
27
+ readonly durationMs?: number;
28
+ }
29
+ /** Canonical Studio-managed authoring media entry. */
30
+ export interface MediaAsset {
31
+ readonly id: string;
32
+ readonly name: string;
33
+ readonly kind: MediaAssetKind;
34
+ readonly source: MediaAssetSource;
35
+ readonly contentType?: string;
36
+ readonly metadata?: MediaAssetMetadata;
37
+ }
38
+ export type MediaAssetRegistry = Readonly<Record<string, MediaAsset>>;
39
+ /** App-authoring media pool. Runtime/user-generated uploads do not belong here. */
40
+ export interface MediaManifest {
41
+ readonly assets: MediaAssetRegistry;
42
+ }
43
+ /** Stable component/property reference to one entry in `AppManifest.media.assets`. */
44
+ export interface MediaAssetReference {
45
+ readonly mediaId: string;
46
+ }
47
+ export declare function isMediaAssetReference(value: unknown): value is MediaAssetReference;
48
+ //# sourceMappingURL=media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,sDAAuD,CAAC;AAEtF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,oFAAoF;IACpF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,sFAAsF;IACtF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAExF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAEtE,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC;AAED,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAUlF"}
package/dist/media.js ADDED
@@ -0,0 +1,11 @@
1
+ export const MEDIA_ASSET_KINDS = ['image', 'audio', 'video', 'font', 'file'];
2
+ export function isMediaAssetReference(value) {
3
+ return (typeof value === 'object' &&
4
+ value !== null &&
5
+ !Array.isArray(value) &&
6
+ Object.keys(value).length === 1 &&
7
+ 'mediaId' in value &&
8
+ typeof value.mediaId === 'string' &&
9
+ value.mediaId.trim().length > 0);
10
+ }
11
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAyDtF,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;QAC/B,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAChC,CAAC;AACJ,CAAC","sourcesContent":["export const MEDIA_ASSET_KINDS = ['image', 'audio', 'video', 'font', 'file'] as const;\n\nexport type MediaAssetKind = (typeof MEDIA_ASSET_KINDS)[number];\n\nexport interface MediaStorageSource {\n readonly kind: 'storage';\n /** Optional logical storage connection identifier for future multi-storage apps. */\n readonly storageId?: string;\n readonly bucket: string;\n readonly path: string;\n}\n\nexport interface MediaUrlSource {\n readonly kind: 'url';\n /** Stable remote URL. Transient/local URL schemes are not canonical media sources. */\n readonly url: string;\n}\n\nexport interface MediaBundledSource {\n readonly kind: 'bundled';\n /** App-relative bundled asset path resolved by the generated/runtime host. */\n readonly path: string;\n}\n\nexport type MediaAssetSource = MediaStorageSource | MediaUrlSource | MediaBundledSource;\n\nexport interface MediaAssetMetadata {\n readonly originalFileName?: string;\n readonly sizeBytes?: number;\n readonly createdAt?: string;\n readonly width?: number;\n readonly height?: number;\n readonly durationMs?: number;\n}\n\n/** Canonical Studio-managed authoring media entry. */\nexport interface MediaAsset {\n readonly id: string;\n readonly name: string;\n readonly kind: MediaAssetKind;\n readonly source: MediaAssetSource;\n readonly contentType?: string;\n readonly metadata?: MediaAssetMetadata;\n}\n\nexport type MediaAssetRegistry = Readonly<Record<string, MediaAsset>>;\n\n/** App-authoring media pool. Runtime/user-generated uploads do not belong here. */\nexport interface MediaManifest {\n readonly assets: MediaAssetRegistry;\n}\n\n/** Stable component/property reference to one entry in `AppManifest.media.assets`. */\nexport interface MediaAssetReference {\n readonly mediaId: string;\n}\n\nexport function isMediaAssetReference(value: unknown): value is MediaAssetReference {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 1 &&\n 'mediaId' in value &&\n typeof value.mediaId === 'string' &&\n value.mediaId.trim().length > 0\n );\n}\n"]}
package/dist/storage.d.ts CHANGED
@@ -45,6 +45,46 @@ export interface StoragePublicUrlInput {
45
45
  export interface StoragePublicUrlResult {
46
46
  publicUrl: string;
47
47
  }
48
+ export interface StorageObjectMetadata {
49
+ storageId?: string;
50
+ bucket: string;
51
+ path: string;
52
+ contentType?: string;
53
+ sizeBytes?: number;
54
+ createdAt?: string;
55
+ updatedAt?: string;
56
+ etag?: string;
57
+ }
58
+ export interface StorageListInput {
59
+ storageId?: string;
60
+ bucket: string;
61
+ prefix?: string;
62
+ cursor?: string;
63
+ limit?: number;
64
+ }
65
+ export interface StorageListResult {
66
+ objects: readonly StorageObjectMetadata[];
67
+ nextCursor?: string;
68
+ }
69
+ export type StorageResolvedAccess = 'public' | 'signed';
70
+ export interface StorageResolveInput {
71
+ storageId?: string;
72
+ bucket: string;
73
+ path: string;
74
+ access?: StorageResolvedAccess;
75
+ expiresInSeconds?: number;
76
+ }
77
+ export interface StorageResolvedAsset {
78
+ storageId?: string;
79
+ bucket: string;
80
+ path: string;
81
+ url: string;
82
+ access: StorageResolvedAccess;
83
+ expiresAt?: string;
84
+ }
85
+ export interface StorageResolveResult {
86
+ asset: StorageResolvedAsset;
87
+ }
48
88
  export interface ImageMetadata {
49
89
  fileName?: string;
50
90
  sizeBytes?: number;
@@ -78,4 +118,19 @@ export interface StorageAdapter {
78
118
  publicUrl(input: StoragePublicUrlInput): Promise<StorageResult<StoragePublicUrlResult>>;
79
119
  getImageMetadata?(input: StorageAssetReference): Promise<StorageResult<ImageMetadata>>;
80
120
  }
121
+ export interface StorageListAdapter {
122
+ list(input: StorageListInput): Promise<StorageResult<StorageListResult>>;
123
+ }
124
+ export interface StorageResolveAdapter {
125
+ resolve(input: StorageResolveInput): Promise<StorageResult<StorageResolveResult>>;
126
+ }
127
+ /**
128
+ * Storage capability required by the app-authoring media service.
129
+ *
130
+ * Remote URL import/ingest is intentionally not part of this low-level object-storage
131
+ * contract. It is a trusted service operation that can be implemented by reading the
132
+ * remote object and delegating to `upload` when ingestion is requested.
133
+ */
134
+ export interface MediaStorageAdapter extends StorageAdapter, StorageListAdapter, StorageResolveAdapter {
135
+ }
81
136
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,eAAe,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,GACvD;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAE9B,MAAM,MAAM,aAAa,CAAC,KAAK,GAAG,IAAI,IAClC,eAAe,CAAC,KAAK,CAAC,GACtB;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,mBAAmB,CAAC;CAC5B,CAAC;AAEN,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GAAG,uBAAuB,GAAG,mBAAmB,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1D,SAAS,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACxF,gBAAgB,CAAC,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;CACxF"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"","sourcesContent":["export interface StorageAdapterError {\n code: string;\n message: string;\n cause?: unknown;\n}\n\nexport type StorageOkResult<TData> = [TData] extends [void]\n ? { ok: true; data?: undefined }\n : { ok: true; data: TData };\n\nexport type StorageResult<TData = void> =\n | StorageOkResult<TData>\n | {\n ok: false;\n error: StorageAdapterError;\n };\n\nexport interface StorageAssetReference {\n storageId?: string;\n bucket: string;\n path: string;\n publicUrl?: string;\n}\n\nexport interface StorageUploadInput {\n storageId?: string;\n bucket: string;\n path: string;\n body: Uint8Array;\n contentType?: string;\n cacheControl?: string;\n upsert?: boolean;\n}\n\nexport interface StorageUploadResult {\n asset: StorageAssetReference;\n}\n\nexport interface StorageRemoveInput {\n storageId?: string;\n bucket: string;\n path: string;\n}\n\nexport interface StoragePublicUrlInput {\n storageId?: string;\n bucket: string;\n path: string;\n}\n\nexport interface StoragePublicUrlResult {\n publicUrl: string;\n}\n\nexport interface ImageMetadata {\n fileName?: string;\n sizeBytes?: number;\n createdAt?: string;\n}\n\nexport interface StorageImageAssetSource {\n kind: 'storage';\n storageId?: string;\n bucket: string;\n path: string;\n publicUrl?: string;\n alt?: string;\n width?: number;\n height?: number;\n contentType?: string;\n metadata?: ImageMetadata;\n}\n\nexport interface UrlImageAssetSource {\n kind: 'url';\n url: string;\n alt?: string;\n width?: number;\n height?: number;\n contentType?: string;\n metadata?: ImageMetadata;\n}\n\nexport type ImageAssetSource = StorageImageAssetSource | UrlImageAssetSource;\n\nexport interface StorageAdapter {\n upload(input: StorageUploadInput): Promise<StorageResult<StorageUploadResult>>;\n remove(input: StorageRemoveInput): Promise<StorageResult>;\n publicUrl(input: StoragePublicUrlInput): Promise<StorageResult<StoragePublicUrlResult>>;\n getImageMetadata?(input: StorageAssetReference): Promise<StorageResult<ImageMetadata>>;\n}\n"]}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"","sourcesContent":["export interface StorageAdapterError {\n code: string;\n message: string;\n cause?: unknown;\n}\n\nexport type StorageOkResult<TData> = [TData] extends [void]\n ? { ok: true; data?: undefined }\n : { ok: true; data: TData };\n\nexport type StorageResult<TData = void> =\n | StorageOkResult<TData>\n | {\n ok: false;\n error: StorageAdapterError;\n };\n\nexport interface StorageAssetReference {\n storageId?: string;\n bucket: string;\n path: string;\n publicUrl?: string;\n}\n\nexport interface StorageUploadInput {\n storageId?: string;\n bucket: string;\n path: string;\n body: Uint8Array;\n contentType?: string;\n cacheControl?: string;\n upsert?: boolean;\n}\n\nexport interface StorageUploadResult {\n asset: StorageAssetReference;\n}\n\nexport interface StorageRemoveInput {\n storageId?: string;\n bucket: string;\n path: string;\n}\n\nexport interface StoragePublicUrlInput {\n storageId?: string;\n bucket: string;\n path: string;\n}\n\nexport interface StoragePublicUrlResult {\n publicUrl: string;\n}\n\nexport interface StorageObjectMetadata {\n storageId?: string;\n bucket: string;\n path: string;\n contentType?: string;\n sizeBytes?: number;\n createdAt?: string;\n updatedAt?: string;\n etag?: string;\n}\n\nexport interface StorageListInput {\n storageId?: string;\n bucket: string;\n prefix?: string;\n cursor?: string;\n limit?: number;\n}\n\nexport interface StorageListResult {\n objects: readonly StorageObjectMetadata[];\n nextCursor?: string;\n}\n\nexport type StorageResolvedAccess = 'public' | 'signed';\n\nexport interface StorageResolveInput {\n storageId?: string;\n bucket: string;\n path: string;\n access?: StorageResolvedAccess;\n expiresInSeconds?: number;\n}\n\nexport interface StorageResolvedAsset {\n storageId?: string;\n bucket: string;\n path: string;\n url: string;\n access: StorageResolvedAccess;\n expiresAt?: string;\n}\n\nexport interface StorageResolveResult {\n asset: StorageResolvedAsset;\n}\n\nexport interface ImageMetadata {\n fileName?: string;\n sizeBytes?: number;\n createdAt?: string;\n}\n\nexport interface StorageImageAssetSource {\n kind: 'storage';\n storageId?: string;\n bucket: string;\n path: string;\n publicUrl?: string;\n alt?: string;\n width?: number;\n height?: number;\n contentType?: string;\n metadata?: ImageMetadata;\n}\n\nexport interface UrlImageAssetSource {\n kind: 'url';\n url: string;\n alt?: string;\n width?: number;\n height?: number;\n contentType?: string;\n metadata?: ImageMetadata;\n}\n\nexport type ImageAssetSource = StorageImageAssetSource | UrlImageAssetSource;\n\nexport interface StorageAdapter {\n upload(input: StorageUploadInput): Promise<StorageResult<StorageUploadResult>>;\n remove(input: StorageRemoveInput): Promise<StorageResult>;\n publicUrl(input: StoragePublicUrlInput): Promise<StorageResult<StoragePublicUrlResult>>;\n getImageMetadata?(input: StorageAssetReference): Promise<StorageResult<ImageMetadata>>;\n}\n\nexport interface StorageListAdapter {\n list(input: StorageListInput): Promise<StorageResult<StorageListResult>>;\n}\n\nexport interface StorageResolveAdapter {\n resolve(input: StorageResolveInput): Promise<StorageResult<StorageResolveResult>>;\n}\n\n/**\n * Storage capability required by the app-authoring media service.\n *\n * Remote URL import/ingest is intentionally not part of this low-level object-storage\n * contract. It is a trusted service operation that can be implemented by reading the\n * remote object and delegating to `upload` when ingestion is requested.\n */\nexport interface MediaStorageAdapter\n extends StorageAdapter, StorageListAdapter, StorageResolveAdapter {}\n"]}
package/dist/types.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { ColorHarmony } from '@ankhorage/color-theory';
2
2
  import type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';
3
3
  import type { BindingValueSource, ComponentDataBindingRegistry, ScreenDataLoaderDefinition } from './bindings';
4
4
  import type { DataSourceRegistry, GeneratedApiRegistry } from './data';
5
+ import type { MediaManifest } from './media';
5
6
  import type { ScreenRequirements } from './requirements';
6
7
  import type { ThemeGlobalTokenOverrides, ThemeRecipeOverrides } from './theme';
7
8
  export interface ThemeModeConfig {
@@ -268,6 +269,8 @@ export interface AppManifest {
268
269
  activeThemeId: string;
269
270
  activeThemeMode?: 'dark' | 'light';
270
271
  splashScreen?: SplashScreenSpec;
272
+ /** Studio-managed authoring media. Runtime/user uploads are intentionally separate. */
273
+ media?: MediaManifest;
271
274
  infra: InfraManifest;
272
275
  navigator: NavigatorSpec;
273
276
  screens: Record<string, ScreenSpec>;
@@ -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,EACV,kBAAkB,EAClB,4BAA4B,EAC5B,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,eAAe,CAAC;IACtB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,8FAA8F;IAC9F,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAED,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,OAAO,GACP,SAAS,GACT,gBAAgB,GAChB,aAAa,GACb,QAAQ,GACR,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;KAC1C,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,MAAM,MAAM,GACd,WAAW,GACX,aAAa,GACb,YAAY,GACZ,cAAc,GACd,YAAY,GACZ,iBAAiB,GACjB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,aAAa,EAAE,GACxB;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,CAAC;AAE9C,MAAM,MAAM,0BAA0B,GAAG,aAAa,CAAC;AAEvD,MAAM,WAAW,iBAAiB,CAChC,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,QAAQ,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAEpE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAChD,aAAa,EACb;IACE,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC,CACF,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAE3F,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;CAC3D;AAED,MAAM,MAAM,2BAA2B,GAAG,iBAAiB,CACzD,sBAAsB,EACtB,0BAA0B,CAC3B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,mBAAmB,CAAC,MAAM,CAAC,GAC3B,2BAA2B,CAAC,MAAM,CAAC,GACnC,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE/B,MAAM,MAAM,sBAAsB,GAC9B,mBAAmB,GACnB,2BAA2B,GAC3B,kBAAkB,CAAC;AAEvB,eAAO,MAAM,eAAe,sCAAuC,CAAC;AACpE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,eAAO,MAAM,cAAc,4YAwBjB,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,kBAAkB,uBAAwB,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAErE,eAAO,MAAM,kBAAkB,uBAAwB,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAErE,eAAO,MAAM,cAAc,0BAA2B,CAAC;AACvD,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,eAAO,MAAM,iBAAiB,+BAAgC,CAAC;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,eAAO,MAAM,eAAe,qBAAsB,CAAC;AACnD,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE/D,eAAO,MAAM,uBAAuB,kDAAmD,CAAC;AACxF,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,eAAO,MAAM,WAAW,2BAA4B,CAAC;AACrD,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,aAAa,+BAAgC,CAAC;AAC3D,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,WAAW,2CAA4C,CAAC;AACrE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,cAAc,uBAAwB,CAAC;AACpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE7D,eAAO,MAAM,wBAAwB,yCAA0C,CAAC;AAChF,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEtD,eAAO,MAAM,qBAAqB,gDAAiD,CAAC;AACpF,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,eAAO,MAAM,mBAAmB,8FAMtB,CAAC;AACX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACzE,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAErE,eAAO,MAAM,mCAAmC,yBAA0B,CAAC;AAC3E,MAAM,MAAM,6BAA6B,GAAG,CAAC,OAAO,mCAAmC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjG,eAAO,MAAM,8BAA8B,oCAAqC,CAAC;AACjF,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAExF,eAAO,MAAM,8BAA8B,yBAA0B,CAAC;AACtE,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,8BAA8B,CAAC,CAAC,MAAM,CAAC,CAAC;AAExF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACpD,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,sBAAsB,CAAC;CAC9C;AAED,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IACjE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,6BAA6B,CAAC;IAC3C,cAAc,CAAC,EAAE,yBAAyB,CAAC;IAC3C,cAAc,CAAC,EAAE,yBAAyB,CAAC;CAC5C;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,WAAW,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpC,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,EAAE,WAAW,CAAC;CACvB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgJA,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;AAIX,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,YAAY,CAAU,CAAC;AAG3E,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAGjF,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC","sourcesContent":["import type { ColorHarmony } from '@ankhorage/color-theory';\n\nimport type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';\nimport type {\n BindingValueSource,\n ComponentDataBindingRegistry,\n ScreenDataLoaderDefinition,\n} from './bindings';\nimport type { DataSourceRegistry, GeneratedApiRegistry } from './data';\nimport type { ScreenRequirements } from './requirements';\nimport type { ThemeGlobalTokenOverrides, ThemeRecipeOverrides } from './theme';\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 /** Theme-global authored token overrides shared by light and dark mode. */\n tokens?: ThemeGlobalTokenOverrides;\n /** Component/pattern recipe override values; recipe schemas remain package-owned metadata. */\n recipes?: ThemeRecipeOverrides;\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 const AUTH_PROFILE_PRIMARY_KEY_STRATEGIES = ['authUserId'] as const;\nexport type AuthProfilePrimaryKeyStrategy = (typeof AUTH_PROFILE_PRIMARY_KEY_STRATEGIES)[number];\n\nexport const AUTH_PROFILE_CREATE_STRATEGIES = ['trigger', 'api', 'app'] as const;\nexport type AuthProfileCreateStrategy = (typeof AUTH_PROFILE_CREATE_STRATEGIES)[number];\n\nexport const AUTH_PROFILE_UPDATE_STRATEGIES = ['api', 'app'] as const;\nexport type AuthProfileUpdateStrategy = (typeof AUTH_PROFILE_UPDATE_STRATEGIES)[number];\n\nexport interface IconSpec {\n name: string;\n provider?: string;\n size?: number | string;\n color?: string;\n}\n\nexport interface UiNodeRepeatSpec {\n source: BindingValueSource;\n itemAlias?: string;\n keyPath?: string;\n empty?: readonly UiNode[];\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 repeat?: UiNodeRepeatSpec;\n}\n\nexport interface ScreenSpec {\n id: string;\n name: string;\n title?: string;\n description?: string;\n root: UiNode;\n dataLoaders?: readonly ScreenDataLoaderDefinition[];\n requires?: ScreenRequirements;\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 /**\n * Whether this route appears in Tabs and Drawer primary navigation.\n *\n * Omitted routes are visible by default. Setting this to `false` hides the\n * route from primary navigation without making it unnavigable. Stack\n * navigators preserve the value but do not present primary navigation.\n */\n showInPrimaryNavigation?: 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 table?: string;\n primaryKey?: AuthProfilePrimaryKeyStrategy;\n createStrategy?: AuthProfileCreateStrategy;\n updateStrategy?: AuthProfileUpdateStrategy;\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 modules: string[];\n modulesConfig?: Record<string, unknown>;\n}\n\nexport interface AppSettings {\n apiBaseUrl?: string;\n localization: {\n defaultLocale: string;\n locales: string[];\n };\n}\n\nexport interface AppManifest {\n metadata: {\n name: string;\n slug: string;\n version: string;\n category: AppCategory;\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 generatedApis?: GeneratedApiRegistry;\n dataSources?: DataSourceRegistry;\n dataBindings?: ComponentDataBindingRegistry;\n settings: AppSettings;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAiJA,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;AAIX,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,YAAY,CAAU,CAAC;AAG3E,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAGjF,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC","sourcesContent":["import type { ColorHarmony } from '@ankhorage/color-theory';\n\nimport type { AuthFlowConfig, AuthIdentifierKind, AuthOAuthConfig, AuthSignUpField } from './auth';\nimport type {\n BindingValueSource,\n ComponentDataBindingRegistry,\n ScreenDataLoaderDefinition,\n} from './bindings';\nimport type { DataSourceRegistry, GeneratedApiRegistry } from './data';\nimport type { MediaManifest } from './media';\nimport type { ScreenRequirements } from './requirements';\nimport type { ThemeGlobalTokenOverrides, ThemeRecipeOverrides } from './theme';\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 /** Theme-global authored token overrides shared by light and dark mode. */\n tokens?: ThemeGlobalTokenOverrides;\n /** Component/pattern recipe override values; recipe schemas remain package-owned metadata. */\n recipes?: ThemeRecipeOverrides;\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 const AUTH_PROFILE_PRIMARY_KEY_STRATEGIES = ['authUserId'] as const;\nexport type AuthProfilePrimaryKeyStrategy = (typeof AUTH_PROFILE_PRIMARY_KEY_STRATEGIES)[number];\n\nexport const AUTH_PROFILE_CREATE_STRATEGIES = ['trigger', 'api', 'app'] as const;\nexport type AuthProfileCreateStrategy = (typeof AUTH_PROFILE_CREATE_STRATEGIES)[number];\n\nexport const AUTH_PROFILE_UPDATE_STRATEGIES = ['api', 'app'] as const;\nexport type AuthProfileUpdateStrategy = (typeof AUTH_PROFILE_UPDATE_STRATEGIES)[number];\n\nexport interface IconSpec {\n name: string;\n provider?: string;\n size?: number | string;\n color?: string;\n}\n\nexport interface UiNodeRepeatSpec {\n source: BindingValueSource;\n itemAlias?: string;\n keyPath?: string;\n empty?: readonly UiNode[];\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 repeat?: UiNodeRepeatSpec;\n}\n\nexport interface ScreenSpec {\n id: string;\n name: string;\n title?: string;\n description?: string;\n root: UiNode;\n dataLoaders?: readonly ScreenDataLoaderDefinition[];\n requires?: ScreenRequirements;\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 /**\n * Whether this route appears in Tabs and Drawer primary navigation.\n *\n * Omitted routes are visible by default. Setting this to `false` hides the\n * route from primary navigation without making it unnavigable. Stack\n * navigators preserve the value but do not present primary navigation.\n */\n showInPrimaryNavigation?: 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 table?: string;\n primaryKey?: AuthProfilePrimaryKeyStrategy;\n createStrategy?: AuthProfileCreateStrategy;\n updateStrategy?: AuthProfileUpdateStrategy;\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 modules: string[];\n modulesConfig?: Record<string, unknown>;\n}\n\nexport interface AppSettings {\n apiBaseUrl?: string;\n localization: {\n defaultLocale: string;\n locales: string[];\n };\n}\n\nexport interface AppManifest {\n metadata: {\n name: string;\n slug: string;\n version: string;\n category: AppCategory;\n themeId: string;\n created?: string;\n updated?: string;\n };\n themes: ThemeConfig[];\n activeThemeId: string;\n activeThemeMode?: 'dark' | 'light';\n splashScreen?: SplashScreenSpec;\n /** Studio-managed authoring media. Runtime/user uploads are intentionally separate. */\n media?: MediaManifest;\n infra: InfraManifest;\n navigator: NavigatorSpec;\n screens: Record<string, ScreenSpec>;\n generatedApis?: GeneratedApiRegistry;\n dataSources?: DataSourceRegistry;\n dataBindings?: ComponentDataBindingRegistry;\n settings: AppSettings;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ankhorage/contracts",
3
- "version": "7.2.0",
3
+ "version": "7.4.0",
4
4
  "main": "./dist/index.js",
5
5
  "ankh": {
6
6
  "category": "contracts",
@@ -64,6 +64,10 @@
64
64
  "./ui": {
65
65
  "types": "./dist/ui.d.ts",
66
66
  "default": "./dist/ui.js"
67
+ },
68
+ "./media": {
69
+ "types": "./dist/media.d.ts",
70
+ "default": "./dist/media.js"
67
71
  }
68
72
  },
69
73
  "description": "Serializable app, action, theme, auth, and secret-store contracts for Ankhorage.",
@@ -76,7 +80,9 @@
76
80
  "secrets",
77
81
  "secret-store",
78
82
  "storage",
79
- "adapter"
83
+ "adapter",
84
+ "media",
85
+ "assets"
80
86
  ],
81
87
  "files": [
82
88
  "dist",
@@ -0,0 +1,101 @@
1
+ import {
2
+ MEDIA_ASSET_KINDS,
3
+ type MediaAsset,
4
+ type MediaAssetMetadata,
5
+ type MediaAssetSource,
6
+ type MediaManifest,
7
+ } from '../media';
8
+ import { isOptionalString, isRecord } from './shared';
9
+
10
+ const MEDIA_ASSET_KIND_SET = new Set<string>(MEDIA_ASSET_KINDS);
11
+
12
+ export function isMediaManifest(value: unknown): value is MediaManifest {
13
+ if (!isRecord(value) || !hasOnlyKeys(value, ['assets']) || !isRecord(value.assets)) return false;
14
+
15
+ return Object.entries(value.assets).every(
16
+ ([assetId, asset]) => isMediaAsset(asset) && asset.id === assetId,
17
+ );
18
+ }
19
+
20
+ function isMediaAsset(value: unknown): value is MediaAsset {
21
+ return (
22
+ isRecord(value) &&
23
+ hasOnlyKeys(value, ['id', 'name', 'kind', 'source', 'contentType', 'metadata']) &&
24
+ isNonEmptyString(value.id) &&
25
+ isNonEmptyString(value.name) &&
26
+ typeof value.kind === 'string' &&
27
+ MEDIA_ASSET_KIND_SET.has(value.kind) &&
28
+ isMediaAssetSource(value.source) &&
29
+ isOptionalString(value.contentType) &&
30
+ (value.metadata === undefined || isMediaAssetMetadata(value.metadata))
31
+ );
32
+ }
33
+
34
+ function isMediaAssetSource(value: unknown): value is MediaAssetSource {
35
+ if (!isRecord(value) || typeof value.kind !== 'string') return false;
36
+
37
+ if (value.kind === 'storage') {
38
+ return (
39
+ hasOnlyKeys(value, ['kind', 'storageId', 'bucket', 'path']) &&
40
+ isOptionalString(value.storageId) &&
41
+ isNonEmptyString(value.bucket) &&
42
+ isNonEmptyString(value.path)
43
+ );
44
+ }
45
+
46
+ if (value.kind === 'url') {
47
+ return hasOnlyKeys(value, ['kind', 'url']) && isStableRemoteUrl(value.url);
48
+ }
49
+
50
+ return (
51
+ value.kind === 'bundled' && hasOnlyKeys(value, ['kind', 'path']) && isBundledPath(value.path)
52
+ );
53
+ }
54
+
55
+ function isMediaAssetMetadata(value: unknown): value is MediaAssetMetadata {
56
+ return (
57
+ isRecord(value) &&
58
+ hasOnlyKeys(value, [
59
+ 'originalFileName',
60
+ 'sizeBytes',
61
+ 'createdAt',
62
+ 'width',
63
+ 'height',
64
+ 'durationMs',
65
+ ]) &&
66
+ isOptionalString(value.originalFileName) &&
67
+ isOptionalString(value.createdAt) &&
68
+ isOptionalFiniteNonNegativeNumber(value.sizeBytes) &&
69
+ isOptionalFinitePositiveNumber(value.width) &&
70
+ isOptionalFinitePositiveNumber(value.height) &&
71
+ isOptionalFiniteNonNegativeNumber(value.durationMs)
72
+ );
73
+ }
74
+
75
+ function isStableRemoteUrl(value: unknown): boolean {
76
+ return typeof value === 'string' && /^https?:\/\//iu.test(value.trim());
77
+ }
78
+
79
+ function isBundledPath(value: unknown): boolean {
80
+ if (!isNonEmptyString(value)) return false;
81
+ const path = value.trim();
82
+ if (path.startsWith('/') || /^[a-z][a-z0-9+.-]*:/iu.test(path)) return false;
83
+ return !path.split('/').includes('..');
84
+ }
85
+
86
+ function isNonEmptyString(value: unknown): value is string {
87
+ return typeof value === 'string' && value.trim().length > 0;
88
+ }
89
+
90
+ function isOptionalFiniteNonNegativeNumber(value: unknown): boolean {
91
+ return value === undefined || (typeof value === 'number' && Number.isFinite(value) && value >= 0);
92
+ }
93
+
94
+ function isOptionalFinitePositiveNumber(value: unknown): boolean {
95
+ return value === undefined || (typeof value === 'number' && Number.isFinite(value) && value > 0);
96
+ }
97
+
98
+ function hasOnlyKeys(value: Record<string, unknown>, allowedKeys: readonly string[]): boolean {
99
+ const allowed = new Set(allowedKeys);
100
+ return Object.keys(value).every((key) => allowed.has(key));
101
+ }
@@ -27,6 +27,16 @@ function createManifest(): Record<string, unknown> {
27
27
  backgroundColor: '#ffffff',
28
28
  dark: { backgroundColor: '#000000' },
29
29
  },
30
+ media: {
31
+ assets: {
32
+ hero: {
33
+ id: 'hero',
34
+ name: 'Hero image',
35
+ kind: 'image',
36
+ source: { kind: 'storage', bucket: 'media', path: 'studio/hero.webp' },
37
+ },
38
+ },
39
+ },
30
40
  infra: {
31
41
  deployment: { target: 'minikube', monitoring: true },
32
42
  database: { provider: 'supabase', tier: 'dev' },
@@ -157,6 +167,14 @@ describe('AppManifest runtime parsing', () => {
157
167
  });
158
168
  });
159
169
 
170
+ it('rejects transient media URLs at the manifest boundary', () => {
171
+ const manifest = createManifest();
172
+ const media = manifest.media as Record<string, Record<string, Record<string, unknown>>>;
173
+ media.assets.hero.source = { kind: 'url', url: 'blob:https://example.test/transient' };
174
+
175
+ expect(isAppManifest(manifest)).toBe(false);
176
+ });
177
+
160
178
  it('rejects legacy infra plugin state', () => {
161
179
  const manifest = createManifest();
162
180
  const infra = manifest.infra as Record<string, unknown>;
@@ -2,6 +2,7 @@ import { isComponentDataBindingRegistry } from './appManifest/bindings';
2
2
  import { isDataSourceRegistry } from './appManifest/dataSources';
3
3
  import { isGeneratedApiRegistry } from './appManifest/generatedApis';
4
4
  import { isInfraManifest } from './appManifest/infra';
5
+ import { isMediaManifest } from './appManifest/media';
5
6
  import {
6
7
  isManifestMetadata,
7
8
  isNavigatorSpec,
@@ -22,6 +23,7 @@ const APP_MANIFEST_KEY_POLICY = {
22
23
  activeThemeId: 'required',
23
24
  activeThemeMode: 'optional',
24
25
  splashScreen: 'optional',
26
+ media: 'optional',
25
27
  infra: 'required',
26
28
  navigator: 'required',
27
29
  screens: 'required',
@@ -55,6 +57,7 @@ export function isAppManifest(value: unknown): value is AppManifest {
55
57
  typeof value.activeThemeId === 'string' &&
56
58
  isActiveThemeMode(value.activeThemeMode) &&
57
59
  (value.splashScreen === undefined || isSplashScreenSpec(value.splashScreen)) &&
60
+ (value.media === undefined || isMediaManifest(value.media)) &&
58
61
  isInfraManifest(value.infra) &&
59
62
  isNavigatorSpec(value.navigator) &&
60
63
  isScreenRegistry(value.screens) &&
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ export * from './bindings';
4
4
  export * from './cli';
5
5
  export * from './data';
6
6
  export * from './db';
7
+ export * from './media';
7
8
  export * from './requirements';
8
9
  export * from './runtimeCallbacks';
9
10
  export * from './secretManifest';
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+
3
+ import { isMediaManifest } from './appManifest/media';
4
+ import { isMediaAssetReference } from './media';
5
+
6
+ function createMediaManifest() {
7
+ return {
8
+ assets: {
9
+ hero: {
10
+ id: 'hero',
11
+ name: 'Hero image',
12
+ kind: 'image',
13
+ source: { kind: 'storage', bucket: 'media', path: 'studio/hero.webp' },
14
+ contentType: 'image/webp',
15
+ metadata: { width: 1600, height: 900, sizeBytes: 42000 },
16
+ },
17
+ logo: {
18
+ id: 'logo',
19
+ name: 'Logo',
20
+ kind: 'image',
21
+ source: { kind: 'bundled', path: 'assets/logo.png' },
22
+ },
23
+ remote: {
24
+ id: 'remote',
25
+ name: 'Remote image',
26
+ kind: 'image',
27
+ source: { kind: 'url', url: 'https://example.test/image.png' },
28
+ },
29
+ },
30
+ };
31
+ }
32
+
33
+ describe('media contracts', () => {
34
+ it('accepts storage, bundled, and stable URL authoring media', () => {
35
+ expect(isMediaManifest(createMediaManifest())).toBe(true);
36
+ });
37
+
38
+ it('requires registry keys to match media asset ids', () => {
39
+ const media = createMediaManifest();
40
+ media.assets.hero.id = 'other';
41
+
42
+ expect(isMediaManifest(media)).toBe(false);
43
+ });
44
+
45
+ it('rejects transient or local URL schemes', () => {
46
+ for (const url of [
47
+ 'blob:https://example.test/id',
48
+ 'file:///tmp/image.png',
49
+ 'data:image/png;base64,x',
50
+ ]) {
51
+ const media = createMediaManifest();
52
+ media.assets.remote.source = { kind: 'url', url };
53
+ expect(isMediaManifest(media)).toBe(false);
54
+ }
55
+ });
56
+
57
+ it('rejects denormalized public URLs on managed storage sources', () => {
58
+ const media = createMediaManifest();
59
+ const source = media.assets.hero.source as Record<string, unknown>;
60
+ source.publicUrl = 'https://example.test/public/hero.webp';
61
+
62
+ expect(isMediaManifest(media)).toBe(false);
63
+ });
64
+
65
+ it('validates stable media references', () => {
66
+ expect(isMediaAssetReference({ mediaId: 'hero' })).toBe(true);
67
+ expect(isMediaAssetReference({ mediaId: 'hero', url: 'blob:local' })).toBe(false);
68
+ expect(isMediaAssetReference({ mediaId: '' })).toBe(false);
69
+ });
70
+ });
package/src/media.ts ADDED
@@ -0,0 +1,68 @@
1
+ export const MEDIA_ASSET_KINDS = ['image', 'audio', 'video', 'font', 'file'] as const;
2
+
3
+ export type MediaAssetKind = (typeof MEDIA_ASSET_KINDS)[number];
4
+
5
+ export interface MediaStorageSource {
6
+ readonly kind: 'storage';
7
+ /** Optional logical storage connection identifier for future multi-storage apps. */
8
+ readonly storageId?: string;
9
+ readonly bucket: string;
10
+ readonly path: string;
11
+ }
12
+
13
+ export interface MediaUrlSource {
14
+ readonly kind: 'url';
15
+ /** Stable remote URL. Transient/local URL schemes are not canonical media sources. */
16
+ readonly url: string;
17
+ }
18
+
19
+ export interface MediaBundledSource {
20
+ readonly kind: 'bundled';
21
+ /** App-relative bundled asset path resolved by the generated/runtime host. */
22
+ readonly path: string;
23
+ }
24
+
25
+ export type MediaAssetSource = MediaStorageSource | MediaUrlSource | MediaBundledSource;
26
+
27
+ export interface MediaAssetMetadata {
28
+ readonly originalFileName?: string;
29
+ readonly sizeBytes?: number;
30
+ readonly createdAt?: string;
31
+ readonly width?: number;
32
+ readonly height?: number;
33
+ readonly durationMs?: number;
34
+ }
35
+
36
+ /** Canonical Studio-managed authoring media entry. */
37
+ export interface MediaAsset {
38
+ readonly id: string;
39
+ readonly name: string;
40
+ readonly kind: MediaAssetKind;
41
+ readonly source: MediaAssetSource;
42
+ readonly contentType?: string;
43
+ readonly metadata?: MediaAssetMetadata;
44
+ }
45
+
46
+ export type MediaAssetRegistry = Readonly<Record<string, MediaAsset>>;
47
+
48
+ /** App-authoring media pool. Runtime/user-generated uploads do not belong here. */
49
+ export interface MediaManifest {
50
+ readonly assets: MediaAssetRegistry;
51
+ }
52
+
53
+ /** Stable component/property reference to one entry in `AppManifest.media.assets`. */
54
+ export interface MediaAssetReference {
55
+ readonly mediaId: string;
56
+ }
57
+
58
+ export function isMediaAssetReference(value: unknown): value is MediaAssetReference {
59
+ return (
60
+ typeof value === 'object' &&
61
+ value !== null &&
62
+ !Array.isArray(value) &&
63
+ Object.keys(value).length === 1 &&
64
+ 'mediaId' in value &&
65
+ typeof value.mediaId === 'string' &&
66
+ value.mediaId.trim().length > 0
67
+ );
68
+ }
@@ -0,0 +1,107 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+
3
+ import type { MediaStorageAdapter } from './storage';
4
+
5
+ const adapter: MediaStorageAdapter = {
6
+ upload(input) {
7
+ return Promise.resolve({
8
+ ok: true,
9
+ data: {
10
+ asset: {
11
+ storageId: input.storageId,
12
+ bucket: input.bucket,
13
+ path: input.path,
14
+ },
15
+ },
16
+ });
17
+ },
18
+ remove() {
19
+ return Promise.resolve({ ok: true });
20
+ },
21
+ publicUrl(input) {
22
+ return Promise.resolve({
23
+ ok: true,
24
+ data: { publicUrl: `https://cdn.example.test/${input.bucket}/${input.path}` },
25
+ });
26
+ },
27
+ list(input) {
28
+ return Promise.resolve({
29
+ ok: true,
30
+ data: {
31
+ objects: [
32
+ {
33
+ storageId: input.storageId,
34
+ bucket: input.bucket,
35
+ path: `${input.prefix ?? ''}hero.png`,
36
+ contentType: 'image/png',
37
+ sizeBytes: 4096,
38
+ },
39
+ ],
40
+ },
41
+ });
42
+ },
43
+ resolve(input) {
44
+ return Promise.resolve({
45
+ ok: true,
46
+ data: {
47
+ asset: {
48
+ storageId: input.storageId,
49
+ bucket: input.bucket,
50
+ path: input.path,
51
+ url: `https://signed.example.test/${input.bucket}/${input.path}`,
52
+ access: input.access ?? 'signed',
53
+ expiresAt: '2026-08-12T10:00:00.000Z',
54
+ },
55
+ },
56
+ });
57
+ },
58
+ };
59
+
60
+ describe('media storage capabilities', () => {
61
+ it('lists normalized provider-neutral object metadata', async () => {
62
+ const result = await adapter.list({
63
+ storageId: 'primary',
64
+ bucket: 'media',
65
+ prefix: 'authoring/',
66
+ });
67
+
68
+ expect(result).toEqual({
69
+ ok: true,
70
+ data: {
71
+ objects: [
72
+ {
73
+ storageId: 'primary',
74
+ bucket: 'media',
75
+ path: 'authoring/hero.png',
76
+ contentType: 'image/png',
77
+ sizeBytes: 4096,
78
+ },
79
+ ],
80
+ },
81
+ });
82
+ });
83
+
84
+ it('resolves a stable storage identity to a runtime-readable URL', async () => {
85
+ const result = await adapter.resolve({
86
+ storageId: 'primary',
87
+ bucket: 'media',
88
+ path: 'authoring/hero.png',
89
+ access: 'signed',
90
+ expiresInSeconds: 900,
91
+ });
92
+
93
+ expect(result).toEqual({
94
+ ok: true,
95
+ data: {
96
+ asset: {
97
+ storageId: 'primary',
98
+ bucket: 'media',
99
+ path: 'authoring/hero.png',
100
+ url: 'https://signed.example.test/media/authoring/hero.png',
101
+ access: 'signed',
102
+ expiresAt: '2026-08-12T10:00:00.000Z',
103
+ },
104
+ },
105
+ });
106
+ });
107
+ });
package/src/storage.ts CHANGED
@@ -52,6 +52,53 @@ export interface StoragePublicUrlResult {
52
52
  publicUrl: string;
53
53
  }
54
54
 
55
+ export interface StorageObjectMetadata {
56
+ storageId?: string;
57
+ bucket: string;
58
+ path: string;
59
+ contentType?: string;
60
+ sizeBytes?: number;
61
+ createdAt?: string;
62
+ updatedAt?: string;
63
+ etag?: string;
64
+ }
65
+
66
+ export interface StorageListInput {
67
+ storageId?: string;
68
+ bucket: string;
69
+ prefix?: string;
70
+ cursor?: string;
71
+ limit?: number;
72
+ }
73
+
74
+ export interface StorageListResult {
75
+ objects: readonly StorageObjectMetadata[];
76
+ nextCursor?: string;
77
+ }
78
+
79
+ export type StorageResolvedAccess = 'public' | 'signed';
80
+
81
+ export interface StorageResolveInput {
82
+ storageId?: string;
83
+ bucket: string;
84
+ path: string;
85
+ access?: StorageResolvedAccess;
86
+ expiresInSeconds?: number;
87
+ }
88
+
89
+ export interface StorageResolvedAsset {
90
+ storageId?: string;
91
+ bucket: string;
92
+ path: string;
93
+ url: string;
94
+ access: StorageResolvedAccess;
95
+ expiresAt?: string;
96
+ }
97
+
98
+ export interface StorageResolveResult {
99
+ asset: StorageResolvedAsset;
100
+ }
101
+
55
102
  export interface ImageMetadata {
56
103
  fileName?: string;
57
104
  sizeBytes?: number;
@@ -89,3 +136,21 @@ export interface StorageAdapter {
89
136
  publicUrl(input: StoragePublicUrlInput): Promise<StorageResult<StoragePublicUrlResult>>;
90
137
  getImageMetadata?(input: StorageAssetReference): Promise<StorageResult<ImageMetadata>>;
91
138
  }
139
+
140
+ export interface StorageListAdapter {
141
+ list(input: StorageListInput): Promise<StorageResult<StorageListResult>>;
142
+ }
143
+
144
+ export interface StorageResolveAdapter {
145
+ resolve(input: StorageResolveInput): Promise<StorageResult<StorageResolveResult>>;
146
+ }
147
+
148
+ /**
149
+ * Storage capability required by the app-authoring media service.
150
+ *
151
+ * Remote URL import/ingest is intentionally not part of this low-level object-storage
152
+ * contract. It is a trusted service operation that can be implemented by reading the
153
+ * remote object and delegating to `upload` when ingestion is requested.
154
+ */
155
+ export interface MediaStorageAdapter
156
+ extends StorageAdapter, StorageListAdapter, StorageResolveAdapter {}
package/src/types.ts CHANGED
@@ -7,6 +7,7 @@ import type {
7
7
  ScreenDataLoaderDefinition,
8
8
  } from './bindings';
9
9
  import type { DataSourceRegistry, GeneratedApiRegistry } from './data';
10
+ import type { MediaManifest } from './media';
10
11
  import type { ScreenRequirements } from './requirements';
11
12
  import type { ThemeGlobalTokenOverrides, ThemeRecipeOverrides } from './theme';
12
13
 
@@ -398,6 +399,8 @@ export interface AppManifest {
398
399
  activeThemeId: string;
399
400
  activeThemeMode?: 'dark' | 'light';
400
401
  splashScreen?: SplashScreenSpec;
402
+ /** Studio-managed authoring media. Runtime/user uploads are intentionally separate. */
403
+ media?: MediaManifest;
401
404
  infra: InfraManifest;
402
405
  navigator: NavigatorSpec;
403
406
  screens: Record<string, ScreenSpec>;