@stackable-labs/sdk-extension-contracts 1.0.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/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ LICENSE
2
+
3
+ Copyright (c) 2026-present UNIQUELY PARTICULAR LLC, STACKABLE LABS, LLC, agnoStack, Inc., and Adam Grohs ("Author" herein)
4
+
5
+ Permission is hereby granted to use, copy, and modify this software
6
+ (the "Software") solely for the purpose of developing, testing,
7
+ or maintaining integration with Author's products and services.
8
+
9
+ The Software may not be used:
10
+ - as a standalone product or service,
11
+ - to integrate with any platform or service other than Author's,
12
+ - to build or enhance a competing product or service,
13
+ - or for any purpose unrelated to integrations with Author.
14
+
15
+ Redistribution of the Software, in whole or in part, is permitted
16
+ only as part of an application or service that integrates with Author
17
+ and does not expose the Software as a general-purpose library.
18
+
19
+ This Software is provided "AS IS", without warranty of any kind, express
20
+ or implied, including but not limited to the warranties of merchantability,
21
+ fitness for a particular purpose, and noninfringement.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ PUBLISHER, AUTHORS, ANY CONTRIBUTOR OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
28
+ OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
29
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # @stackable-labs/sdk-extension-contracts
2
+
3
+ TypeScript contracts, interfaces, and types for building Stackable extensions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @stackable-labs/sdk-extension-contracts
9
+ ```
10
+
11
+ ## What's included
12
+
13
+ - Extension manifest types (`ExtensionManifest`, `ExtensionRegistryEntry`)
14
+ - Permission interfaces and identifiers
15
+ - Target/slot type definitions
16
+ - Shared RPC protocol types used across the Stackable SDK
17
+ - Domain types (`Customer`, `Order`, etc.) for ecommerce capability responses
18
+
19
+ ## Usage
20
+
21
+ ```ts
22
+ import type { ExtensionManifest, CapabilityCall, Order } from '@stackable-labs/sdk-extension-contracts';
23
+ ```
24
+
25
+ ## Changelog
26
+
27
+ See [npm version history](https://www.npmjs.com/package/@stackable-labs/sdk-extension-contracts?activeTab=versions).
28
+
29
+ ## License
30
+
31
+ SEE LICENSE IN [LICENSE](./LICENSE)
package/dist/api.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ export interface ApiRequest {
2
+ action: 'getOrder' | 'getOrders' | 'getCustomer';
3
+ orderId?: string;
4
+ customerId?: string;
5
+ email?: string;
6
+ }
7
+ export interface ApiResponse<T = unknown> {
8
+ success: boolean;
9
+ data: T;
10
+ action: string;
11
+ }
12
+ export interface ApiError {
13
+ error: string;
14
+ status?: number;
15
+ message?: string;
16
+ }
package/dist/api.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Capabilities Contract
3
+ * Defines the host-mediated APIs that extensions can call via RPC.
4
+ */
5
+ import type { ApiRequest } from './api';
6
+ /** Payload for actions.toast capability */
7
+ export interface ToastPayload {
8
+ message: string;
9
+ type?: 'success' | 'error' | 'info' | 'warning';
10
+ duration?: number;
11
+ }
12
+ /** Payload for actions.invoke capability */
13
+ export interface ActionInvokePayload {
14
+ action: string;
15
+ payload?: Record<string, unknown>;
16
+ }
17
+ /** Context returned by context.read capability */
18
+ export interface ContextData {
19
+ customerId?: string;
20
+ customerEmail?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ /** Union of all capability call types */
24
+ export type CapabilityCall = {
25
+ type: 'data.query';
26
+ payload: ApiRequest;
27
+ } | {
28
+ type: 'actions.toast';
29
+ payload: ToastPayload;
30
+ } | {
31
+ type: 'actions.invoke';
32
+ payload: ActionInvokePayload;
33
+ } | {
34
+ type: 'context.read';
35
+ };
36
+ export type CapabilityType = CapabilityCall['type'];
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Capabilities Contract
3
+ * Defines the host-mediated APIs that extensions can call via RPC.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared primitive types used across contracts.
3
+ */
4
+ /** Lightweight reference to a named entity (e.g. extension, instance). */
5
+ export interface NamedEntity {
6
+ id: string;
7
+ name: string;
8
+ }
package/dist/common.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared primitive types used across contracts.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * UI Component Contract
3
+ * Defines the fixed set of UI tags that extensions can render.
4
+ * The host maps these to real React components.
5
+ */
6
+ export declare const UI_TAGS: readonly ["ui-card", "ui-card-content", "ui-card-header", "ui-button", "ui-text", "ui-heading", "ui-badge", "ui-input", "ui-stack", "ui-inline", "ui-separator", "ui-tabs", "ui-tabs-list", "ui-tabs-trigger", "ui-tabs-content", "ui-scroll-area", "ui-avatar", "ui-avatar-image", "ui-avatar-fallback", "ui-icon", "ui-link", "ui-menu", "ui-menu-item"];
7
+ export type UITag = (typeof UI_TAGS)[number];
8
+ /**
9
+ * Allowed attributes per UI tag.
10
+ * Host should reject any attributes not in this allowlist.
11
+ */
12
+ export declare const UI_TAG_ATTRIBUTES: Record<UITag, readonly string[]>;
13
+ /**
14
+ * Supported icon names (subset of lucide-react).
15
+ * Extensions reference icons by name; host renders the actual icon component.
16
+ */
17
+ export declare const ALLOWED_ICONS: readonly ["arrow-left", "calendar", "check-circle-2", "chevron-left", "chevron-right", "clock", "credit-card", "external-link", "help-circle", "info", "loader-2", "mail", "map-pin", "message-circle", "message-square", "package", "phone", "search", "shopping-bag", "sparkles", "truck", "user", "x-circle", "alert-circle", "book-open"];
18
+ export type AllowedIconName = (typeof ALLOWED_ICONS)[number];
@@ -0,0 +1,91 @@
1
+ /**
2
+ * UI Component Contract
3
+ * Defines the fixed set of UI tags that extensions can render.
4
+ * The host maps these to real React components.
5
+ */
6
+ export const UI_TAGS = [
7
+ 'ui-card',
8
+ 'ui-card-content',
9
+ 'ui-card-header',
10
+ 'ui-button',
11
+ 'ui-text',
12
+ 'ui-heading',
13
+ 'ui-badge',
14
+ 'ui-input',
15
+ 'ui-stack',
16
+ 'ui-inline',
17
+ 'ui-separator',
18
+ 'ui-tabs',
19
+ 'ui-tabs-list',
20
+ 'ui-tabs-trigger',
21
+ 'ui-tabs-content',
22
+ 'ui-scroll-area',
23
+ 'ui-avatar',
24
+ 'ui-avatar-image',
25
+ 'ui-avatar-fallback',
26
+ 'ui-icon',
27
+ 'ui-link',
28
+ 'ui-menu',
29
+ 'ui-menu-item'
30
+ ];
31
+ /**
32
+ * Allowed attributes per UI tag.
33
+ * Host should reject any attributes not in this allowlist.
34
+ */
35
+ export const UI_TAG_ATTRIBUTES = {
36
+ 'ui-card': ['className', 'onClick'],
37
+ 'ui-card-content': ['className'],
38
+ 'ui-card-header': ['className'],
39
+ 'ui-button': ['variant', 'size', 'disabled', 'onClick', 'type', 'className', 'title'],
40
+ 'ui-text': ['className', 'tone'],
41
+ 'ui-heading': ['level', 'className'],
42
+ 'ui-badge': ['variant', 'tone', 'className'],
43
+ 'ui-input': ['type', 'placeholder', 'value', 'onChange', 'disabled', 'className', 'id'],
44
+ 'ui-stack': ['gap', 'direction', 'align', 'className'],
45
+ 'ui-inline': ['gap', 'align', 'className'],
46
+ 'ui-separator': ['className'],
47
+ 'ui-tabs': ['defaultValue', 'className'],
48
+ 'ui-tabs-list': ['className'],
49
+ 'ui-tabs-trigger': ['value', 'className'],
50
+ 'ui-tabs-content': ['value', 'className'],
51
+ 'ui-scroll-area': ['className'],
52
+ 'ui-avatar': ['className'],
53
+ 'ui-avatar-image': ['src', 'alt', 'className'],
54
+ 'ui-avatar-fallback': ['className'],
55
+ 'ui-icon': ['name', 'size', 'className'],
56
+ 'ui-link': ['href', 'target', 'rel', 'className'],
57
+ 'ui-menu-item': ['icon', 'label', 'description', 'onClick', 'className'],
58
+ 'ui-menu': ['title', 'className'],
59
+ };
60
+ /**
61
+ * Supported icon names (subset of lucide-react).
62
+ * Extensions reference icons by name; host renders the actual icon component.
63
+ */
64
+ export const ALLOWED_ICONS = [
65
+ 'arrow-left',
66
+ 'calendar',
67
+ 'check-circle-2',
68
+ 'chevron-left',
69
+ 'chevron-right',
70
+ 'clock',
71
+ 'credit-card',
72
+ 'external-link',
73
+ 'help-circle',
74
+ 'info',
75
+ 'loader-2',
76
+ 'mail',
77
+ 'map-pin',
78
+ 'message-circle',
79
+ 'message-square',
80
+ 'package',
81
+ 'phone',
82
+ 'search',
83
+ 'shopping-bag',
84
+ 'sparkles',
85
+ 'truck',
86
+ 'user',
87
+ 'x-circle',
88
+ 'alert-circle',
89
+ 'book-open'
90
+ ];
91
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,SAAS;IACT,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,SAAS;IACT,YAAY;IACZ,UAAU;IACV,UAAU;IACV,UAAU;IACV,WAAW;IACX,cAAc;IACd,SAAS;IACT,cAAc;IACd,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,iBAAiB;IACjB,oBAAoB;IACpB,SAAS;IACT,SAAS;IACT,SAAS;IACT,cAAc;CACN,CAAA;AAIV;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAqC;IACjE,SAAS,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC;IACnC,iBAAiB,EAAE,CAAC,WAAW,CAAC;IAChC,gBAAgB,EAAE,CAAC,WAAW,CAAC;IAC/B,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC;IACrF,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IACpC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;IAC5C,UAAU,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,CAAC;IACvF,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC;IACtD,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC;IAC1C,cAAc,EAAE,CAAC,WAAW,CAAC;IAC7B,SAAS,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC;IACxC,cAAc,EAAE,CAAC,WAAW,CAAC;IAC7B,iBAAiB,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IACzC,gBAAgB,EAAE,CAAC,WAAW,CAAC;IAC/B,WAAW,EAAE,CAAC,WAAW,CAAC;IAC1B,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC;IAC9C,oBAAoB,EAAE,CAAC,WAAW,CAAC;IACnC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC;IACxC,SAAS,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC;IACjD,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,CAAC;IACxE,SAAS,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;CAClC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,YAAY;IACZ,UAAU;IACV,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,OAAO;IACP,aAAa;IACb,eAAe;IACf,aAAa;IACb,MAAM;IACN,UAAU;IACV,MAAM;IACN,SAAS;IACT,gBAAgB;IAChB,gBAAgB;IAChB,SAAS;IACT,OAAO;IACP,QAAQ;IACR,cAAc;IACd,UAAU;IACV,OAAO;IACP,MAAM;IACN,UAAU;IACV,cAAc;IACd,WAAW;CACH,CAAA"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Ecommerce Type Definitions
3
+ * Ported from zendesk-embedded-widget/app/src/types/ecommerce.ts
4
+ */
5
+ export interface Price {
6
+ currency: string;
7
+ amount: number;
8
+ precise: number;
9
+ rounded: string;
10
+ formatted: string;
11
+ }
12
+ export interface Address {
13
+ id: string;
14
+ type: 'address';
15
+ first_name: string;
16
+ last_name: string;
17
+ phone: string;
18
+ line_1: string;
19
+ line_2: string;
20
+ city: string;
21
+ region: string;
22
+ postcode: string;
23
+ country: string;
24
+ meta?: {
25
+ entity_id: string;
26
+ };
27
+ }
28
+ export type DataFieldType = 'data_boolean' | 'data_text' | 'data_pill' | 'data_badge' | 'data_price' | 'data_highlight' | 'data_datestamp';
29
+ export interface DataField {
30
+ identifier: string;
31
+ type: DataFieldType;
32
+ value: unknown;
33
+ editable?: boolean;
34
+ label?: string;
35
+ }
36
+ export interface Customer {
37
+ id: string;
38
+ url: string;
39
+ type: 'guest' | 'registered';
40
+ name: string;
41
+ first_name: string;
42
+ last_name: string;
43
+ email: string;
44
+ phone: string;
45
+ data: Array<{
46
+ data: DataField[];
47
+ provider: string;
48
+ }>;
49
+ meta: {
50
+ tags: {
51
+ data: string[];
52
+ };
53
+ entity_id: string;
54
+ total_orders: string;
55
+ };
56
+ relationships: {
57
+ notes: Array<{
58
+ id: string;
59
+ type: 'note';
60
+ messages: string[];
61
+ editable: boolean;
62
+ }>;
63
+ metadata: Array<{
64
+ identifier: string;
65
+ data: DataField[];
66
+ }>;
67
+ addresses: Address[];
68
+ };
69
+ }
70
+ export interface OrderStatus {
71
+ vendor: string;
72
+ color: string;
73
+ abbreviation: string;
74
+ label: string;
75
+ }
76
+ export interface OrderStatuses {
77
+ note: string;
78
+ alerts: unknown[];
79
+ isPaid: boolean;
80
+ isShipped: boolean;
81
+ isRefunded: boolean;
82
+ isCancelled: boolean;
83
+ isRefundable: boolean;
84
+ hasBalanceOwed: boolean;
85
+ isCancellable: boolean;
86
+ isModifiable: boolean;
87
+ order: OrderStatus;
88
+ payment: OrderStatus;
89
+ shipping: OrderStatus;
90
+ refund: OrderStatus;
91
+ }
92
+ export interface OrderItem {
93
+ id: string;
94
+ type: 'order_item' | 'custom_item';
95
+ sku: string;
96
+ name: string;
97
+ quantity: number;
98
+ refunded: number;
99
+ modified?: number;
100
+ url?: string;
101
+ statuses?: {
102
+ isShipped: boolean;
103
+ isModifiable: boolean;
104
+ };
105
+ meta: {
106
+ entity_id?: string;
107
+ timestamps: {
108
+ created_at: string;
109
+ updated_at: string;
110
+ };
111
+ actions?: Array<{
112
+ id: string;
113
+ type: string;
114
+ label: {
115
+ key: string;
116
+ };
117
+ url?: string;
118
+ }>;
119
+ product?: unknown;
120
+ price_mode?: string;
121
+ display_price: {
122
+ with_tax: {
123
+ unit: Price;
124
+ value: Price;
125
+ };
126
+ without_tax: {
127
+ unit: Price;
128
+ value: Price;
129
+ };
130
+ tax: {
131
+ unit: Price;
132
+ value: Price;
133
+ };
134
+ };
135
+ discount_price?: {
136
+ with_tax: {
137
+ unit: Price;
138
+ value: Price;
139
+ };
140
+ without_tax: {
141
+ unit: Price;
142
+ value: Price;
143
+ };
144
+ tax: {
145
+ unit: Price;
146
+ value: Price;
147
+ };
148
+ };
149
+ vendor?: string;
150
+ };
151
+ relationships?: {
152
+ shipping?: {
153
+ parcels?: Array<{
154
+ id: string;
155
+ shipment_status: string;
156
+ trackings: Array<{
157
+ tracking_number: string;
158
+ carrier: string;
159
+ carrier_code: string;
160
+ service_code?: string;
161
+ url?: string;
162
+ }>;
163
+ name?: string;
164
+ timestamps?: {
165
+ created_at: string;
166
+ };
167
+ }>;
168
+ };
169
+ };
170
+ }
171
+ export interface Shipment {
172
+ id: string;
173
+ shipping_address: Address;
174
+ }
175
+ export interface OrderAction {
176
+ id: string;
177
+ type: 'order_action';
178
+ label: {
179
+ key: string;
180
+ };
181
+ url?: string;
182
+ confirm?: boolean;
183
+ }
184
+ export interface Order {
185
+ id: string;
186
+ type: 'order';
187
+ url: string;
188
+ transaction_id: string;
189
+ statuses: OrderStatuses;
190
+ actions?: OrderAction[];
191
+ billing_address?: Address;
192
+ shipments: Shipment[];
193
+ relationships: {
194
+ items: {
195
+ data: OrderItem[];
196
+ };
197
+ transactions?: {
198
+ data: unknown[];
199
+ };
200
+ customer: {
201
+ data: {
202
+ type: 'customer';
203
+ id: string;
204
+ url: string;
205
+ name: string;
206
+ phone: string;
207
+ email: string;
208
+ };
209
+ };
210
+ };
211
+ meta: {
212
+ timestamps: {
213
+ created_at: string;
214
+ updated_at: string;
215
+ };
216
+ tax_mode: string;
217
+ entity_id: string;
218
+ tags: {
219
+ data: string[];
220
+ };
221
+ display_price: {
222
+ with_tax: Price;
223
+ without_tax: Price;
224
+ tax: Price;
225
+ };
226
+ display_balance_price?: {
227
+ with_tax: Price;
228
+ };
229
+ refundable_balance_price?: {
230
+ with_tax: Price;
231
+ };
232
+ };
233
+ display_status?: OrderStatus;
234
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Ecommerce Type Definitions
3
+ * Ported from zendesk-embedded-widget/app/src/types/ecommerce.ts
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=ecommerce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ecommerce.js","sourceRoot":"","sources":["../src/ecommerce.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,10 @@
1
+ export * from './common';
2
+ export * from './api';
3
+ export * from './components';
4
+ export * from './capabilities';
5
+ export * from './instance';
6
+ export * from './permissions';
7
+ export * from './manifest';
8
+ export * from './surface';
9
+ export * from './rpc';
10
+ export * from './ecommerce';
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ export * from './common';
2
+ export * from './api';
3
+ export * from './components';
4
+ export * from './capabilities';
5
+ export * from './instance';
6
+ export * from './permissions';
7
+ export * from './manifest';
8
+ export * from './surface';
9
+ export * from './rpc';
10
+ export * from './ecommerce';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,cAAc,CAAA;AAC5B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Instance Contract
3
+ * Shared types for extension instances used by both host and admin.
4
+ */
5
+ export type Theme = 'light' | 'dark';
6
+ export type InstanceSettings = {
7
+ theme?: Theme;
8
+ } & Record<string, unknown>;
9
+ export interface InstanceOption {
10
+ id: string;
11
+ name: string;
12
+ settings?: InstanceSettings;
13
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Instance Contract
3
+ * Shared types for extension instances used by both host and admin.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=instance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.js","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Extension Manifest Schema
3
+ * Declared by extension developers in manifest.json.
4
+ */
5
+ import type { Permission } from './permissions';
6
+ /**
7
+ * An extension point target identifier (e.g. "slot.header").
8
+ * Apps define which targets they expose; this is not a fixed list.
9
+ */
10
+ export type Target = string;
11
+ export interface ExtensionManifest {
12
+ /** Human-readable extension name */
13
+ name: string;
14
+ /** Semver version string */
15
+ version: string;
16
+ /** Extension point targets this extension renders into */
17
+ targets: string[];
18
+ /** Permissions required by this extension */
19
+ permissions: Permission[];
20
+ }
21
+ /**
22
+ * Registry entry for an installed extension (returned by /api/extensions).
23
+ */
24
+ export interface ExtensionRegistryEntry {
25
+ /** Unique extension ID */
26
+ id: string;
27
+ /** Extension manifest */
28
+ manifest: ExtensionManifest;
29
+ /** URL to the extension's JS bundle */
30
+ bundleUrl: string;
31
+ /** Whether the extension is enabled */
32
+ enabled: boolean;
33
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Extension Manifest Schema
3
+ * Declared by extension developers in manifest.json.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Permissions Contract
3
+ * Extensions declare required permissions in their manifest.
4
+ * Host enforces: capability calls must be a subset of granted permissions.
5
+ */
6
+ export declare const PERMISSIONS: readonly ["context:read", "data:query", "actions:toast", "actions:invoke"];
7
+ export type Permission = (typeof PERMISSIONS)[number];
8
+ /**
9
+ * Maps capability types to the permission required to use them.
10
+ */
11
+ export declare const CAPABILITY_PERMISSION_MAP: Record<string, Permission>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Permissions Contract
3
+ * Extensions declare required permissions in their manifest.
4
+ * Host enforces: capability calls must be a subset of granted permissions.
5
+ */
6
+ export const PERMISSIONS = [
7
+ 'context:read',
8
+ 'data:query',
9
+ 'actions:toast',
10
+ 'actions:invoke'
11
+ ];
12
+ /**
13
+ * Maps capability types to the permission required to use them.
14
+ */
15
+ export const CAPABILITY_PERMISSION_MAP = {
16
+ 'context.read': 'context:read',
17
+ 'data.query': 'data:query',
18
+ 'actions.toast': 'actions:toast',
19
+ 'actions.invoke': 'actions:invoke',
20
+ };
21
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc;IACd,YAAY;IACZ,eAAe;IACf,gBAAgB;CACR,CAAA;AAIV;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAA+B;IACnE,cAAc,EAAE,cAAc;IAC9B,YAAY,EAAE,YAAY;IAC1B,eAAe,EAAE,eAAe;IAChC,gBAAgB,EAAE,gBAAgB;CACnC,CAAA"}
package/dist/rpc.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * RPC Protocol Types
3
+ * Messages exchanged between sandbox (extension) and host for capability calls.
4
+ */
5
+ import type { CapabilityType } from './capabilities';
6
+ /** Request from extension sandbox to host */
7
+ export interface CapabilityRequest {
8
+ type: 'capability-request';
9
+ id: string;
10
+ capability: CapabilityType;
11
+ payload: unknown;
12
+ }
13
+ /** Response from host to extension sandbox */
14
+ export interface CapabilityResponse {
15
+ type: 'capability-response';
16
+ id: string;
17
+ success: boolean;
18
+ data?: unknown;
19
+ error?: string;
20
+ }
21
+ /** All message types that can be sent between host and sandbox */
22
+ export type HostToSandboxMessage = {
23
+ type: 'surface-lifecycle';
24
+ data: import('./surface.js').SurfaceLifecycleMessage;
25
+ } | CapabilityResponse | {
26
+ type: 'context-update';
27
+ surfaceId: string;
28
+ context: Record<string, unknown>;
29
+ };
30
+ export type SandboxToHostMessage = CapabilityRequest | {
31
+ type: 'surface-ready';
32
+ surfaceId: string;
33
+ } | {
34
+ type: 'extension-ready';
35
+ };
package/dist/rpc.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * RPC Protocol Types
3
+ * Messages exchanged between sandbox (extension) and host for capability calls.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=rpc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Surface Lifecycle Contract
3
+ * Messages exchanged between host and sandbox for surface management.
4
+ */
5
+ export interface SurfaceContext {
6
+ [key: string]: unknown;
7
+ }
8
+ export type SurfaceLifecycleMessage = {
9
+ type: 'createSurface';
10
+ surfaceId: string;
11
+ target: string;
12
+ context: SurfaceContext;
13
+ } | {
14
+ type: 'updateSurfaceContext';
15
+ surfaceId: string;
16
+ context: SurfaceContext;
17
+ } | {
18
+ type: 'destroySurface';
19
+ surfaceId: string;
20
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Surface Lifecycle Contract
3
+ * Messages exchanged between host and sandbox for surface management.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.js","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@stackable-labs/sdk-extension-contracts",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "description": "TypeScript contracts and interfaces for Stackable extensions.",
15
+ "license": "SEE LICENSE IN LICENSE",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "homepage": "https://www.npmjs.com/package/@stackable-labs/sdk-extension-contracts",
20
+ "files": [
21
+ "dist/",
22
+ "README.md",
23
+ "LICENSE"
24
+ ]
25
+ }