@ankhorage/contracts 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/storage.d.ts +81 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +2 -0
- package/dist/storage.js.map +1 -0
- package/package.json +6 -2
- package/src/contracts.test.ts +54 -0
- package/src/index.ts +1 -0
- package/src/storage.ts +91 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @ankhorage/contracts
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f773215: Add provider-neutral storage and image asset contracts.
|
|
8
|
+
|
|
9
|
+
This introduces serializable storage asset references, a `StorageAdapter` contract for upload, remove, and public URL workflows, and manifest-safe `ImageAssetSource` variants for storage-backed and URL-backed images.
|
|
10
|
+
|
|
11
|
+
The storage upload boundary uses `Uint8Array` only, avoids DOM-specific `File`/`Blob` types, and keeps storage identity provider-neutral through `storageId`, `bucket`, and `path`.
|
|
12
|
+
|
|
3
13
|
## 1.1.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ Shared public contracts for Ankhorage packages and standalone provider packages.
|
|
|
23
23
|
import type { AppManifest } from '@ankhorage/contracts';
|
|
24
24
|
import type { AuthAdapter } from '@ankhorage/contracts/auth';
|
|
25
25
|
import type { DbAdapter } from '@ankhorage/contracts/db';
|
|
26
|
+
import type { StorageAdapter } from '@ankhorage/contracts/storage';
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
Contracts keeps theme configuration serializable. Color validation, harmony,
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,SAAS,CAAC","sourcesContent":["export * from './auth';\nexport * from './db';\nexport * from './types';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC","sourcesContent":["export * from './auth';\nexport * from './db';\nexport * from './storage';\nexport * from './types';\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export interface StorageAdapterError {
|
|
2
|
+
code: string;
|
|
3
|
+
message: string;
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
}
|
|
6
|
+
export type StorageOkResult<TData> = [TData] extends [void] ? {
|
|
7
|
+
ok: true;
|
|
8
|
+
data?: undefined;
|
|
9
|
+
} : {
|
|
10
|
+
ok: true;
|
|
11
|
+
data: TData;
|
|
12
|
+
};
|
|
13
|
+
export type StorageResult<TData = void> = StorageOkResult<TData> | {
|
|
14
|
+
ok: false;
|
|
15
|
+
error: StorageAdapterError;
|
|
16
|
+
};
|
|
17
|
+
export interface StorageAssetReference {
|
|
18
|
+
storageId?: string;
|
|
19
|
+
bucket: string;
|
|
20
|
+
path: string;
|
|
21
|
+
publicUrl?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface StorageUploadInput {
|
|
24
|
+
storageId?: string;
|
|
25
|
+
bucket: string;
|
|
26
|
+
path: string;
|
|
27
|
+
body: Uint8Array;
|
|
28
|
+
contentType?: string;
|
|
29
|
+
cacheControl?: string;
|
|
30
|
+
upsert?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface StorageUploadResult {
|
|
33
|
+
asset: StorageAssetReference;
|
|
34
|
+
}
|
|
35
|
+
export interface StorageRemoveInput {
|
|
36
|
+
storageId?: string;
|
|
37
|
+
bucket: string;
|
|
38
|
+
path: string;
|
|
39
|
+
}
|
|
40
|
+
export interface StoragePublicUrlInput {
|
|
41
|
+
storageId?: string;
|
|
42
|
+
bucket: string;
|
|
43
|
+
path: string;
|
|
44
|
+
}
|
|
45
|
+
export interface StoragePublicUrlResult {
|
|
46
|
+
publicUrl: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ImageMetadata {
|
|
49
|
+
fileName?: string;
|
|
50
|
+
sizeBytes?: number;
|
|
51
|
+
createdAt?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface StorageImageAssetSource {
|
|
54
|
+
kind: 'storage';
|
|
55
|
+
storageId?: string;
|
|
56
|
+
bucket: string;
|
|
57
|
+
path: string;
|
|
58
|
+
publicUrl?: string;
|
|
59
|
+
alt?: string;
|
|
60
|
+
width?: number;
|
|
61
|
+
height?: number;
|
|
62
|
+
contentType?: string;
|
|
63
|
+
metadata?: ImageMetadata;
|
|
64
|
+
}
|
|
65
|
+
export interface UrlImageAssetSource {
|
|
66
|
+
kind: 'url';
|
|
67
|
+
url: string;
|
|
68
|
+
alt?: string;
|
|
69
|
+
width?: number;
|
|
70
|
+
height?: number;
|
|
71
|
+
contentType?: string;
|
|
72
|
+
metadata?: ImageMetadata;
|
|
73
|
+
}
|
|
74
|
+
export type ImageAssetSource = StorageImageAssetSource | UrlImageAssetSource;
|
|
75
|
+
export interface StorageAdapter {
|
|
76
|
+
upload(input: StorageUploadInput): Promise<StorageResult<StorageUploadResult>>;
|
|
77
|
+
remove(input: StorageRemoveInput): Promise<StorageResult>;
|
|
78
|
+
publicUrl(input: StoragePublicUrlInput): Promise<StorageResult<StoragePublicUrlResult>>;
|
|
79
|
+
getImageMetadata?(input: StorageAssetReference): Promise<StorageResult<ImageMetadata>>;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +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"]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/contracts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@ankhorage/color-theory": "^0.0.
|
|
6
|
+
"@ankhorage/color-theory": "^0.0.4"
|
|
7
7
|
},
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@ankhorage/devtools": "^1.0.0",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"./db": {
|
|
25
25
|
"types": "./dist/db.d.ts",
|
|
26
26
|
"default": "./dist/db.js"
|
|
27
|
+
},
|
|
28
|
+
"./storage": {
|
|
29
|
+
"types": "./dist/storage.d.ts",
|
|
30
|
+
"default": "./dist/storage.js"
|
|
27
31
|
}
|
|
28
32
|
},
|
|
29
33
|
"description": "Serializable app, action, and theme config contracts for Ankhorage.",
|
package/src/contracts.test.ts
CHANGED
|
@@ -13,7 +13,11 @@ import {
|
|
|
13
13
|
type AuthFlowConfig,
|
|
14
14
|
type AuthSpec,
|
|
15
15
|
DEPLOYMENT_TARGETS,
|
|
16
|
+
type ImageAssetSource,
|
|
16
17
|
NAVIGATOR_TYPES,
|
|
18
|
+
type StoragePublicUrlResult,
|
|
19
|
+
type StorageResult,
|
|
20
|
+
type StorageUploadResult,
|
|
17
21
|
type ThemeConfig,
|
|
18
22
|
type ThemeModeConfig,
|
|
19
23
|
} from './index';
|
|
@@ -164,4 +168,54 @@ describe('contracts', () => {
|
|
|
164
168
|
expect(auth.flow?.signInRoute).toBe('/sign-in');
|
|
165
169
|
expect(auth.signUp?.signUpPolicy).toBe('requireVerification');
|
|
166
170
|
});
|
|
171
|
+
|
|
172
|
+
it('requires data for successful non-void storage results', () => {
|
|
173
|
+
const uploaded: StorageResult<StorageUploadResult> = {
|
|
174
|
+
ok: true,
|
|
175
|
+
data: {
|
|
176
|
+
asset: {
|
|
177
|
+
storageId: 'default',
|
|
178
|
+
bucket: 'app-assets',
|
|
179
|
+
path: 'images/logo.png',
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
expect(uploaded.ok).toBe(true);
|
|
185
|
+
expect(uploaded.data.asset.bucket).toBe('app-assets');
|
|
186
|
+
expect(uploaded.data.asset.path).toBe('images/logo.png');
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('accepts a public URL result for storage assets', () => {
|
|
190
|
+
const resolved: StorageResult<StoragePublicUrlResult> = {
|
|
191
|
+
ok: true,
|
|
192
|
+
data: {
|
|
193
|
+
publicUrl: 'https://cdn.example.com/app-assets/images/logo.png',
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
expect(resolved.ok).toBe(true);
|
|
198
|
+
expect(resolved.data.publicUrl).toContain('https://');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('serializes image asset sources without provider-specific runtime values', () => {
|
|
202
|
+
const source: ImageAssetSource = {
|
|
203
|
+
kind: 'storage',
|
|
204
|
+
storageId: 'default',
|
|
205
|
+
bucket: 'app-assets',
|
|
206
|
+
path: 'images/logo.png',
|
|
207
|
+
publicUrl: 'https://cdn.example.com/app-assets/images/logo.png',
|
|
208
|
+
alt: 'Logo',
|
|
209
|
+
width: 1200,
|
|
210
|
+
height: 630,
|
|
211
|
+
contentType: 'image/png',
|
|
212
|
+
metadata: {
|
|
213
|
+
fileName: 'logo.png',
|
|
214
|
+
sizeBytes: 123456,
|
|
215
|
+
createdAt: '2026-05-10T00:00:00.000Z',
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
expect(JSON.parse(JSON.stringify(source))).toEqual(source);
|
|
220
|
+
});
|
|
167
221
|
});
|
package/src/index.ts
CHANGED
package/src/storage.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export interface StorageAdapterError {
|
|
2
|
+
code: string;
|
|
3
|
+
message: string;
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type StorageOkResult<TData> = [TData] extends [void]
|
|
8
|
+
? { ok: true; data?: undefined }
|
|
9
|
+
: { ok: true; data: TData };
|
|
10
|
+
|
|
11
|
+
export type StorageResult<TData = void> =
|
|
12
|
+
| StorageOkResult<TData>
|
|
13
|
+
| {
|
|
14
|
+
ok: false;
|
|
15
|
+
error: StorageAdapterError;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export interface StorageAssetReference {
|
|
19
|
+
storageId?: string;
|
|
20
|
+
bucket: string;
|
|
21
|
+
path: string;
|
|
22
|
+
publicUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StorageUploadInput {
|
|
26
|
+
storageId?: string;
|
|
27
|
+
bucket: string;
|
|
28
|
+
path: string;
|
|
29
|
+
body: Uint8Array;
|
|
30
|
+
contentType?: string;
|
|
31
|
+
cacheControl?: string;
|
|
32
|
+
upsert?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface StorageUploadResult {
|
|
36
|
+
asset: StorageAssetReference;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface StorageRemoveInput {
|
|
40
|
+
storageId?: string;
|
|
41
|
+
bucket: string;
|
|
42
|
+
path: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface StoragePublicUrlInput {
|
|
46
|
+
storageId?: string;
|
|
47
|
+
bucket: string;
|
|
48
|
+
path: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface StoragePublicUrlResult {
|
|
52
|
+
publicUrl: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ImageMetadata {
|
|
56
|
+
fileName?: string;
|
|
57
|
+
sizeBytes?: number;
|
|
58
|
+
createdAt?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface StorageImageAssetSource {
|
|
62
|
+
kind: 'storage';
|
|
63
|
+
storageId?: string;
|
|
64
|
+
bucket: string;
|
|
65
|
+
path: string;
|
|
66
|
+
publicUrl?: string;
|
|
67
|
+
alt?: string;
|
|
68
|
+
width?: number;
|
|
69
|
+
height?: number;
|
|
70
|
+
contentType?: string;
|
|
71
|
+
metadata?: ImageMetadata;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface UrlImageAssetSource {
|
|
75
|
+
kind: 'url';
|
|
76
|
+
url: string;
|
|
77
|
+
alt?: string;
|
|
78
|
+
width?: number;
|
|
79
|
+
height?: number;
|
|
80
|
+
contentType?: string;
|
|
81
|
+
metadata?: ImageMetadata;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type ImageAssetSource = StorageImageAssetSource | UrlImageAssetSource;
|
|
85
|
+
|
|
86
|
+
export interface StorageAdapter {
|
|
87
|
+
upload(input: StorageUploadInput): Promise<StorageResult<StorageUploadResult>>;
|
|
88
|
+
remove(input: StorageRemoveInput): Promise<StorageResult>;
|
|
89
|
+
publicUrl(input: StoragePublicUrlInput): Promise<StorageResult<StoragePublicUrlResult>>;
|
|
90
|
+
getImageMetadata?(input: StorageAssetReference): Promise<StorageResult<ImageMetadata>>;
|
|
91
|
+
}
|