@portablecore/integrations 0.1.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.
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @portablecore/integrations — Surface Capability Resolution
3
+ *
4
+ * The PEP bridge: translates platform integration configuration into
5
+ * `CredentialAvailability[]` that surfaces pass to experts at invocation time.
6
+ *
7
+ * An expert's capabilities are intrinsic — it *knows* how to send SMS,
8
+ * generate presentations, process payments. But whether it *can* do those
9
+ * things on a given surface depends on what integrations that surface has
10
+ * configured. This module answers the question:
11
+ *
12
+ * "What can this surface actually do?"
13
+ *
14
+ * @see {@link https://github.com/portableteam/portablecore/docs/SHARED_INTEGRATIONS_VISION.md}
15
+ */
16
+ import type { AnySupabaseClient } from "./types.js";
17
+ import type { CapabilityMapping } from "./types.js";
18
+ /**
19
+ * PEP §4.4 — Credential availability for a capability.
20
+ *
21
+ * This is structurally identical to `CredentialAvailability` from
22
+ * `@portablecore/types`. We define it here to avoid a runtime dependency
23
+ * on the types package (which is devDependencies-only for most consumers).
24
+ */
25
+ export interface CredentialAvailability {
26
+ /** Capability slug this credential enables */
27
+ capabilitySlug: string;
28
+ /** Credential type (e.g., "oauth:google", "apikey:perplexity") */
29
+ credentialType: string;
30
+ /** Whether credentials are available and valid */
31
+ isAvailable: boolean;
32
+ /** Connection status */
33
+ status?: "connected" | "expired" | "error" | "not_configured";
34
+ }
35
+ /**
36
+ * Discover what integrations are available on this surface.
37
+ *
38
+ * Queries all active platform-level integrations, joins with
39
+ * `integration_providers` for slugs, then maps them to PEP
40
+ * `CredentialAvailability[]` using the capability mapping table.
41
+ *
42
+ * @param supabase - Service-role Supabase client
43
+ * @param platformIdentityId - Optional: scope to a specific platform.
44
+ * If not provided, checks the metaplatform first, then any platform.
45
+ * @param customMappings - Optional: override or extend the default
46
+ * provider-slug → capability mapping
47
+ * @returns Array of credential availability records for PEP invocation
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const capabilities = await getSurfaceCapabilities(supabase)
52
+ * // [
53
+ * // { capabilitySlug: "sms", credentialType: "apikey:twilio", isAvailable: true, status: "connected" },
54
+ * // { capabilitySlug: "email", credentialType: "apikey:postmark", isAvailable: true, status: "connected" },
55
+ * // ]
56
+ *
57
+ * // Pass to PEP invocation:
58
+ * const pepRequest = {
59
+ * credentials: { available: capabilities },
60
+ * // ...
61
+ * }
62
+ * ```
63
+ */
64
+ export declare function getSurfaceCapabilities(supabase: AnySupabaseClient, platformIdentityId?: string, customMappings?: CapabilityMapping[]): Promise<CredentialAvailability[]>;
65
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAMnD;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,cAAc,EAAE,MAAM,CAAA;IACtB,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAA;IACtB,kDAAkD;IAClD,WAAW,EAAE,OAAO,CAAA;IACpB,wBAAwB;IACxB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,gBAAgB,CAAA;CAC9D;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,iBAAiB,EAC3B,kBAAkB,CAAC,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,iBAAiB,EAAE,GACnC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAkGnC"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * @portablecore/integrations — Surface Capability Resolution
4
+ *
5
+ * The PEP bridge: translates platform integration configuration into
6
+ * `CredentialAvailability[]` that surfaces pass to experts at invocation time.
7
+ *
8
+ * An expert's capabilities are intrinsic — it *knows* how to send SMS,
9
+ * generate presentations, process payments. But whether it *can* do those
10
+ * things on a given surface depends on what integrations that surface has
11
+ * configured. This module answers the question:
12
+ *
13
+ * "What can this surface actually do?"
14
+ *
15
+ * @see {@link https://github.com/portableteam/portablecore/docs/SHARED_INTEGRATIONS_VISION.md}
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.getSurfaceCapabilities = getSurfaceCapabilities;
19
+ const types_js_1 = require("./types.js");
20
+ // ---------------------------------------------------------------------------
21
+ // Surface Capabilities
22
+ // ---------------------------------------------------------------------------
23
+ /**
24
+ * Discover what integrations are available on this surface.
25
+ *
26
+ * Queries all active platform-level integrations, joins with
27
+ * `integration_providers` for slugs, then maps them to PEP
28
+ * `CredentialAvailability[]` using the capability mapping table.
29
+ *
30
+ * @param supabase - Service-role Supabase client
31
+ * @param platformIdentityId - Optional: scope to a specific platform.
32
+ * If not provided, checks the metaplatform first, then any platform.
33
+ * @param customMappings - Optional: override or extend the default
34
+ * provider-slug → capability mapping
35
+ * @returns Array of credential availability records for PEP invocation
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const capabilities = await getSurfaceCapabilities(supabase)
40
+ * // [
41
+ * // { capabilitySlug: "sms", credentialType: "apikey:twilio", isAvailable: true, status: "connected" },
42
+ * // { capabilitySlug: "email", credentialType: "apikey:postmark", isAvailable: true, status: "connected" },
43
+ * // ]
44
+ *
45
+ * // Pass to PEP invocation:
46
+ * const pepRequest = {
47
+ * credentials: { available: capabilities },
48
+ * // ...
49
+ * }
50
+ * ```
51
+ */
52
+ async function getSurfaceCapabilities(supabase, platformIdentityId, customMappings) {
53
+ const mappings = customMappings || types_js_1.DEFAULT_CAPABILITY_MAPPINGS;
54
+ try {
55
+ // Build a set of provider slugs we care about
56
+ const slugsOfInterest = mappings.map((m) => m.providerSlug);
57
+ // Get provider IDs for the slugs we're mapping
58
+ const { data: providers, error: providerError } = await supabase
59
+ .from("integration_providers")
60
+ .select("id, slug")
61
+ .in("slug", slugsOfInterest);
62
+ if (providerError || !providers?.length) {
63
+ return mappings.map((m) => ({
64
+ capabilitySlug: m.capabilitySlug,
65
+ credentialType: m.credentialType,
66
+ isAvailable: false,
67
+ status: "not_configured",
68
+ }));
69
+ }
70
+ // Build a map of provider ID → slug for fast lookup
71
+ const providerIdToSlug = new Map();
72
+ for (const p of providers) {
73
+ providerIdToSlug.set(p.id, p.slug);
74
+ }
75
+ // Query active integrations for these providers
76
+ const providerIds = providers.map((p) => p.id);
77
+ let integrationQuery = supabase
78
+ .from("integrations")
79
+ .select("provider_id, is_active, config, access_token")
80
+ .in("provider_id", providerIds)
81
+ .eq("context_type", "platform")
82
+ .eq("is_active", true);
83
+ // Scope to specific platform if provided
84
+ if (platformIdentityId) {
85
+ integrationQuery = integrationQuery.eq("platform_identity_id", platformIdentityId);
86
+ }
87
+ const { data: integrations, error: intError } = await integrationQuery;
88
+ if (intError) {
89
+ console.warn("[Integrations] Failed to query integrations for capabilities:", intError.message);
90
+ }
91
+ // Build a set of provider slugs that have active integrations
92
+ const activeProviderSlugs = new Set();
93
+ if (integrations) {
94
+ for (const integration of integrations) {
95
+ const slug = providerIdToSlug.get(integration.provider_id);
96
+ if (slug) {
97
+ // Verify the integration has meaningful config or credentials
98
+ const hasToken = !!integration.access_token;
99
+ const hasConfig = integration.config &&
100
+ typeof integration.config === "object" &&
101
+ Object.keys(integration.config).length > 0;
102
+ if (hasToken || hasConfig) {
103
+ activeProviderSlugs.add(slug);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ // If no platform-scoped results, try metaplatform fallback
109
+ if (activeProviderSlugs.size === 0 && !platformIdentityId) {
110
+ const metaCapabilities = await tryMetaplatformCapabilities(supabase, providerIds, providerIdToSlug, mappings);
111
+ if (metaCapabilities)
112
+ return metaCapabilities;
113
+ }
114
+ // Map to CredentialAvailability
115
+ return mappings.map((m) => {
116
+ const isActive = activeProviderSlugs.has(m.providerSlug);
117
+ return {
118
+ capabilitySlug: m.capabilitySlug,
119
+ credentialType: m.credentialType,
120
+ isAvailable: isActive,
121
+ status: isActive ? "connected" : "not_configured",
122
+ };
123
+ });
124
+ }
125
+ catch (err) {
126
+ console.error("[Integrations] Error resolving surface capabilities:", err);
127
+ return mappings.map((m) => ({
128
+ capabilitySlug: m.capabilitySlug,
129
+ credentialType: m.credentialType,
130
+ isAvailable: false,
131
+ status: "error",
132
+ }));
133
+ }
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Metaplatform Fallback
137
+ // ---------------------------------------------------------------------------
138
+ async function tryMetaplatformCapabilities(supabase, providerIds, providerIdToSlug, mappings) {
139
+ try {
140
+ const { data: meta } = await supabase
141
+ .from("platform_identity")
142
+ .select("id")
143
+ .eq("is_metaplatform", true)
144
+ .maybeSingle();
145
+ if (!meta?.id)
146
+ return null;
147
+ const { data: integrations } = await supabase
148
+ .from("integrations")
149
+ .select("provider_id, is_active, config, access_token")
150
+ .in("provider_id", providerIds)
151
+ .eq("context_type", "platform")
152
+ .eq("platform_identity_id", meta.id)
153
+ .eq("is_active", true);
154
+ if (!integrations?.length)
155
+ return null;
156
+ const activeSlugs = new Set();
157
+ for (const integration of integrations) {
158
+ const slug = providerIdToSlug.get(integration.provider_id);
159
+ if (slug) {
160
+ const hasToken = !!integration.access_token;
161
+ const hasConfig = integration.config &&
162
+ typeof integration.config === "object" &&
163
+ Object.keys(integration.config).length > 0;
164
+ if (hasToken || hasConfig) {
165
+ activeSlugs.add(slug);
166
+ }
167
+ }
168
+ }
169
+ if (activeSlugs.size === 0)
170
+ return null;
171
+ return mappings.map((m) => {
172
+ const isActive = activeSlugs.has(m.providerSlug);
173
+ return {
174
+ capabilitySlug: m.capabilitySlug,
175
+ credentialType: m.credentialType,
176
+ isAvailable: isActive,
177
+ status: isActive ? "connected" : "not_configured",
178
+ };
179
+ });
180
+ }
181
+ catch {
182
+ // platform_identity may not exist — expected on Expert
183
+ return null;
184
+ }
185
+ }
186
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @portablecore/integrations — Credential Resolution
3
+ *
4
+ * The core of the package: resolves integration credentials from the
5
+ * `integrations` table with a well-defined fallback chain.
6
+ *
7
+ * Resolution order:
8
+ * 1. Account-level (BYOK) — if scope.accountId provided
9
+ * 2. User-level (OAuth tokens) — if scope.userId provided
10
+ * 3. Platform-specific — if scope.platformIdentityId provided
11
+ * 4. Metaplatform fallback — auto-detected via platform_identity.is_metaplatform
12
+ * 5. Any active platform integration — legacy catch-all
13
+ *
14
+ * This generalizes what Expert's `getProviderApiKey()` does for AI providers
15
+ * and what `getTwilioConfig()` does for Twilio into a single function.
16
+ */
17
+ import type { AnySupabaseClient, ConfigSource, ProviderConfigResult, ProviderScope } from "./types.js";
18
+ /**
19
+ * Resolve integration credentials for a provider with scope-based fallback.
20
+ *
21
+ * @param supabase - Service-role Supabase client (bypasses RLS)
22
+ * @param providerSlug - Provider slug (e.g. "twilio", "postmark", "openai")
23
+ * @param scope - Optional scope to control the fallback chain
24
+ * @returns The resolved config, or null if no active integration is found
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * // Platform-level Twilio config
29
+ * const twilio = await getProviderConfig<TwilioConfig>(supabase, "twilio")
30
+ *
31
+ * // BYOK with account fallback
32
+ * const openai = await getProviderConfig(supabase, "openai", {
33
+ * accountId: "acc_123",
34
+ * })
35
+ * // openai.source === "account" | "platform"
36
+ * ```
37
+ */
38
+ export declare function getProviderConfig<T = Record<string, unknown>>(supabase: AnySupabaseClient, providerSlug: string, scope?: ProviderScope): Promise<ProviderConfigResult<T> | null>;
39
+ /**
40
+ * Shorthand for getting just the API key string for a provider.
41
+ *
42
+ * Checks `access_token` first, then `config.api_key`, then
43
+ * `credentials.api_key`. Returns null if none found.
44
+ *
45
+ * @param supabase - Service-role Supabase client
46
+ * @param providerSlug - Provider slug
47
+ * @param scope - Optional scope
48
+ * @returns The API key string and its source, or null
49
+ */
50
+ export declare function getProviderApiKey(supabase: AnySupabaseClient, providerSlug: string, scope?: ProviderScope): Promise<{
51
+ apiKey: string;
52
+ source: ConfigSource;
53
+ providerId: string;
54
+ } | null>;
55
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACd,MAAM,YAAY,CAAA;AAMnB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,QAAQ,EAAE,iBAAiB,EAC3B,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAwBzC;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,iBAAiB,EAC3B,YAAY,EAAE,MAAM,EACpB,KAAK,CAAC,EAAE,aAAa,GACpB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAkC9E"}
package/dist/config.js ADDED
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ /**
3
+ * @portablecore/integrations — Credential Resolution
4
+ *
5
+ * The core of the package: resolves integration credentials from the
6
+ * `integrations` table with a well-defined fallback chain.
7
+ *
8
+ * Resolution order:
9
+ * 1. Account-level (BYOK) — if scope.accountId provided
10
+ * 2. User-level (OAuth tokens) — if scope.userId provided
11
+ * 3. Platform-specific — if scope.platformIdentityId provided
12
+ * 4. Metaplatform fallback — auto-detected via platform_identity.is_metaplatform
13
+ * 5. Any active platform integration — legacy catch-all
14
+ *
15
+ * This generalizes what Expert's `getProviderApiKey()` does for AI providers
16
+ * and what `getTwilioConfig()` does for Twilio into a single function.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.getProviderConfig = getProviderConfig;
20
+ exports.getProviderApiKey = getProviderApiKey;
21
+ const provider_js_1 = require("./provider.js");
22
+ // ---------------------------------------------------------------------------
23
+ // Main Resolver
24
+ // ---------------------------------------------------------------------------
25
+ /**
26
+ * Resolve integration credentials for a provider with scope-based fallback.
27
+ *
28
+ * @param supabase - Service-role Supabase client (bypasses RLS)
29
+ * @param providerSlug - Provider slug (e.g. "twilio", "postmark", "openai")
30
+ * @param scope - Optional scope to control the fallback chain
31
+ * @returns The resolved config, or null if no active integration is found
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // Platform-level Twilio config
36
+ * const twilio = await getProviderConfig<TwilioConfig>(supabase, "twilio")
37
+ *
38
+ * // BYOK with account fallback
39
+ * const openai = await getProviderConfig(supabase, "openai", {
40
+ * accountId: "acc_123",
41
+ * })
42
+ * // openai.source === "account" | "platform"
43
+ * ```
44
+ */
45
+ async function getProviderConfig(supabase, providerSlug, scope) {
46
+ // 1. Resolve provider ID
47
+ const provider = await (0, provider_js_1.getProvider)(supabase, providerSlug);
48
+ if (!provider) {
49
+ console.warn(`[Integrations] Provider not found: "${providerSlug}"`);
50
+ return null;
51
+ }
52
+ // 2. Walk the fallback chain
53
+ const steps = buildFallbackChain(scope);
54
+ for (const step of steps) {
55
+ const result = await queryIntegration(supabase, provider.id, step);
56
+ if (result) {
57
+ return { ...result, providerId: provider.id };
58
+ }
59
+ }
60
+ // 3. No integration found at any level
61
+ console.warn(`[Integrations] No active integration for "${providerSlug}"`, scope ? `(scope: ${JSON.stringify(scope)})` : "(no scope)");
62
+ return null;
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // Convenience: Get API Key
66
+ // ---------------------------------------------------------------------------
67
+ /**
68
+ * Shorthand for getting just the API key string for a provider.
69
+ *
70
+ * Checks `access_token` first, then `config.api_key`, then
71
+ * `credentials.api_key`. Returns null if none found.
72
+ *
73
+ * @param supabase - Service-role Supabase client
74
+ * @param providerSlug - Provider slug
75
+ * @param scope - Optional scope
76
+ * @returns The API key string and its source, or null
77
+ */
78
+ async function getProviderApiKey(supabase, providerSlug, scope) {
79
+ const result = await getProviderConfig(supabase, providerSlug, scope);
80
+ if (!result)
81
+ return null;
82
+ // Try access_token first (most common for API keys)
83
+ if (result.accessToken) {
84
+ return {
85
+ apiKey: result.accessToken,
86
+ source: result.source,
87
+ providerId: result.providerId,
88
+ };
89
+ }
90
+ // Try config.api_key
91
+ const configKey = result.config?.api_key;
92
+ if (typeof configKey === "string" && configKey) {
93
+ return {
94
+ apiKey: configKey,
95
+ source: result.source,
96
+ providerId: result.providerId,
97
+ };
98
+ }
99
+ // Try credentials.api_key
100
+ const credKey = result.credentials?.api_key;
101
+ if (typeof credKey === "string" && credKey) {
102
+ return {
103
+ apiKey: credKey,
104
+ source: result.source,
105
+ providerId: result.providerId,
106
+ };
107
+ }
108
+ return null;
109
+ }
110
+ /**
111
+ * Build the ordered list of integration lookups to try.
112
+ */
113
+ function buildFallbackChain(scope) {
114
+ const steps = [];
115
+ // 1. Account-level (BYOK)
116
+ if (scope?.accountId) {
117
+ steps.push({
118
+ source: "account",
119
+ contextType: "account",
120
+ filters: { account_id: scope.accountId },
121
+ });
122
+ }
123
+ // 2. User-level (OAuth tokens)
124
+ if (scope?.userId) {
125
+ steps.push({
126
+ source: "user",
127
+ contextType: "user",
128
+ filters: { user_id: scope.userId },
129
+ });
130
+ }
131
+ // 3. Platform-specific
132
+ if (scope?.platformIdentityId) {
133
+ steps.push({
134
+ source: "platform",
135
+ contextType: "platform",
136
+ filters: { platform_identity_id: scope.platformIdentityId },
137
+ });
138
+ }
139
+ // 4. Metaplatform fallback (resolved dynamically in queryIntegration)
140
+ steps.push({
141
+ source: "metaplatform",
142
+ contextType: "platform",
143
+ filters: { __metaplatform: "true" }, // sentinel — resolved at query time
144
+ });
145
+ // 5. Any active platform integration (legacy catch-all)
146
+ steps.push({
147
+ source: "platform",
148
+ contextType: "platform",
149
+ filters: {},
150
+ });
151
+ return steps;
152
+ }
153
+ // ---------------------------------------------------------------------------
154
+ // Integration Query
155
+ // ---------------------------------------------------------------------------
156
+ /**
157
+ * Query the `integrations` table for a single matching row.
158
+ */
159
+ async function queryIntegration(supabase, providerId, step) {
160
+ try {
161
+ // Handle metaplatform sentinel
162
+ if (step.filters.__metaplatform) {
163
+ return await queryMetaplatformIntegration(supabase, providerId, step.source);
164
+ }
165
+ let query = supabase
166
+ .from("integrations")
167
+ .select("id, config, credentials, settings, access_token")
168
+ .eq("provider_id", providerId)
169
+ .eq("context_type", step.contextType)
170
+ .eq("is_active", true);
171
+ // Apply scope filters
172
+ for (const [key, value] of Object.entries(step.filters)) {
173
+ if (value !== null && value !== undefined) {
174
+ query = query.eq(key, value);
175
+ }
176
+ }
177
+ const { data, error } = await query.maybeSingle();
178
+ if (error || !data)
179
+ return null;
180
+ return mapIntegrationRow(data, step.source);
181
+ }
182
+ catch {
183
+ // Column might not exist on some platforms — fail silently
184
+ return null;
185
+ }
186
+ }
187
+ /**
188
+ * Resolve the metaplatform's integration for a provider.
189
+ *
190
+ * Queries `platform_identity` for the metaplatform row, then looks up
191
+ * the integration scoped to that platform. Fails gracefully if the
192
+ * `platform_identity` table or `is_metaplatform` column doesn't exist
193
+ * (e.g. on Expert, which doesn't have multi-platform support yet).
194
+ */
195
+ async function queryMetaplatformIntegration(supabase, providerId, source) {
196
+ try {
197
+ // Find the metaplatform
198
+ const { data: meta, error: metaError } = await supabase
199
+ .from("platform_identity")
200
+ .select("id")
201
+ .eq("is_metaplatform", true)
202
+ .maybeSingle();
203
+ if (metaError || !meta?.id)
204
+ return null;
205
+ // Query integration for the metaplatform
206
+ const { data, error } = await supabase
207
+ .from("integrations")
208
+ .select("id, config, credentials, settings, access_token")
209
+ .eq("provider_id", providerId)
210
+ .eq("context_type", "platform")
211
+ .eq("platform_identity_id", meta.id)
212
+ .eq("is_active", true)
213
+ .maybeSingle();
214
+ if (error || !data)
215
+ return null;
216
+ return mapIntegrationRow(data, source);
217
+ }
218
+ catch {
219
+ // platform_identity table may not exist (Expert) — skip silently
220
+ return null;
221
+ }
222
+ }
223
+ // ---------------------------------------------------------------------------
224
+ // Row Mapping
225
+ // ---------------------------------------------------------------------------
226
+ function mapIntegrationRow(row, source) {
227
+ return {
228
+ config: (row.config || {}),
229
+ source,
230
+ integrationId: row.id,
231
+ accessToken: row.access_token,
232
+ credentials: row.credentials,
233
+ settings: row.settings,
234
+ };
235
+ }
236
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @portablecore/integrations
3
+ *
4
+ * Shared integration provider registry and credential resolution for
5
+ * Portable platforms. Extracted from Portable Expert's production
6
+ * integration system.
7
+ *
8
+ * Provides:
9
+ * - Provider lookup by slug (getProvider, getProviders, listProviders)
10
+ * - Credential resolution with scope-based fallback (getProviderConfig)
11
+ * - API key convenience helper (getProviderApiKey)
12
+ * - PEP capability discovery (getSurfaceCapabilities)
13
+ * - Platform-agnostic types
14
+ *
15
+ * All functions accept a Supabase client as a parameter so they work
16
+ * in any Portable platform (Expert, Team, Theater, etc.).
17
+ *
18
+ * "The expert brings expertise. The surface provides integrations."
19
+ */
20
+ export type { AnySupabaseClient, IntegrationProvider, ProviderScope, ProviderConfigResult, ConfigSource, CapabilityMapping, } from "./types.js";
21
+ export { DEFAULT_CAPABILITY_MAPPINGS } from "./types.js";
22
+ export { getProvider, getProviders, listProviders } from "./provider.js";
23
+ export { getProviderConfig, getProviderApiKey } from "./config.js";
24
+ export { getSurfaceCapabilities } from "./capabilities.js";
25
+ export type { CredentialAvailability } from "./capabilities.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAGxE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAGlE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * @portablecore/integrations
4
+ *
5
+ * Shared integration provider registry and credential resolution for
6
+ * Portable platforms. Extracted from Portable Expert's production
7
+ * integration system.
8
+ *
9
+ * Provides:
10
+ * - Provider lookup by slug (getProvider, getProviders, listProviders)
11
+ * - Credential resolution with scope-based fallback (getProviderConfig)
12
+ * - API key convenience helper (getProviderApiKey)
13
+ * - PEP capability discovery (getSurfaceCapabilities)
14
+ * - Platform-agnostic types
15
+ *
16
+ * All functions accept a Supabase client as a parameter so they work
17
+ * in any Portable platform (Expert, Team, Theater, etc.).
18
+ *
19
+ * "The expert brings expertise. The surface provides integrations."
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.getSurfaceCapabilities = exports.getProviderApiKey = exports.getProviderConfig = exports.listProviders = exports.getProviders = exports.getProvider = exports.DEFAULT_CAPABILITY_MAPPINGS = void 0;
23
+ var types_js_1 = require("./types.js");
24
+ Object.defineProperty(exports, "DEFAULT_CAPABILITY_MAPPINGS", { enumerable: true, get: function () { return types_js_1.DEFAULT_CAPABILITY_MAPPINGS; } });
25
+ // Provider lookup
26
+ var provider_js_1 = require("./provider.js");
27
+ Object.defineProperty(exports, "getProvider", { enumerable: true, get: function () { return provider_js_1.getProvider; } });
28
+ Object.defineProperty(exports, "getProviders", { enumerable: true, get: function () { return provider_js_1.getProviders; } });
29
+ Object.defineProperty(exports, "listProviders", { enumerable: true, get: function () { return provider_js_1.listProviders; } });
30
+ // Credential resolution
31
+ var config_js_1 = require("./config.js");
32
+ Object.defineProperty(exports, "getProviderConfig", { enumerable: true, get: function () { return config_js_1.getProviderConfig; } });
33
+ Object.defineProperty(exports, "getProviderApiKey", { enumerable: true, get: function () { return config_js_1.getProviderApiKey; } });
34
+ // PEP capability discovery
35
+ var capabilities_js_1 = require("./capabilities.js");
36
+ Object.defineProperty(exports, "getSurfaceCapabilities", { enumerable: true, get: function () { return capabilities_js_1.getSurfaceCapabilities; } });
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAYH,uCAAwD;AAA/C,uHAAA,2BAA2B,OAAA;AAEpC,kBAAkB;AAClB,6CAAwE;AAA/D,0GAAA,WAAW,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,4GAAA,aAAa,OAAA;AAEjD,wBAAwB;AACxB,yCAAkE;AAAzD,8GAAA,iBAAiB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAE7C,2BAA2B;AAC3B,qDAA0D;AAAjD,yHAAA,sBAAsB,OAAA"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @portablecore/integrations — Provider Lookup
3
+ *
4
+ * Canonical functions for querying the `integration_providers` table.
5
+ * Every other module in this package (and every consumer) should use
6
+ * these functions instead of querying `integration_providers` directly.
7
+ *
8
+ * The `slug` column is the canonical identifier across all platforms.
9
+ */
10
+ import type { AnySupabaseClient, IntegrationProvider } from "./types.js";
11
+ /**
12
+ * Look up an integration provider by its canonical slug.
13
+ *
14
+ * @param supabase - Any Supabase client (service-role recommended for server use)
15
+ * @param slug - Provider slug (e.g. "twilio", "postmark", "openai")
16
+ * @returns The provider record, or null if not found / inactive
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const twilio = await getProvider(supabase, "twilio")
21
+ * if (!twilio) throw new Error("Twilio not configured")
22
+ * ```
23
+ */
24
+ export declare function getProvider(supabase: AnySupabaseClient, slug: string): Promise<IntegrationProvider | null>;
25
+ /**
26
+ * Look up multiple integration providers by slug.
27
+ *
28
+ * @param supabase - Any Supabase client
29
+ * @param slugs - Array of provider slugs
30
+ * @returns Map of slug → IntegrationProvider (missing slugs are omitted)
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * const providers = await getProviders(supabase, ["twilio", "postmark"])
35
+ * const twilio = providers.get("twilio")
36
+ * ```
37
+ */
38
+ export declare function getProviders(supabase: AnySupabaseClient, slugs: string[]): Promise<Map<string, IntegrationProvider>>;
39
+ /**
40
+ * List all active integration providers.
41
+ *
42
+ * @param supabase - Any Supabase client
43
+ * @returns Array of all active providers, sorted by display_order
44
+ */
45
+ export declare function listProviders(supabase: AnySupabaseClient): Promise<IntegrationProvider[]>;
46
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAMxE;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAqBrC;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAyB3C;AAMD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAkBhC"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ /**
3
+ * @portablecore/integrations — Provider Lookup
4
+ *
5
+ * Canonical functions for querying the `integration_providers` table.
6
+ * Every other module in this package (and every consumer) should use
7
+ * these functions instead of querying `integration_providers` directly.
8
+ *
9
+ * The `slug` column is the canonical identifier across all platforms.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getProvider = getProvider;
13
+ exports.getProviders = getProviders;
14
+ exports.listProviders = listProviders;
15
+ // ---------------------------------------------------------------------------
16
+ // Single Provider Lookup
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Look up an integration provider by its canonical slug.
20
+ *
21
+ * @param supabase - Any Supabase client (service-role recommended for server use)
22
+ * @param slug - Provider slug (e.g. "twilio", "postmark", "openai")
23
+ * @returns The provider record, or null if not found / inactive
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const twilio = await getProvider(supabase, "twilio")
28
+ * if (!twilio) throw new Error("Twilio not configured")
29
+ * ```
30
+ */
31
+ async function getProvider(supabase, slug) {
32
+ try {
33
+ const { data, error } = await supabase
34
+ .from("integration_providers")
35
+ .select("id, slug, name, display_name, category, is_active, config_fields, auth_scopes")
36
+ .eq("slug", slug)
37
+ .single();
38
+ if (error || !data) {
39
+ if (error?.code !== "PGRST116") {
40
+ // PGRST116 = "no rows returned" — expected when provider doesn't exist
41
+ console.warn(`[Integrations] Provider lookup failed for "${slug}":`, error?.message);
42
+ }
43
+ return null;
44
+ }
45
+ return mapProviderRow(data);
46
+ }
47
+ catch (err) {
48
+ console.error(`[Integrations] Unexpected error looking up provider "${slug}":`, err);
49
+ return null;
50
+ }
51
+ }
52
+ // ---------------------------------------------------------------------------
53
+ // Multiple Provider Lookup
54
+ // ---------------------------------------------------------------------------
55
+ /**
56
+ * Look up multiple integration providers by slug.
57
+ *
58
+ * @param supabase - Any Supabase client
59
+ * @param slugs - Array of provider slugs
60
+ * @returns Map of slug → IntegrationProvider (missing slugs are omitted)
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * const providers = await getProviders(supabase, ["twilio", "postmark"])
65
+ * const twilio = providers.get("twilio")
66
+ * ```
67
+ */
68
+ async function getProviders(supabase, slugs) {
69
+ const result = new Map();
70
+ if (slugs.length === 0)
71
+ return result;
72
+ try {
73
+ const { data, error } = await supabase
74
+ .from("integration_providers")
75
+ .select("id, slug, name, display_name, category, is_active, config_fields, auth_scopes")
76
+ .in("slug", slugs);
77
+ if (error || !data) {
78
+ console.warn("[Integrations] Batch provider lookup failed:", error?.message);
79
+ return result;
80
+ }
81
+ for (const row of data) {
82
+ const provider = mapProviderRow(row);
83
+ result.set(provider.slug, provider);
84
+ }
85
+ }
86
+ catch (err) {
87
+ console.error("[Integrations] Unexpected error in batch provider lookup:", err);
88
+ }
89
+ return result;
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // All Active Providers
93
+ // ---------------------------------------------------------------------------
94
+ /**
95
+ * List all active integration providers.
96
+ *
97
+ * @param supabase - Any Supabase client
98
+ * @returns Array of all active providers, sorted by display_order
99
+ */
100
+ async function listProviders(supabase) {
101
+ try {
102
+ const { data, error } = await supabase
103
+ .from("integration_providers")
104
+ .select("id, slug, name, display_name, category, is_active, config_fields, auth_scopes")
105
+ .eq("is_active", true)
106
+ .order("display_order", { ascending: true });
107
+ if (error || !data) {
108
+ console.warn("[Integrations] Failed to list providers:", error?.message);
109
+ return [];
110
+ }
111
+ return data.map(mapProviderRow);
112
+ }
113
+ catch (err) {
114
+ console.error("[Integrations] Unexpected error listing providers:", err);
115
+ return [];
116
+ }
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Row Mapping
120
+ // ---------------------------------------------------------------------------
121
+ /**
122
+ * Map a raw database row to the typed IntegrationProvider interface.
123
+ * Handles column name differences (snake_case → camelCase).
124
+ */
125
+ function mapProviderRow(row) {
126
+ return {
127
+ id: row.id,
128
+ slug: row.slug,
129
+ name: row.name,
130
+ displayName: row.display_name || row.name,
131
+ category: row.category,
132
+ isActive: row.is_active !== false,
133
+ configFields: row.config_fields,
134
+ authScopes: row.auth_scopes,
135
+ };
136
+ }
137
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @portablecore/integrations — Type definitions
3
+ *
4
+ * Core types for integration provider lookup and credential resolution.
5
+ * These mirror the shared `integration_providers` and `integrations` tables
6
+ * that exist on every Portable platform (Expert, Team, Theater, etc.).
7
+ */
8
+ export type AnySupabaseClient = any;
9
+ /**
10
+ * A registered integration provider (Twilio, Postmark, OpenAI, etc.).
11
+ *
12
+ * Queried from the `integration_providers` table using `slug` as the
13
+ * canonical identifier.
14
+ */
15
+ export interface IntegrationProvider {
16
+ id: string;
17
+ slug: string;
18
+ name: string;
19
+ displayName: string;
20
+ category?: string;
21
+ isActive: boolean;
22
+ configFields?: unknown[];
23
+ authScopes?: string[];
24
+ }
25
+ /**
26
+ * Scope for credential resolution.
27
+ *
28
+ * Determines which `integrations` rows are checked and in what order:
29
+ * 1. Account-level (BYOK) — if `accountId` provided
30
+ * 2. User-level (OAuth tokens) — if `userId` provided
31
+ * 3. Platform-specific — if `platformIdentityId` provided
32
+ * 4. Metaplatform fallback — auto-detected via `is_metaplatform`
33
+ * 5. Any active platform integration — legacy catch-all
34
+ */
35
+ export interface ProviderScope {
36
+ /** Check account-level integration first (BYOK API keys) */
37
+ accountId?: string;
38
+ /** Check user-level integration (OAuth tokens) */
39
+ userId?: string;
40
+ /** Check a specific platform's integration */
41
+ platformIdentityId?: string;
42
+ }
43
+ /**
44
+ * The resolved configuration for an integration provider.
45
+ *
46
+ * Generic parameter `T` allows callers to type the config object:
47
+ * ```ts
48
+ * const result = await getProviderConfig<TwilioConfig>(supabase, "twilio")
49
+ * result?.config.accountSid // typed
50
+ * ```
51
+ */
52
+ export interface ProviderConfigResult<T = Record<string, unknown>> {
53
+ /** The integration's JSONB config, typed by the caller */
54
+ config: T;
55
+ /** Where the credential was resolved from */
56
+ source: ConfigSource;
57
+ /** The integration_providers.id */
58
+ providerId: string;
59
+ /** The integrations.id */
60
+ integrationId: string;
61
+ /** The access_token column (API keys, OAuth tokens) */
62
+ accessToken?: string;
63
+ /** The credentials JSONB column (structured secrets) */
64
+ credentials?: Record<string, unknown>;
65
+ /** The settings JSONB column (non-secret configuration) */
66
+ settings?: Record<string, unknown>;
67
+ }
68
+ export type ConfigSource = "account" | "user" | "platform" | "metaplatform";
69
+ /**
70
+ * Maps an integration provider category to a PEP credential type.
71
+ *
72
+ * Used by `getSurfaceCapabilities()` to translate database rows into
73
+ * the `CredentialAvailability` type that PEP invocations consume.
74
+ */
75
+ export interface CapabilityMapping {
76
+ /** The integration_providers slug (e.g. "twilio") */
77
+ providerSlug: string;
78
+ /** The PEP capability slug (e.g. "sms") */
79
+ capabilitySlug: string;
80
+ /** The PEP credential type (e.g. "apikey:twilio") */
81
+ credentialType: string;
82
+ }
83
+ /**
84
+ * Default mappings from provider slugs to PEP capabilities.
85
+ *
86
+ * Surfaces use these to tell experts what actions are available.
87
+ * This list grows as new integrations are added to the platform.
88
+ */
89
+ export declare const DEFAULT_CAPABILITY_MAPPINGS: CapabilityMapping[];
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAMnC;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAMD;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8CAA8C;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/D,0DAA0D;IAC1D,MAAM,EAAE,CAAC,CAAA;IACT,6CAA6C;IAC7C,MAAM,EAAE,YAAY,CAAA;IACpB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,0BAA0B;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc,CAAA;AAM3E;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAA;IACpB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAA;IACtB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,EAAE,iBAAiB,EAS1D,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * @portablecore/integrations — Type definitions
4
+ *
5
+ * Core types for integration provider lookup and credential resolution.
6
+ * These mirror the shared `integration_providers` and `integrations` tables
7
+ * that exist on every Portable platform (Expert, Team, Theater, etc.).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DEFAULT_CAPABILITY_MAPPINGS = void 0;
11
+ /**
12
+ * Default mappings from provider slugs to PEP capabilities.
13
+ *
14
+ * Surfaces use these to tell experts what actions are available.
15
+ * This list grows as new integrations are added to the platform.
16
+ */
17
+ exports.DEFAULT_CAPABILITY_MAPPINGS = [
18
+ { providerSlug: "twilio", capabilitySlug: "sms", credentialType: "apikey:twilio" },
19
+ { providerSlug: "postmark", capabilitySlug: "email", credentialType: "apikey:postmark" },
20
+ { providerSlug: "stripe", capabilitySlug: "payments", credentialType: "apikey:stripe" },
21
+ { providerSlug: "gamma", capabilitySlug: "presentations", credentialType: "oauth:gamma" },
22
+ { providerSlug: "google-classroom", capabilitySlug: "classroom", credentialType: "oauth:google-classroom" },
23
+ { providerSlug: "google-calendar", capabilitySlug: "calendar", credentialType: "oauth:google-calendar" },
24
+ { providerSlug: "lucidlink", capabilitySlug: "storage", credentialType: "apikey:lucidlink" },
25
+ { providerSlug: "wistia", capabilitySlug: "video", credentialType: "apikey:wistia" },
26
+ ];
27
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAoGH;;;;;GAKG;AACU,QAAA,2BAA2B,GAAwB;IAC9D,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE;IAClF,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE;IACxF,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE;IACvF,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE;IACzF,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,wBAAwB,EAAE;IAC3G,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,uBAAuB,EAAE;IACxG,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE;IAC5F,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE;CACrF,CAAA"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@portablecore/integrations",
3
+ "version": "0.1.0",
4
+ "description": "Shared integration provider registry and credential resolution for Portable platforms",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./provider": {
13
+ "types": "./dist/provider.d.ts",
14
+ "default": "./dist/provider.js"
15
+ },
16
+ "./config": {
17
+ "types": "./dist/config.d.ts",
18
+ "default": "./dist/config.js"
19
+ },
20
+ "./capabilities": {
21
+ "types": "./dist/capabilities.d.ts",
22
+ "default": "./dist/capabilities.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "dev": "tsc --watch",
31
+ "clean": "rm -rf dist",
32
+ "typecheck": "tsc --noEmit"
33
+ },
34
+ "keywords": [
35
+ "portable",
36
+ "integrations",
37
+ "provider",
38
+ "credentials",
39
+ "pep"
40
+ ],
41
+ "author": "Portable",
42
+ "license": "UNLICENSED",
43
+ "peerDependencies": {
44
+ "@supabase/supabase-js": "^2.0.0"
45
+ },
46
+ "devDependencies": {
47
+ "@supabase/supabase-js": "^2.49.0",
48
+ "typescript": "^5.3.0"
49
+ }
50
+ }