@commandable/mcp-core 0.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.
Files changed (157) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +8 -0
  3. package/dist/config/configApply.d.ts +16 -0
  4. package/dist/config/configApply.d.ts.map +1 -0
  5. package/dist/config/configApply.js +77 -0
  6. package/dist/config/configApply.js.map +1 -0
  7. package/dist/config/configLoader.d.ts +9 -0
  8. package/dist/config/configLoader.d.ts.map +1 -0
  9. package/dist/config/configLoader.js +75 -0
  10. package/dist/config/configLoader.js.map +1 -0
  11. package/dist/config/configSchema.d.ts +45 -0
  12. package/dist/config/configSchema.d.ts.map +1 -0
  13. package/dist/config/configSchema.js +23 -0
  14. package/dist/config/configSchema.js.map +1 -0
  15. package/dist/crypto/encryption.d.ts +3 -0
  16. package/dist/crypto/encryption.d.ts.map +1 -0
  17. package/dist/crypto/encryption.js +29 -0
  18. package/dist/crypto/encryption.js.map +1 -0
  19. package/dist/db/client.d.ts +24 -0
  20. package/dist/db/client.d.ts.map +1 -0
  21. package/dist/db/client.js +50 -0
  22. package/dist/db/client.js.map +1 -0
  23. package/dist/db/credentialStore.d.ts +15 -0
  24. package/dist/db/credentialStore.d.ts.map +1 -0
  25. package/dist/db/credentialStore.js +56 -0
  26. package/dist/db/credentialStore.js.map +1 -0
  27. package/dist/db/integrationStore.d.ts +14 -0
  28. package/dist/db/integrationStore.d.ts.map +1 -0
  29. package/dist/db/integrationStore.js +128 -0
  30. package/dist/db/integrationStore.js.map +1 -0
  31. package/dist/db/integrationTypeConfigStore.d.ts +7 -0
  32. package/dist/db/integrationTypeConfigStore.d.ts.map +1 -0
  33. package/dist/db/integrationTypeConfigStore.js +101 -0
  34. package/dist/db/integrationTypeConfigStore.js.map +1 -0
  35. package/dist/db/migrate.d.ts +3 -0
  36. package/dist/db/migrate.d.ts.map +1 -0
  37. package/dist/db/migrate.js +11 -0
  38. package/dist/db/migrate.js.map +1 -0
  39. package/dist/db/migrations/pg/0000_initial.sql +74 -0
  40. package/dist/db/migrations/pg/meta/_journal.json +13 -0
  41. package/dist/db/migrations/sqlite/0000_initial.sql +74 -0
  42. package/dist/db/migrations/sqlite/meta/_journal.json +13 -0
  43. package/dist/db/schema.d.ts +1863 -0
  44. package/dist/db/schema.d.ts.map +1 -0
  45. package/dist/db/schema.js +133 -0
  46. package/dist/db/schema.js.map +1 -0
  47. package/dist/db/toolDefinitionStore.d.ts +9 -0
  48. package/dist/db/toolDefinitionStore.d.ts.map +1 -0
  49. package/dist/db/toolDefinitionStore.js +117 -0
  50. package/dist/db/toolDefinitionStore.js.map +1 -0
  51. package/dist/errors/httpError.d.ts +6 -0
  52. package/dist/errors/httpError.d.ts.map +1 -0
  53. package/dist/errors/httpError.js +11 -0
  54. package/dist/errors/httpError.js.map +1 -0
  55. package/dist/index.d.ts +34 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +34 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/integrations/actionsFactory.d.ts +16 -0
  60. package/dist/integrations/actionsFactory.d.ts.map +1 -0
  61. package/dist/integrations/actionsFactory.js +98 -0
  62. package/dist/integrations/actionsFactory.js.map +1 -0
  63. package/dist/integrations/catalog.d.ts +8 -0
  64. package/dist/integrations/catalog.d.ts.map +1 -0
  65. package/dist/integrations/catalog.js +45 -0
  66. package/dist/integrations/catalog.js.map +1 -0
  67. package/dist/integrations/customToolFactory.d.ts +13 -0
  68. package/dist/integrations/customToolFactory.d.ts.map +1 -0
  69. package/dist/integrations/customToolFactory.js +31 -0
  70. package/dist/integrations/customToolFactory.js.map +1 -0
  71. package/dist/integrations/dataLoader.d.ts +3 -0
  72. package/dist/integrations/dataLoader.d.ts.map +1 -0
  73. package/dist/integrations/dataLoader.js +2 -0
  74. package/dist/integrations/dataLoader.js.map +1 -0
  75. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts +7 -0
  76. package/dist/integrations/fileIntegrationTypeConfigStore.d.ts.map +1 -0
  77. package/dist/integrations/fileIntegrationTypeConfigStore.js +34 -0
  78. package/dist/integrations/fileIntegrationTypeConfigStore.js.map +1 -0
  79. package/dist/integrations/getIntegration.d.ts +14 -0
  80. package/dist/integrations/getIntegration.d.ts.map +1 -0
  81. package/dist/integrations/getIntegration.js +30 -0
  82. package/dist/integrations/getIntegration.js.map +1 -0
  83. package/dist/integrations/googleServiceAccount.d.ts +6 -0
  84. package/dist/integrations/googleServiceAccount.d.ts.map +1 -0
  85. package/dist/integrations/googleServiceAccount.js +54 -0
  86. package/dist/integrations/googleServiceAccount.js.map +1 -0
  87. package/dist/integrations/health.d.ts +20 -0
  88. package/dist/integrations/health.d.ts.map +1 -0
  89. package/dist/integrations/health.js +43 -0
  90. package/dist/integrations/health.js.map +1 -0
  91. package/dist/integrations/integrationTypeConfigLookup.d.ts +12 -0
  92. package/dist/integrations/integrationTypeConfigLookup.d.ts.map +1 -0
  93. package/dist/integrations/integrationTypeConfigLookup.js +11 -0
  94. package/dist/integrations/integrationTypeConfigLookup.js.map +1 -0
  95. package/dist/integrations/providerRegistry.d.ts +2 -0
  96. package/dist/integrations/providerRegistry.d.ts.map +1 -0
  97. package/dist/integrations/providerRegistry.js +72 -0
  98. package/dist/integrations/providerRegistry.js.map +1 -0
  99. package/dist/integrations/proxy.d.ts +19 -0
  100. package/dist/integrations/proxy.d.ts.map +1 -0
  101. package/dist/integrations/proxy.js +377 -0
  102. package/dist/integrations/proxy.js.map +1 -0
  103. package/dist/integrations/sandbox.d.ts +8 -0
  104. package/dist/integrations/sandbox.d.ts.map +1 -0
  105. package/dist/integrations/sandbox.js +221 -0
  106. package/dist/integrations/sandbox.js.map +1 -0
  107. package/dist/integrations/sandboxUtils.d.ts +15 -0
  108. package/dist/integrations/sandboxUtils.d.ts.map +1 -0
  109. package/dist/integrations/sandboxUtils.js +489 -0
  110. package/dist/integrations/sandboxUtils.js.map +1 -0
  111. package/dist/integrations/tools.d.ts +3 -0
  112. package/dist/integrations/tools.d.ts.map +1 -0
  113. package/dist/integrations/tools.js +70 -0
  114. package/dist/integrations/tools.js.map +1 -0
  115. package/dist/mcp/abilityCatalog.d.ts +51 -0
  116. package/dist/mcp/abilityCatalog.d.ts.map +1 -0
  117. package/dist/mcp/abilityCatalog.js +300 -0
  118. package/dist/mcp/abilityCatalog.js.map +1 -0
  119. package/dist/mcp/auth.d.ts +18 -0
  120. package/dist/mcp/auth.d.ts.map +1 -0
  121. package/dist/mcp/auth.js +45 -0
  122. package/dist/mcp/auth.js.map +1 -0
  123. package/dist/mcp/builder_guide.md +441 -0
  124. package/dist/mcp/commandable_readme.md +29 -0
  125. package/dist/mcp/handlers.d.ts +21 -0
  126. package/dist/mcp/handlers.d.ts.map +1 -0
  127. package/dist/mcp/handlers.js +86 -0
  128. package/dist/mcp/handlers.js.map +1 -0
  129. package/dist/mcp/metaTools.d.ts +79 -0
  130. package/dist/mcp/metaTools.d.ts.map +1 -0
  131. package/dist/mcp/metaTools.js +901 -0
  132. package/dist/mcp/metaTools.js.map +1 -0
  133. package/dist/mcp/server.d.ts +25 -0
  134. package/dist/mcp/server.d.ts.map +1 -0
  135. package/dist/mcp/server.js +14 -0
  136. package/dist/mcp/server.js.map +1 -0
  137. package/dist/mcp/sessionState.d.ts +19 -0
  138. package/dist/mcp/sessionState.d.ts.map +1 -0
  139. package/dist/mcp/sessionState.js +79 -0
  140. package/dist/mcp/sessionState.js.map +1 -0
  141. package/dist/mcp/toolAdapter.d.ts +34 -0
  142. package/dist/mcp/toolAdapter.d.ts.map +1 -0
  143. package/dist/mcp/toolAdapter.js +24 -0
  144. package/dist/mcp/toolAdapter.js.map +1 -0
  145. package/dist/runtime/credentialManager.d.ts +19 -0
  146. package/dist/runtime/credentialManager.d.ts.map +1 -0
  147. package/dist/runtime/credentialManager.js +82 -0
  148. package/dist/runtime/credentialManager.js.map +1 -0
  149. package/dist/runtime/stdioSession.d.ts +8 -0
  150. package/dist/runtime/stdioSession.d.ts.map +1 -0
  151. package/dist/runtime/stdioSession.js +79 -0
  152. package/dist/runtime/stdioSession.js.map +1 -0
  153. package/dist/types.d.ts +92 -0
  154. package/dist/types.d.ts.map +1 -0
  155. package/dist/types.js +2 -0
  156. package/dist/types.js.map +1 -0
  157. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ GNU AFFERO GENERAL PUBLIC LICENSE
2
+ Version 3, 19 November 2007
3
+
4
+ This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
5
+
6
+ You may obtain a copy of the license at:
7
+ https://www.gnu.org/licenses/agpl-3.0.html
8
+
9
+ SPDX-License-Identifier: AGPL-3.0-only
10
+
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # @commandable/mcp-core
2
+
3
+ Shared runtime package for Commandable.
4
+
5
+ It owns the reusable database, integration, auth, config, and MCP runtime logic used by:
6
+
7
+ - `@commandable/mcp`
8
+ - `@commandable/mcp-connect`
@@ -0,0 +1,16 @@
1
+ import type { DbClient } from '../db/client.js';
2
+ import type { SqlCredentialStore } from '../db/credentialStore.js';
3
+ import type { CommandableConfig } from './configSchema.js';
4
+ export type ApplyConfigResult = {
5
+ spaceId: string;
6
+ integrationsUpserted: number;
7
+ credentialsWritten: number;
8
+ credentialsUnchanged: number;
9
+ };
10
+ export declare function applyConfig(params: {
11
+ config: CommandableConfig;
12
+ db: DbClient;
13
+ credentialStore: SqlCredentialStore;
14
+ defaultSpaceId?: string;
15
+ }): Promise<ApplyConfigResult>;
16
+ //# sourceMappingURL=configApply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configApply.d.ts","sourceRoot":"","sources":["../../src/config/configApply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAqB,MAAM,mBAAmB,CAAA;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,oBAAoB,EAAE,MAAM,CAAA;IAC5B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,oBAAoB,EAAE,MAAM,CAAA;CAC7B,CAAA;AAiDD,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,iBAAiB,CAAA;IACzB,EAAE,EAAE,QAAQ,CAAA;IACZ,eAAe,EAAE,kBAAkB,CAAA;IACnC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuC7B"}
@@ -0,0 +1,77 @@
1
+ import { upsertIntegration } from '../db/integrationStore.js';
2
+ function stableSort(value) {
3
+ if (Array.isArray(value))
4
+ return value.map(stableSort);
5
+ if (value && typeof value === 'object') {
6
+ const out = {};
7
+ for (const k of Object.keys(value).sort())
8
+ out[k] = stableSort(value[k]);
9
+ return out;
10
+ }
11
+ return value;
12
+ }
13
+ function stableJson(value) {
14
+ return JSON.stringify(stableSort(value));
15
+ }
16
+ function makeIntegrationId(it) {
17
+ if (it.id && it.id.trim().length)
18
+ return it.id.trim();
19
+ const ref = (it.referenceId && it.referenceId.trim().length) ? it.referenceId.trim() : it.type;
20
+ if (ref !== it.type)
21
+ return `${it.type}:${ref}`;
22
+ return it.type;
23
+ }
24
+ function toIntegrationData(spaceId, it) {
25
+ const referenceId = (it.referenceId && it.referenceId.trim().length) ? it.referenceId.trim() : it.type;
26
+ const label = (it.label && it.label.trim().length) ? it.label.trim() : referenceId;
27
+ const credentialId = (it.credentialId && it.credentialId.trim().length) ? it.credentialId.trim() : `${referenceId}-creds`;
28
+ return {
29
+ spaceId: (it.spaceId && it.spaceId.trim().length) ? it.spaceId.trim() : spaceId,
30
+ id: makeIntegrationId(it),
31
+ type: it.type,
32
+ referenceId,
33
+ label,
34
+ enabled: it.enabled ?? true,
35
+ enabledToolsets: it.toolsets ?? undefined,
36
+ maxScope: it.maxScope ?? undefined,
37
+ disabledTools: it.disabledTools?.length ? it.disabledTools : undefined,
38
+ connectionMethod: it.credentials ? 'credentials' : undefined,
39
+ connectionId: null,
40
+ credentialId: it.credentials ? credentialId : (it.credentialId ?? undefined),
41
+ credentialVariant: (it.credentialVariant && it.credentialVariant.trim().length) ? it.credentialVariant.trim() : undefined,
42
+ };
43
+ }
44
+ export async function applyConfig(params) {
45
+ const spaceId = params.config.spaceId || params.defaultSpaceId || process.env.COMMANDABLE_SPACE_ID || 'local';
46
+ let integrationsUpserted = 0;
47
+ let credentialsWritten = 0;
48
+ let credentialsUnchanged = 0;
49
+ for (const it of params.config.integrations || []) {
50
+ const integration = toIntegrationData(spaceId, it);
51
+ await upsertIntegration(params.db, integration);
52
+ integrationsUpserted++;
53
+ if (!it.credentials || !integration.credentialId)
54
+ continue;
55
+ const desired = it.credentials;
56
+ let existing = null;
57
+ try {
58
+ existing = await params.credentialStore.getCredentials(integration.spaceId || spaceId, integration.credentialId);
59
+ }
60
+ catch {
61
+ existing = null;
62
+ }
63
+ if (existing && stableJson(existing) === stableJson(desired)) {
64
+ credentialsUnchanged++;
65
+ continue;
66
+ }
67
+ await params.credentialStore.saveCredentials(integration.spaceId || spaceId, integration.credentialId, desired);
68
+ credentialsWritten++;
69
+ }
70
+ return {
71
+ spaceId,
72
+ integrationsUpserted,
73
+ credentialsWritten,
74
+ credentialsUnchanged,
75
+ };
76
+ }
77
+ //# sourceMappingURL=configApply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configApply.js","sourceRoot":"","sources":["../../src/config/configApply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type CommandableConfig } from './configSchema.js';
2
+ export declare class ConfigError extends Error {
3
+ name: string;
4
+ }
5
+ export declare function loadConfig(configPath?: string): {
6
+ path: string;
7
+ config: CommandableConfig;
8
+ };
9
+ //# sourceMappingURL=configLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configLoader.d.ts","sourceRoot":"","sources":["../../src/config/configLoader.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEnF,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAgB;CAC9B;AA2DD,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAkB3F"}
@@ -0,0 +1,75 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { cwd } from 'node:process';
4
+ import YAML from 'js-yaml';
5
+ import { CommandableConfigSchema } from './configSchema.js';
6
+ export class ConfigError extends Error {
7
+ name = 'ConfigError';
8
+ }
9
+ function parseConfigFile(raw, filePath) {
10
+ if (filePath.endsWith('.json')) {
11
+ try {
12
+ return JSON.parse(raw);
13
+ }
14
+ catch (err) {
15
+ throw new ConfigError(`Invalid JSON in config file: ${filePath}${err?.message ? ` (${err.message})` : ''}`);
16
+ }
17
+ }
18
+ try {
19
+ return YAML.load(raw);
20
+ }
21
+ catch (err) {
22
+ throw new ConfigError(`Invalid YAML in config file: ${filePath}${err?.message ? ` (${err.message})` : ''}`);
23
+ }
24
+ }
25
+ function resolveEnvRefs(value, filePath) {
26
+ if (typeof value === 'string') {
27
+ return value.replace(/\$\{([A-Z0-9_]+)\}/g, (_m, name) => {
28
+ const v = process.env[name];
29
+ if (v == null || v === '')
30
+ throw new ConfigError(`Missing environment variable ${name} referenced in ${filePath}`);
31
+ return v;
32
+ });
33
+ }
34
+ if (Array.isArray(value))
35
+ return value.map(v => resolveEnvRefs(v, filePath));
36
+ if (value && typeof value === 'object') {
37
+ const out = {};
38
+ for (const [k, v] of Object.entries(value))
39
+ out[k] = resolveEnvRefs(v, filePath);
40
+ return out;
41
+ }
42
+ return value;
43
+ }
44
+ function findConfigPath() {
45
+ const explicit = process.env.COMMANDABLE_CONFIG_FILE;
46
+ if (explicit && explicit.trim().length)
47
+ return resolve(explicit.trim());
48
+ const base = resolve(cwd());
49
+ const candidates = [
50
+ 'commandable.config.yaml',
51
+ 'commandable.config.yml',
52
+ 'commandable.config.json',
53
+ ].map(f => resolve(base, f));
54
+ for (const p of candidates) {
55
+ if (existsSync(p))
56
+ return p;
57
+ }
58
+ return null;
59
+ }
60
+ export function loadConfig(configPath) {
61
+ const path = configPath?.trim().length ? resolve(configPath) : findConfigPath();
62
+ if (!path)
63
+ throw new ConfigError('No config file found. Provide --config <path> or set COMMANDABLE_CONFIG_FILE.');
64
+ if (!existsSync(path))
65
+ throw new ConfigError(`Config file not found: ${path}`);
66
+ const raw = readFileSync(path, 'utf8');
67
+ const parsed = parseConfigFile(raw, path);
68
+ const resolved = resolveEnvRefs(parsed, path);
69
+ const result = CommandableConfigSchema.safeParse(resolved);
70
+ if (!result.success) {
71
+ throw new ConfigError(`Invalid config file: ${path}\n${result.error.toString()}`);
72
+ }
73
+ return { path, config: result.data };
74
+ }
75
+ //# sourceMappingURL=configLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configLoader.js","sourceRoot":"","sources":["../../src/config/configLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod';
2
+ export declare const IntegrationConfigSchema: z.ZodObject<{
3
+ id: z.ZodOptional<z.ZodString>;
4
+ type: z.ZodString;
5
+ label: z.ZodOptional<z.ZodString>;
6
+ referenceId: z.ZodOptional<z.ZodString>;
7
+ spaceId: z.ZodOptional<z.ZodString>;
8
+ enabled: z.ZodOptional<z.ZodBoolean>;
9
+ credentialId: z.ZodOptional<z.ZodString>;
10
+ credentialVariant: z.ZodOptional<z.ZodString>;
11
+ toolsets: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
+ maxScope: z.ZodOptional<z.ZodEnum<{
13
+ read: "read";
14
+ write: "write";
15
+ }>>;
16
+ disabledTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
17
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
18
+ }, z.core.$strip>;
19
+ export declare const CommandableConfigSchema: z.ZodObject<{
20
+ spaceId: z.ZodOptional<z.ZodString>;
21
+ mode: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
22
+ static: "static";
23
+ create: "create";
24
+ }>>>;
25
+ integrations: z.ZodDefault<z.ZodArray<z.ZodObject<{
26
+ id: z.ZodOptional<z.ZodString>;
27
+ type: z.ZodString;
28
+ label: z.ZodOptional<z.ZodString>;
29
+ referenceId: z.ZodOptional<z.ZodString>;
30
+ spaceId: z.ZodOptional<z.ZodString>;
31
+ enabled: z.ZodOptional<z.ZodBoolean>;
32
+ credentialId: z.ZodOptional<z.ZodString>;
33
+ credentialVariant: z.ZodOptional<z.ZodString>;
34
+ toolsets: z.ZodOptional<z.ZodArray<z.ZodString>>;
35
+ maxScope: z.ZodOptional<z.ZodEnum<{
36
+ read: "read";
37
+ write: "write";
38
+ }>>;
39
+ disabledTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
40
+ credentials: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
41
+ }, z.core.$strip>>>;
42
+ }, z.core.$strip>;
43
+ export type CommandableConfig = z.infer<typeof CommandableConfigSchema>;
44
+ export type IntegrationConfig = z.infer<typeof IntegrationConfigSchema>;
45
+ //# sourceMappingURL=configSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configSchema.d.ts","sourceRoot":"","sources":["../../src/config/configSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;iBAelC,CAAA;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;iBAIlC,CAAA;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AACvE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ export const IntegrationConfigSchema = z.object({
3
+ id: z.string().min(1).optional(),
4
+ type: z.string().min(1),
5
+ label: z.string().min(1).optional(),
6
+ referenceId: z.string().min(1).optional(),
7
+ spaceId: z.string().min(1).optional(),
8
+ enabled: z.boolean().optional(),
9
+ credentialId: z.string().min(1).optional(),
10
+ credentialVariant: z.string().min(1).optional(),
11
+ toolsets: z.array(z.string()).optional(),
12
+ /** Cap the maximum scope tier. 'read' means only read tools; 'write' means read+write. */
13
+ maxScope: z.enum(['read', 'write']).optional(),
14
+ /** Individual tool names to block regardless of toolset or scope. */
15
+ disabledTools: z.array(z.string()).optional(),
16
+ credentials: z.record(z.string(), z.string()).optional(),
17
+ });
18
+ export const CommandableConfigSchema = z.object({
19
+ spaceId: z.string().min(1).optional(),
20
+ mode: z.enum(['static', 'create']).optional().default('static'),
21
+ integrations: z.array(IntegrationConfigSchema).default([]),
22
+ });
23
+ //# sourceMappingURL=configSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configSchema.js","sourceRoot":"","sources":["../../src/config/configSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1C,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC/C,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxC,0FAA0F;IAC1F,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC9C,qEAAqE;IACrE,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC7C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC/D,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3D,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export declare function encrypt(text: string, secret: string): string;
2
+ export declare function decrypt(encryptedText: string, secret: string): string;
3
+ //# sourceMappingURL=encryption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/crypto/encryption.ts"],"names":[],"mappings":"AAQA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ5D;AAED,wBAAgB,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAcrE"}
@@ -0,0 +1,29 @@
1
+ import crypto from 'node:crypto';
2
+ const algorithm = 'aes-256-cbc';
3
+ function getKey(secret) {
4
+ return crypto.createHash('sha256').update(secret).digest();
5
+ }
6
+ export function encrypt(text, secret) {
7
+ const key = getKey(secret);
8
+ const iv = crypto.randomBytes(16);
9
+ const cipher = crypto.createCipheriv(algorithm, key, iv);
10
+ let encrypted = cipher.update(text, 'utf8', 'hex');
11
+ encrypted += cipher.final('hex');
12
+ return `${iv.toString('hex')}:${encrypted}`;
13
+ }
14
+ export function decrypt(encryptedText, secret) {
15
+ const key = getKey(secret);
16
+ const parts = encryptedText.split(':');
17
+ if (parts.length !== 2)
18
+ throw new Error('Invalid encrypted text format');
19
+ const ivHex = parts[0];
20
+ const encrypted = parts[1];
21
+ if (!ivHex || !encrypted)
22
+ throw new Error('Invalid encrypted text format');
23
+ const iv = Buffer.from(ivHex, 'hex');
24
+ const decipher = crypto.createDecipheriv(algorithm, key, iv);
25
+ let decrypted = decipher.update(encrypted, 'hex', 'utf8');
26
+ decrypted += decipher.final('utf8');
27
+ return decrypted;
28
+ }
29
+ //# sourceMappingURL=encryption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/crypto/encryption.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,MAAM,SAAS,GAAG,aAAa,CAAA;AAE/B,SAAS,MAAM,CAAC,MAAc;IAC5B,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,MAAc;IAClD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;IAExD,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IAClD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAChC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,aAAqB,EAAE,MAAc;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAClD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IACtB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1B,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS;QACtB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAClD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;IAC5D,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IACzD,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACnC,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import Database from 'better-sqlite3';
2
+ import { drizzle as drizzleSqlite } from 'drizzle-orm/better-sqlite3';
3
+ import { drizzle as drizzlePg } from 'drizzle-orm/node-postgres';
4
+ import { Pool } from 'pg';
5
+ export type DbDialect = 'sqlite' | 'postgres';
6
+ export type AnyDrizzle = ReturnType<typeof drizzleSqlite> | ReturnType<typeof drizzlePg>;
7
+ export type DbClient = {
8
+ dialect: 'sqlite';
9
+ db: ReturnType<typeof drizzleSqlite>;
10
+ raw: InstanceType<typeof Database>;
11
+ close: () => void;
12
+ } | {
13
+ dialect: 'postgres';
14
+ db: ReturnType<typeof drizzlePg>;
15
+ raw: Pool;
16
+ close: () => Promise<void>;
17
+ };
18
+ export interface CreateDbOptions {
19
+ sqlitePath?: string;
20
+ databaseUrl?: string;
21
+ }
22
+ export declare function createDbFromEnv(): DbClient;
23
+ export declare function createDb(opts?: CreateDbOptions): DbClient;
24
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAEzB,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAA;AAE7C,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAA;AAExF,MAAM,MAAM,QAAQ,GAChB;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IAAC,GAAG,EAAE,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,GAClH;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;IAAC,GAAG,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAA;AAEpG,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,eAAe,IAAI,QAAQ,CAS1C;AAED,wBAAgB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,QAAQ,CAkC7D"}
@@ -0,0 +1,50 @@
1
+ import { dirname, resolve } from 'node:path';
2
+ import { mkdirSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import Database from 'better-sqlite3';
5
+ import { drizzle as drizzleSqlite } from 'drizzle-orm/better-sqlite3';
6
+ import { drizzle as drizzlePg } from 'drizzle-orm/node-postgres';
7
+ import { Pool } from 'pg';
8
+ export function createDbFromEnv() {
9
+ const dataDir = process.env.COMMANDABLE_DATA_DIR;
10
+ const sqliteFromDataDir = dataDir && dataDir.trim().length
11
+ ? resolve(dataDir, 'credentials.sqlite')
12
+ : undefined;
13
+ return createDb({
14
+ databaseUrl: process.env.DATABASE_URL,
15
+ sqlitePath: process.env.COMMANDABLE_MCP_SQLITE_PATH || sqliteFromDataDir,
16
+ });
17
+ }
18
+ export function createDb(opts = {}) {
19
+ const databaseUrl = opts.databaseUrl || process.env.DATABASE_URL;
20
+ if (databaseUrl) {
21
+ const pool = new Pool({ connectionString: databaseUrl });
22
+ const db = drizzlePg(pool);
23
+ return {
24
+ dialect: 'postgres',
25
+ db,
26
+ raw: pool,
27
+ close: async () => {
28
+ await pool.end();
29
+ },
30
+ };
31
+ }
32
+ const sqlitePath = opts.sqlitePath
33
+ ? resolve(opts.sqlitePath)
34
+ : resolve(homedir(), '.commandable', 'credentials.sqlite');
35
+ // Ensure parent directory exists so SQLite can create the file.
36
+ // (better-sqlite3 does not create directories automatically)
37
+ try {
38
+ mkdirSync(dirname(sqlitePath), { recursive: true, mode: 0o700 });
39
+ }
40
+ catch { }
41
+ const sqlite = new Database(sqlitePath);
42
+ const db = drizzleSqlite(sqlite);
43
+ return {
44
+ dialect: 'sqlite',
45
+ db,
46
+ raw: sqlite,
47
+ close: () => sqlite.close(),
48
+ };
49
+ }
50
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAezB,MAAM,UAAU,eAAe;IAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAA;IAChD,MAAM,iBAAiB,GAAG,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM;QACxD,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,CAAC;QACxC,CAAC,CAAC,SAAS,CAAA;IACb,OAAO,QAAQ,CAAC;QACd,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,iBAAiB;KACzE,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAwB,EAAE;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAA;IAChE,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAAA;QACxD,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAO;YACL,OAAO,EAAE,UAAU;YACnB,EAAE;YACF,GAAG,EAAE,IAAI;YACT,KAAK,EAAE,KAAK,IAAI,EAAE;gBAChB,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;YAClB,CAAC;SACF,CAAA;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;QAChC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,oBAAoB,CAAC,CAAA;IAE5D,gEAAgE;IAChE,6DAA6D;IAC7D,IAAI,CAAC;QACH,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,MAAM,CAAC,CAAA,CAAC;IAER,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAA;IACvC,MAAM,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO;QACL,OAAO,EAAE,QAAQ;QACjB,EAAE;QACF,GAAG,EAAE,MAAM;QACX,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE;KAC5B,CAAA;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { CredentialStore } from '../integrations/proxy.js';
2
+ import type { DbClient } from './client.js';
3
+ export declare class SqlCredentialStore implements CredentialStore {
4
+ private readonly client;
5
+ private readonly encryptionSecret;
6
+ constructor(client: DbClient, encryptionSecret: string);
7
+ hasCredentials(spaceId: string, credentialId: string): Promise<boolean>;
8
+ saveCredentials(spaceId: string, credentialId: string, credentials: Record<string, string>): Promise<void>;
9
+ getCredentials(spaceId: string, credentialId: string): Promise<Record<string, string> | null>;
10
+ deleteCredentials(spaceId: string, credentialId: string): Promise<void>;
11
+ private _table;
12
+ private _db;
13
+ private _getRow;
14
+ }
15
+ //# sourceMappingURL=credentialStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentialStore.d.ts","sourceRoot":"","sources":["../../src/db/credentialStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C,qBAAa,kBAAmB,YAAW,eAAe;IAEtD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,MAAM,EAAE,QAAQ,EAChB,gBAAgB,EAAE,MAAM;IAGrC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1G,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAS7F,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7E,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,GAAG;YAIG,OAAO;CAStB"}
@@ -0,0 +1,56 @@
1
+ import { and, eq } from 'drizzle-orm';
2
+ import { decrypt, encrypt } from '../crypto/encryption.js';
3
+ import { pgCredentials, sqliteCredentials } from './schema.js';
4
+ export class SqlCredentialStore {
5
+ client;
6
+ encryptionSecret;
7
+ constructor(client, encryptionSecret) {
8
+ this.client = client;
9
+ this.encryptionSecret = encryptionSecret;
10
+ }
11
+ async hasCredentials(spaceId, credentialId) {
12
+ return !!(await this._getRow(spaceId, credentialId));
13
+ }
14
+ async saveCredentials(spaceId, credentialId, credentials) {
15
+ const ciphertext = encrypt(JSON.stringify(credentials ?? {}), this.encryptionSecret);
16
+ const now = new Date();
17
+ const table = this._table();
18
+ await this._db()
19
+ .insert(table)
20
+ .values({ spaceId, id: credentialId, ciphertext, createdAt: now, updatedAt: now })
21
+ .onConflictDoUpdate({
22
+ target: [table.spaceId, table.id],
23
+ set: { ciphertext, updatedAt: now },
24
+ });
25
+ }
26
+ async getCredentials(spaceId, credentialId) {
27
+ const row = await this._getRow(spaceId, credentialId);
28
+ if (!row?.ciphertext)
29
+ return null;
30
+ const plaintext = decrypt(row.ciphertext, this.encryptionSecret);
31
+ const parsed = JSON.parse(plaintext);
32
+ return (parsed && typeof parsed === 'object') ? parsed : null;
33
+ }
34
+ async deleteCredentials(spaceId, credentialId) {
35
+ const table = this._table();
36
+ await this._db()
37
+ .delete(table)
38
+ .where(and(eq(table.spaceId, spaceId), eq(table.id, credentialId)));
39
+ }
40
+ _table() {
41
+ return this.client.dialect === 'sqlite' ? sqliteCredentials : pgCredentials;
42
+ }
43
+ _db() {
44
+ return this.client.db;
45
+ }
46
+ async _getRow(spaceId, credentialId) {
47
+ const table = this._table();
48
+ const rows = await this._db()
49
+ .select()
50
+ .from(table)
51
+ .where(and(eq(table.spaceId, spaceId), eq(table.id, credentialId)))
52
+ .limit(1);
53
+ return rows[0] ?? null;
54
+ }
55
+ }
56
+ //# sourceMappingURL=credentialStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentialStore.js","sourceRoot":"","sources":["../../src/db/credentialStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { IntegrationData } from '../types.js';
2
+ import type { DbClient } from './client.js';
3
+ export declare function listIntegrations(client: DbClient, spaceId?: string): Promise<IntegrationData[]>;
4
+ export declare function getIntegrationById(client: DbClient, id: string): Promise<IntegrationData | null>;
5
+ export declare function upsertIntegration(client: DbClient, integration: IntegrationData): Promise<void>;
6
+ export declare function deleteIntegrationById(client: DbClient, id: string): Promise<number>;
7
+ /** Update only credential linkage fields — does not clobber toolsets/permissions. */
8
+ export declare function updateIntegrationCredentials(client: DbClient, integrationId: string, fields: {
9
+ connectionMethod: 'credentials' | null;
10
+ credentialId: string | null;
11
+ credentialVariant: string | null;
12
+ }): Promise<void>;
13
+ export declare function updateIntegrationHealth(client: DbClient, integrationId: string, healthStatus: 'disconnected' | 'connected' | 'invalid_credentials', checkedAt?: Date): Promise<void>;
14
+ //# sourceMappingURL=integrationStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrationStore.d.ts","sourceRoot":"","sources":["../../src/db/integrationStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AA6C3C,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAQrG;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,QAAQ,EAChB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQjC;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCrG;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF;AAED,qFAAqF;AACrF,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,QAAQ,EAChB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE;IACN,gBAAgB,EAAE,aAAa,GAAG,IAAI,CAAA;IACtC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC,GACA,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,QAAQ,EAChB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,cAAc,GAAG,WAAW,GAAG,qBAAqB,EAClE,SAAS,CAAC,EAAE,IAAI,GACf,OAAO,CAAC,IAAI,CAAC,CAMf"}