@optimizely/ocp-local-env 1.0.0-beta.10

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 (244) hide show
  1. package/README.md +51 -0
  2. package/dist/package.json +112 -0
  3. package/dist/public/bundle.82dc5d29fffb9f205051.js +3 -0
  4. package/dist/public/bundle.82dc5d29fffb9f205051.js.LICENSE.txt +92 -0
  5. package/dist/public/bundle.82dc5d29fffb9f205051.js.map +1 -0
  6. package/dist/public/index.html +1 -0
  7. package/dist/src/cli.d.ts +2 -0
  8. package/dist/src/cli.js +115 -0
  9. package/dist/src/cli.js.map +1 -0
  10. package/dist/src/executor/DestinationExecutor.d.ts +19 -0
  11. package/dist/src/executor/DestinationExecutor.js +72 -0
  12. package/dist/src/executor/DestinationExecutor.js.map +1 -0
  13. package/dist/src/executor/FunctionExecutor.d.ts +67 -0
  14. package/dist/src/executor/FunctionExecutor.js +189 -0
  15. package/dist/src/executor/FunctionExecutor.js.map +1 -0
  16. package/dist/src/executor/JobExecutor.d.ts +79 -0
  17. package/dist/src/executor/JobExecutor.js +215 -0
  18. package/dist/src/executor/JobExecutor.js.map +1 -0
  19. package/dist/src/executor/LifecycleExecutor.d.ts +64 -0
  20. package/dist/src/executor/LifecycleExecutor.js +167 -0
  21. package/dist/src/executor/LifecycleExecutor.js.map +1 -0
  22. package/dist/src/executor/SourceExecutor.d.ts +32 -0
  23. package/dist/src/executor/SourceExecutor.js +163 -0
  24. package/dist/src/executor/SourceExecutor.js.map +1 -0
  25. package/dist/src/executor/watcher.d.ts +62 -0
  26. package/dist/src/executor/watcher.js +213 -0
  27. package/dist/src/executor/watcher.js.map +1 -0
  28. package/dist/src/functions/hello.d.ts +4 -0
  29. package/dist/src/functions/hello.js +8 -0
  30. package/dist/src/functions/hello.js.map +1 -0
  31. package/dist/src/index.d.ts +1 -0
  32. package/dist/src/index.js +9 -0
  33. package/dist/src/index.js.map +1 -0
  34. package/dist/src/jobs/dailyJob.d.ts +4 -0
  35. package/dist/src/jobs/dailyJob.js +8 -0
  36. package/dist/src/jobs/dailyJob.js.map +1 -0
  37. package/dist/src/local_engine/LocalFunctionApi.d.ts +17 -0
  38. package/dist/src/local_engine/LocalFunctionApi.js +54 -0
  39. package/dist/src/local_engine/LocalFunctionApi.js.map +1 -0
  40. package/dist/src/local_engine/LocalJobApi.d.ts +67 -0
  41. package/dist/src/local_engine/LocalJobApi.js +205 -0
  42. package/dist/src/local_engine/LocalJobApi.js.map +1 -0
  43. package/dist/src/local_engine/LocalNotifier.d.ts +9 -0
  44. package/dist/src/local_engine/LocalNotifier.js +26 -0
  45. package/dist/src/local_engine/LocalNotifier.js.map +1 -0
  46. package/dist/src/local_engine/local-engine-child-base.d.ts +110 -0
  47. package/dist/src/local_engine/local-engine-child-base.js +607 -0
  48. package/dist/src/local_engine/local-engine-child-base.js.map +1 -0
  49. package/dist/src/local_engine/local-engine-client.d.ts +161 -0
  50. package/dist/src/local_engine/local-engine-client.js +888 -0
  51. package/dist/src/local_engine/local-engine-client.js.map +1 -0
  52. package/dist/src/local_engine/local-engine-types.d.ts +245 -0
  53. package/dist/src/local_engine/local-engine-types.js +6 -0
  54. package/dist/src/local_engine/local-engine-types.js.map +1 -0
  55. package/dist/src/local_engine/local-engine-unified.d.ts +71 -0
  56. package/dist/src/local_engine/local-engine-unified.js +723 -0
  57. package/dist/src/local_engine/local-engine-unified.js.map +1 -0
  58. package/dist/src/local_engine/local-engine-utils.d.ts +68 -0
  59. package/dist/src/local_engine/local-engine-utils.js +219 -0
  60. package/dist/src/local_engine/local-engine-utils.js.map +1 -0
  61. package/dist/src/local_engine/localSDKConfig.d.ts +40 -0
  62. package/dist/src/local_engine/localSDKConfig.js +247 -0
  63. package/dist/src/local_engine/localSDKConfig.js.map +1 -0
  64. package/dist/src/local_engine/storage/BaseKVStoreWrapper.d.ts +37 -0
  65. package/dist/src/local_engine/storage/BaseKVStoreWrapper.js +110 -0
  66. package/dist/src/local_engine/storage/BaseKVStoreWrapper.js.map +1 -0
  67. package/dist/src/local_engine/storage/LocalConfigStore.d.ts +74 -0
  68. package/dist/src/local_engine/storage/LocalConfigStore.js +178 -0
  69. package/dist/src/local_engine/storage/LocalConfigStore.js.map +1 -0
  70. package/dist/src/local_engine/storage/LocalJobStore.d.ts +111 -0
  71. package/dist/src/local_engine/storage/LocalJobStore.js +249 -0
  72. package/dist/src/local_engine/storage/LocalJobStore.js.map +1 -0
  73. package/dist/src/local_engine/storage/LocalKVStore.d.ts +106 -0
  74. package/dist/src/local_engine/storage/LocalKVStore.js +1061 -0
  75. package/dist/src/local_engine/storage/LocalKVStore.js.map +1 -0
  76. package/dist/src/local_engine/storage/LocalNotificationStore.d.ts +28 -0
  77. package/dist/src/local_engine/storage/LocalNotificationStore.js +149 -0
  78. package/dist/src/local_engine/storage/LocalNotificationStore.js.map +1 -0
  79. package/dist/src/local_engine/storage/LocalSecretsStore.d.ts +115 -0
  80. package/dist/src/local_engine/storage/LocalSecretsStore.js +350 -0
  81. package/dist/src/local_engine/storage/LocalSecretsStore.js.map +1 -0
  82. package/dist/src/local_engine/storage/LocalSecretsStoreWrapper.d.ts +19 -0
  83. package/dist/src/local_engine/storage/LocalSecretsStoreWrapper.js +52 -0
  84. package/dist/src/local_engine/storage/LocalSecretsStoreWrapper.js.map +1 -0
  85. package/dist/src/local_engine/storage/LocalSettingsStore.d.ts +168 -0
  86. package/dist/src/local_engine/storage/LocalSettingsStore.js +509 -0
  87. package/dist/src/local_engine/storage/LocalSettingsStore.js.map +1 -0
  88. package/dist/src/local_engine/storage/LocalSettingsStoreWrapper.d.ts +15 -0
  89. package/dist/src/local_engine/storage/LocalSettingsStoreWrapper.js +28 -0
  90. package/dist/src/local_engine/storage/LocalSettingsStoreWrapper.js.map +1 -0
  91. package/dist/src/local_engine/storage/NumberSet.d.ts +21 -0
  92. package/dist/src/local_engine/storage/NumberSet.js +32 -0
  93. package/dist/src/local_engine/storage/NumberSet.js.map +1 -0
  94. package/dist/src/local_engine/storage/SourceDataStore.d.ts +23 -0
  95. package/dist/src/local_engine/storage/SourceDataStore.js +83 -0
  96. package/dist/src/local_engine/storage/SourceDataStore.js.map +1 -0
  97. package/dist/src/local_engine/storage/SourceJobExecutionStore.d.ts +25 -0
  98. package/dist/src/local_engine/storage/SourceJobExecutionStore.js +61 -0
  99. package/dist/src/local_engine/storage/SourceJobExecutionStore.js.map +1 -0
  100. package/dist/src/local_engine/storage/StringSet.d.ts +21 -0
  101. package/dist/src/local_engine/storage/StringSet.js +32 -0
  102. package/dist/src/local_engine/storage/StringSet.js.map +1 -0
  103. package/dist/src/local_engine/types.d.ts +53 -0
  104. package/dist/src/local_engine/types.js +6 -0
  105. package/dist/src/local_engine/types.js.map +1 -0
  106. package/dist/src/local_engine/utils.d.ts +33 -0
  107. package/dist/src/local_engine/utils.js +143 -0
  108. package/dist/src/local_engine/utils.js.map +1 -0
  109. package/dist/src/logging/LogManager.d.ts +246 -0
  110. package/dist/src/logging/LogManager.js +343 -0
  111. package/dist/src/logging/LogManager.js.map +1 -0
  112. package/dist/src/server/api/destinations.d.ts +7 -0
  113. package/dist/src/server/api/destinations.js +170 -0
  114. package/dist/src/server/api/destinations.js.map +1 -0
  115. package/dist/src/server/api/functions.d.ts +7 -0
  116. package/dist/src/server/api/functions.js +80 -0
  117. package/dist/src/server/api/functions.js.map +1 -0
  118. package/dist/src/server/api/jobs.d.ts +10 -0
  119. package/dist/src/server/api/jobs.js +244 -0
  120. package/dist/src/server/api/jobs.js.map +1 -0
  121. package/dist/src/server/api/settings.d.ts +6 -0
  122. package/dist/src/server/api/settings.js +116 -0
  123. package/dist/src/server/api/settings.js.map +1 -0
  124. package/dist/src/server/api/sources.d.ts +7 -0
  125. package/dist/src/server/api/sources.js +382 -0
  126. package/dist/src/server/api/sources.js.map +1 -0
  127. package/dist/src/server/api/stores.d.ts +2 -0
  128. package/dist/src/server/api/stores.js +341 -0
  129. package/dist/src/server/api/stores.js.map +1 -0
  130. package/dist/src/server/api/v1.d.ts +10 -0
  131. package/dist/src/server/api/v1.js +718 -0
  132. package/dist/src/server/api/v1.js.map +1 -0
  133. package/dist/src/server/api.d.ts +8 -0
  134. package/dist/src/server/api.js +217 -0
  135. package/dist/src/server/api.js.map +1 -0
  136. package/dist/src/server/app-discovery.d.ts +5 -0
  137. package/dist/src/server/app-discovery.js +113 -0
  138. package/dist/src/server/app-discovery.js.map +1 -0
  139. package/dist/src/server/config.d.ts +26 -0
  140. package/dist/src/server/config.js +112 -0
  141. package/dist/src/server/config.js.map +1 -0
  142. package/dist/src/server/mockDataGenerator.d.ts +1 -0
  143. package/dist/src/server/mockDataGenerator.js +154 -0
  144. package/dist/src/server/mockDataGenerator.js.map +1 -0
  145. package/dist/src/server/websocket.d.ts +0 -0
  146. package/dist/src/server/websocket.js +2 -0
  147. package/dist/src/server/websocket.js.map +1 -0
  148. package/dist/src/server.d.ts +2 -0
  149. package/dist/src/server.js +735 -0
  150. package/dist/src/server.js.map +1 -0
  151. package/dist/src/types/app.d.ts +154 -0
  152. package/dist/src/types/app.js +24 -0
  153. package/dist/src/types/app.js.map +1 -0
  154. package/dist/src/types/kvstore.d.ts +320 -0
  155. package/dist/src/types/kvstore.js +5 -0
  156. package/dist/src/types/kvstore.js.map +1 -0
  157. package/dist/src/ui/components/App.d.ts +6 -0
  158. package/dist/src/ui/components/App.js +432 -0
  159. package/dist/src/ui/components/App.js.map +1 -0
  160. package/dist/src/ui/components/DestinationBatchEditor.d.ts +7 -0
  161. package/dist/src/ui/components/DestinationBatchEditor.js +160 -0
  162. package/dist/src/ui/components/DestinationBatchEditor.js.map +1 -0
  163. package/dist/src/ui/components/DestinationSchemaViewer.d.ts +7 -0
  164. package/dist/src/ui/components/DestinationSchemaViewer.js +61 -0
  165. package/dist/src/ui/components/DestinationSchemaViewer.js.map +1 -0
  166. package/dist/src/ui/components/DestinationsView.d.ts +14 -0
  167. package/dist/src/ui/components/DestinationsView.js +68 -0
  168. package/dist/src/ui/components/DestinationsView.js.map +1 -0
  169. package/dist/src/ui/components/FunctionsView.d.ts +13 -0
  170. package/dist/src/ui/components/FunctionsView.js +288 -0
  171. package/dist/src/ui/components/FunctionsView.js.map +1 -0
  172. package/dist/src/ui/components/JobsView.d.ts +13 -0
  173. package/dist/src/ui/components/JobsView.js +320 -0
  174. package/dist/src/ui/components/JobsView.js.map +1 -0
  175. package/dist/src/ui/components/KVStoreViewer.d.ts +11 -0
  176. package/dist/src/ui/components/KVStoreViewer.js +168 -0
  177. package/dist/src/ui/components/KVStoreViewer.js.map +1 -0
  178. package/dist/src/ui/components/MetadataModal.d.ts +14 -0
  179. package/dist/src/ui/components/MetadataModal.js +28 -0
  180. package/dist/src/ui/components/MetadataModal.js.map +1 -0
  181. package/dist/src/ui/components/MetadataModal.test.d.ts +1 -0
  182. package/dist/src/ui/components/MetadataModal.test.js +143 -0
  183. package/dist/src/ui/components/MetadataModal.test.js.map +1 -0
  184. package/dist/src/ui/components/NotificationViewer.d.ts +16 -0
  185. package/dist/src/ui/components/NotificationViewer.js +69 -0
  186. package/dist/src/ui/components/NotificationViewer.js.map +1 -0
  187. package/dist/src/ui/components/SecretsStoreViewer.d.ts +11 -0
  188. package/dist/src/ui/components/SecretsStoreViewer.js +179 -0
  189. package/dist/src/ui/components/SecretsStoreViewer.js.map +1 -0
  190. package/dist/src/ui/components/SettingsStoreViewer.d.ts +24 -0
  191. package/dist/src/ui/components/SettingsStoreViewer.js +132 -0
  192. package/dist/src/ui/components/SettingsStoreViewer.js.map +1 -0
  193. package/dist/src/ui/components/SourceDataViewer.d.ts +8 -0
  194. package/dist/src/ui/components/SourceDataViewer.js +84 -0
  195. package/dist/src/ui/components/SourceDataViewer.js.map +1 -0
  196. package/dist/src/ui/components/SourceJobsSection.d.ts +8 -0
  197. package/dist/src/ui/components/SourceJobsSection.js +99 -0
  198. package/dist/src/ui/components/SourceJobsSection.js.map +1 -0
  199. package/dist/src/ui/components/SourceLifecycleSection.d.ts +7 -0
  200. package/dist/src/ui/components/SourceLifecycleSection.js +58 -0
  201. package/dist/src/ui/components/SourceLifecycleSection.js.map +1 -0
  202. package/dist/src/ui/components/SourceSchemaViewer.d.ts +7 -0
  203. package/dist/src/ui/components/SourceSchemaViewer.js +65 -0
  204. package/dist/src/ui/components/SourceSchemaViewer.js.map +1 -0
  205. package/dist/src/ui/components/SourceWebhookEditor.d.ts +8 -0
  206. package/dist/src/ui/components/SourceWebhookEditor.js +181 -0
  207. package/dist/src/ui/components/SourceWebhookEditor.js.map +1 -0
  208. package/dist/src/ui/components/SourcesView.d.ts +14 -0
  209. package/dist/src/ui/components/SourcesView.js +74 -0
  210. package/dist/src/ui/components/SourcesView.js.map +1 -0
  211. package/dist/src/ui/components/StoreViewer.d.ts +16 -0
  212. package/dist/src/ui/components/StoreViewer.js +86 -0
  213. package/dist/src/ui/components/StoreViewer.js.map +1 -0
  214. package/dist/src/ui/components/TabbedConsole.d.ts +17 -0
  215. package/dist/src/ui/components/TabbedConsole.js +163 -0
  216. package/dist/src/ui/components/TabbedConsole.js.map +1 -0
  217. package/dist/src/ui/components/common/DataTree.d.ts +15 -0
  218. package/dist/src/ui/components/common/DataTree.js +95 -0
  219. package/dist/src/ui/components/common/DataTree.js.map +1 -0
  220. package/dist/src/ui/components/common/EyeIcon.d.ts +11 -0
  221. package/dist/src/ui/components/common/EyeIcon.js +11 -0
  222. package/dist/src/ui/components/common/EyeIcon.js.map +1 -0
  223. package/dist/src/ui/hooks/useEntityNavigation.d.ts +72 -0
  224. package/dist/src/ui/hooks/useEntityNavigation.js +150 -0
  225. package/dist/src/ui/hooks/useEntityNavigation.js.map +1 -0
  226. package/dist/src/ui/hooks/useQueryParams.d.ts +6 -0
  227. package/dist/src/ui/hooks/useQueryParams.js +39 -0
  228. package/dist/src/ui/hooks/useQueryParams.js.map +1 -0
  229. package/dist/src/ui/index.d.ts +1 -0
  230. package/dist/src/ui/index.js +23 -0
  231. package/dist/src/ui/index.js.map +1 -0
  232. package/dist/src/ui/store/formStateSlice.d.ts +54 -0
  233. package/dist/src/ui/store/formStateSlice.js +94 -0
  234. package/dist/src/ui/store/formStateSlice.js.map +1 -0
  235. package/dist/src/ui/store/hooks.d.ts +6 -0
  236. package/dist/src/ui/store/hooks.js +8 -0
  237. package/dist/src/ui/store/hooks.js.map +1 -0
  238. package/dist/src/ui/store/index.d.ts +11 -0
  239. package/dist/src/ui/store/index.js +107 -0
  240. package/dist/src/ui/store/index.js.map +1 -0
  241. package/dist/src/utils/functionEndpoints.d.ts +24 -0
  242. package/dist/src/utils/functionEndpoints.js +45 -0
  243. package/dist/src/utils/functionEndpoints.js.map +1 -0
  244. package/package.json +112 -0
@@ -0,0 +1,718 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createV1Routes = createV1Routes;
7
+ const express_1 = __importDefault(require("express"));
8
+ const functionEndpoints_1 = require("../../utils/functionEndpoints");
9
+ const config_1 = require("../config");
10
+ /**
11
+ * Create v1 API routes matching the REST API documentation
12
+ */
13
+ function createV1Routes(app, watcher, configStore, lifecycleExecutor, settingsStore) {
14
+ const router = express_1.default.Router();
15
+ // Import individual v1 route modules
16
+ router.use('/apps', createAppsRoutes(app, watcher, configStore));
17
+ router.use("/accounts", createAccountsRoutes(app, watcher, configStore, lifecycleExecutor, settingsStore));
18
+ router.use('/installs', createInstallsRoutes(app, watcher, configStore, settingsStore, lifecycleExecutor));
19
+ // Data syncs endpoint
20
+ router.get('/data-syncs', (req, res) => {
21
+ // Accept query parameters but don't use them for now
22
+ const { tracker_id, sort_field, sort_direction, offset, limit } = req.query;
23
+ // Return empty array as requested
24
+ res.json({
25
+ dataSyncItems: []
26
+ });
27
+ });
28
+ return router;
29
+ }
30
+ /**
31
+ * Create apps-specific routes for /v1/apps
32
+ */
33
+ function createAppsRoutes(app, watcher, configStore) {
34
+ const router = express_1.default.Router();
35
+ /**
36
+ * GET /v1/apps
37
+ * Lists running app versions
38
+ */
39
+ router.get('/', (req, res) => {
40
+ const { tracker_id, include_manifest_json, categories, installed } = req.query;
41
+ // Get server URL from request
42
+ const protocol = req.secure ? 'https' : 'http';
43
+ const host = req.get('host') || `${config_1.config.server.host}:${config_1.config.server.port}`;
44
+ const serverUrl = `${protocol}://${host}`;
45
+ // Build app metadata
46
+ const metadata = {
47
+ categories: app.manifest.meta.categories || [],
48
+ display_name: app.manifest.meta.display_name,
49
+ summary: app.manifest.meta.summary || '',
50
+ overview_url: `${serverUrl}/assets/overview.md`,
51
+ support_url: app.manifest.meta.support_url || '',
52
+ logo_url: `${serverUrl}/assets/logo.svg`,
53
+ icon_url: `${serverUrl}/assets/icon.svg`,
54
+ vendor: app.manifest.meta.vendor || '',
55
+ contact_email: app.manifest.meta.contact_email || '',
56
+ settings_url: `${serverUrl}/assets/settings.yml`,
57
+ content_settings_url: '', // Not available in local app manifest
58
+ content_template_url: '' // Not available in local app manifest
59
+ };
60
+ const now = new Date().toISOString();
61
+ // Check installation status from config store
62
+ const isInstalled = configStore.isInstalled();
63
+ // Build the app result
64
+ const appResult = {
65
+ id: {
66
+ app_id: app.manifest.meta.app_id,
67
+ version: app.manifest.meta.version
68
+ },
69
+ metadata: metadata,
70
+ installed: isInstalled,
71
+ installed_at: isInstalled ? now : undefined,
72
+ created_at: now,
73
+ updated_at: now,
74
+ installed_version: isInstalled ? app.manifest.meta.version : undefined,
75
+ manifest_json: include_manifest_json === 'true' ? JSON.stringify(app.manifest) : '',
76
+ install_id: isInstalled ? 1 : undefined // Static install ID for local development
77
+ };
78
+ // Apply filters if provided
79
+ let results = [appResult];
80
+ // Filter by categories if specified
81
+ if (categories) {
82
+ const categoryFilters = Array.isArray(categories) ? categories : [categories];
83
+ const appCategories = app.manifest.meta.categories || [];
84
+ const hasMatchingCategory = categoryFilters.some(cat => appCategories.includes(cat));
85
+ if (!hasMatchingCategory) {
86
+ results = [];
87
+ }
88
+ }
89
+ // Filter by installed status if specified
90
+ if (installed !== undefined) {
91
+ const isInstalledFilter = installed === 'true';
92
+ if (isInstalledFilter !== isInstalled) {
93
+ results = [];
94
+ }
95
+ }
96
+ // Return the results
97
+ res.json({
98
+ results: results
99
+ });
100
+ });
101
+ /**
102
+ * GET /v1/apps/{app_id}
103
+ * Fetches details of a specific app
104
+ */
105
+ router.get('/:app_id', (req, res) => {
106
+ const { app_id } = req.params;
107
+ const { tracker_id } = req.query;
108
+ // Get server URL from request
109
+ const protocol = req.secure ? 'https' : 'http';
110
+ const host = req.get('host') || `${config_1.config.server.host}:${config_1.config.server.port}`;
111
+ const serverUrl = `${protocol}://${host}`;
112
+ // Check if the requested app_id matches our local app
113
+ if (app_id !== app.manifest.meta.app_id) {
114
+ return res.status(404).json({
115
+ error: {
116
+ message: `App with id '${app_id}' not found`,
117
+ code: 'APP_NOT_FOUND'
118
+ }
119
+ });
120
+ }
121
+ // Build app version metadata from manifest
122
+ const metadata = {
123
+ categories: app.manifest.meta.categories || [],
124
+ display_name: app.manifest.meta.display_name,
125
+ summary: app.manifest.meta.summary || '',
126
+ overview_url: `${serverUrl}/assets/overview.md`,
127
+ support_url: app.manifest.meta.support_url || '',
128
+ logo_url: `${serverUrl}/assets/logo.svg`,
129
+ icon_url: `${serverUrl}/assets/icon.svg`,
130
+ vendor: app.manifest.meta.vendor || '',
131
+ contact_email: app.manifest.meta.contact_email || '',
132
+ settings_url: `${serverUrl}/assets/settings.yml`,
133
+ content_settings_url: '', // Not available in local app manifest
134
+ content_template_url: '' // Not available in local app manifest
135
+ };
136
+ const now = new Date().toISOString();
137
+ // Check installation status from config store
138
+ const isInstalled = configStore.isInstalled();
139
+ // Return app details according to the API specification
140
+ const response = {
141
+ app: {
142
+ id: {
143
+ app_id: app.manifest.meta.app_id,
144
+ version: app.manifest.meta.version
145
+ },
146
+ metadata: metadata,
147
+ installed: isInstalled,
148
+ installed_at: isInstalled ? now : undefined,
149
+ installed_version: isInstalled ? app.manifest.meta.version : undefined,
150
+ created_at: now,
151
+ updated_at: now
152
+ }
153
+ };
154
+ res.json(response);
155
+ });
156
+ /**
157
+ * GET /v1/apps/{app_id}/versions/{version}
158
+ * Fetches details of a specific app version
159
+ */
160
+ router.get('/:app_id/versions/:version', (req, res) => {
161
+ const { app_id, version } = req.params;
162
+ // Get server URL from request
163
+ const protocol = req.secure ? 'https' : 'http';
164
+ const host = req.get('host') || `${config_1.config.server.host}:${config_1.config.server.port}`;
165
+ const serverUrl = `${protocol}://${host}`;
166
+ // Check if the requested app_id and version match our local app
167
+ if (app_id !== app.manifest.meta.app_id || version !== app.manifest.meta.version) {
168
+ return res.status(404).json({
169
+ error: {
170
+ message: `App version '${app_id}@${version}' not found`,
171
+ code: 'APP_VERSION_NOT_FOUND'
172
+ }
173
+ });
174
+ }
175
+ // Build app version metadata from manifest
176
+ const metadata = {
177
+ categories: app.manifest.meta.categories || [],
178
+ display_name: app.manifest.meta.display_name,
179
+ summary: app.manifest.meta.summary || '',
180
+ overview_url: `${serverUrl}/assets/overview.md`,
181
+ support_url: app.manifest.meta.support_url || '',
182
+ logo_url: `${serverUrl}/assets/logo.svg`,
183
+ icon_url: `${serverUrl}/assets/icon.svg`,
184
+ vendor: app.manifest.meta.vendor || '',
185
+ contact_email: app.manifest.meta.contact_email || '',
186
+ settings_url: `${serverUrl}/assets/settings.yml`,
187
+ content_settings_url: '', // Not available in local app manifest
188
+ content_template_url: '' // Not available in local app manifest
189
+ };
190
+ const now = new Date().toISOString();
191
+ // Return app version details according to the API specification
192
+ const response = {
193
+ app_version: {
194
+ id: {
195
+ app_id: app.manifest.meta.app_id,
196
+ version: app.manifest.meta.version
197
+ },
198
+ metadata: metadata,
199
+ created_at: now,
200
+ updated_at: now
201
+ }
202
+ };
203
+ res.json(response);
204
+ });
205
+ return router;
206
+ }
207
+ /**
208
+ * Create accounts-specific routes for /v1/accounts
209
+ */
210
+ function createAccountsRoutes(app, watcher, configStore, lifecycleExecutor, settingsStore) {
211
+ const router = express_1.default.Router();
212
+ /**
213
+ * GET /v1/accounts/{tracker_id}/installs
214
+ * Lists apps installed in an account
215
+ */
216
+ router.get("/:tracker_id/installs", (req, res) => {
217
+ const { tracker_id } = req.params;
218
+ const { categories, includes_features } = req.query;
219
+ const now = new Date().toISOString();
220
+ // Check installation status from config store
221
+ const isInstalled = configStore.isInstalled();
222
+ // If not installed, return empty array
223
+ if (!isInstalled) {
224
+ return res.json({
225
+ installations: [],
226
+ });
227
+ }
228
+ // Build the installation object for the local app
229
+ const installation = {
230
+ id: 1, // Static installation ID for local development
231
+ app_id: app.manifest.meta.app_id,
232
+ version: app.manifest.meta.version,
233
+ account_id: 123, // Static account ID for local development
234
+ tracker_id: tracker_id, // Use the provided tracker_id
235
+ app_instance_id: `${app.manifest.meta.app_id}-local-instance`,
236
+ created_at: now,
237
+ updated_at: now,
238
+ };
239
+ // Apply filters if provided
240
+ let installations = [installation];
241
+ // Filter by categories if specified
242
+ if (categories) {
243
+ const categoryFilters = Array.isArray(categories)
244
+ ? categories
245
+ : [categories];
246
+ const appCategories = app.manifest.meta.categories || [];
247
+ const hasMatchingCategory = categoryFilters.some((cat) => appCategories.includes(cat));
248
+ if (!hasMatchingCategory) {
249
+ installations = [];
250
+ }
251
+ }
252
+ // Filter by features if specified (1=DESTINATION_APP, 2=SOURCE_APP)
253
+ if (includes_features) {
254
+ const featureFilters = Array.isArray(includes_features)
255
+ ? includes_features
256
+ : [includes_features];
257
+ const hasDestinations = app.manifest.destinations &&
258
+ Object.keys(app.manifest.destinations).length > 0;
259
+ const hasSources = app.manifest.sources && Object.keys(app.manifest.sources).length > 0;
260
+ const hasMatchingFeature = featureFilters.some((feature) => {
261
+ return ((feature === "1" && hasDestinations) ||
262
+ (feature === "2" && hasSources));
263
+ });
264
+ if (!hasMatchingFeature) {
265
+ installations = [];
266
+ }
267
+ }
268
+ // Return the installations
269
+ res.json({
270
+ installations: installations,
271
+ });
272
+ });
273
+ /**
274
+ * POST /v1/accounts/{tracker_id}/installs
275
+ * Installs an AppVersion to an account
276
+ */
277
+ router.post("/:tracker_id/installs", async (req, res) => {
278
+ const { tracker_id } = req.params;
279
+ let { app_id, version } = req.body;
280
+ // Validate request body
281
+ if (!app_id) {
282
+ return res.status(400).json({
283
+ error: {
284
+ message: "app_id is required",
285
+ code: "INVALID_REQUEST",
286
+ },
287
+ });
288
+ }
289
+ if (!version) {
290
+ version = app.manifest.meta.version;
291
+ }
292
+ // Check if the requested app matches our local app
293
+ if (app_id !== app.manifest.meta.app_id ||
294
+ version !== app.manifest.meta.version) {
295
+ return res.status(404).json({
296
+ error: {
297
+ message: `App version '${app_id}@${version}' not found`,
298
+ code: "APP_VERSION_NOT_FOUND",
299
+ },
300
+ });
301
+ }
302
+ // Check if already installed
303
+ if (configStore.isInstalled()) {
304
+ return res.status(409).json({
305
+ error: {
306
+ message: "App is already installed",
307
+ code: "ALREADY_INSTALLED",
308
+ },
309
+ });
310
+ }
311
+ try {
312
+ // Execute the onInstall lifecycle method
313
+ const lifecycleResult = await lifecycleExecutor.executeInstall();
314
+ if (lifecycleResult.success) {
315
+ // Mark app as installed in config store
316
+ configStore.setInstalled(true);
317
+ const now = new Date().toISOString();
318
+ // Return installation record
319
+ const installation = {
320
+ id: 1, // Static installation ID for local development
321
+ app_id: app.manifest.meta.app_id,
322
+ version: app.manifest.meta.version,
323
+ account_id: 123, // Static account ID for local development
324
+ tracker_id: tracker_id,
325
+ app_instance_id: `${app.manifest.meta.app_id}-local-instance`,
326
+ created_at: now,
327
+ updated_at: now,
328
+ };
329
+ res.json({
330
+ app_installation: installation,
331
+ });
332
+ }
333
+ else {
334
+ // Installation failed - return error with lifecycle logs
335
+ res.status(500).json({
336
+ error: {
337
+ message: "Installation failed during lifecycle execution",
338
+ code: "LIFECYCLE_EXECUTION_FAILED",
339
+ details: {
340
+ logs: lifecycleResult.logs,
341
+ error: lifecycleResult.error,
342
+ executionTime: lifecycleResult.executionTime,
343
+ },
344
+ },
345
+ });
346
+ }
347
+ }
348
+ catch (error) {
349
+ // Unexpected error during installation
350
+ const errorMessage = error instanceof Error ? error.message : String(error);
351
+ res.status(500).json({
352
+ error: {
353
+ message: `Installation failed: ${errorMessage}`,
354
+ code: "INSTALLATION_ERROR",
355
+ },
356
+ });
357
+ }
358
+ });
359
+ /**
360
+ * DELETE /v1/accounts/{tracker_id}/installs/{app_id}
361
+ * Uninstalls an AppVersion from an account
362
+ */
363
+ router.delete("/:tracker_id/installs/:app_id", async (req, res) => {
364
+ const { tracker_id, app_id } = req.params;
365
+ // Check if the requested app matches our local app
366
+ if (app_id !== app.manifest.meta.app_id) {
367
+ return res.status(404).json({
368
+ error: {
369
+ message: `App with id '${app_id}' not found`,
370
+ code: "APP_NOT_FOUND",
371
+ },
372
+ });
373
+ }
374
+ // Check if app is installed
375
+ if (!configStore.isInstalled()) {
376
+ return res.status(404).json({
377
+ error: {
378
+ message: "App is not installed",
379
+ code: "NOT_INSTALLED",
380
+ },
381
+ });
382
+ }
383
+ try {
384
+ // Execute the onUninstall lifecycle method
385
+ const lifecycleResult = await lifecycleExecutor.executeUninstall();
386
+ if (lifecycleResult.success) {
387
+ // Mark app as not installed in config store
388
+ configStore.setInstalled(false);
389
+ // Clear all settings data
390
+ settingsStore.clearSettings();
391
+ // Clear function GUIDs
392
+ configStore.clearFunctionGuids();
393
+ // Return 200 OK as specified in the API documentation
394
+ res.status(200).send({});
395
+ }
396
+ else {
397
+ // Uninstall failed - return error with lifecycle logs
398
+ res.status(500).json({
399
+ error: {
400
+ message: "Uninstall failed during lifecycle execution",
401
+ code: "LIFECYCLE_EXECUTION_FAILED",
402
+ details: {
403
+ logs: lifecycleResult.logs,
404
+ error: lifecycleResult.error,
405
+ executionTime: lifecycleResult.executionTime,
406
+ },
407
+ },
408
+ });
409
+ }
410
+ }
411
+ catch (error) {
412
+ // Unexpected error during uninstall
413
+ const errorMessage = error instanceof Error ? error.message : String(error);
414
+ res.status(500).json({
415
+ error: {
416
+ message: `Uninstall failed: ${errorMessage}`,
417
+ code: "UNINSTALL_ERROR",
418
+ },
419
+ });
420
+ }
421
+ });
422
+ return router;
423
+ }
424
+ /**
425
+ * Create installs-specific routes for /v1/installs
426
+ */
427
+ function createInstallsRoutes(app, watcher, configStore, settingsStore, lifecycleExecutor) {
428
+ const router = express_1.default.Router();
429
+ /**
430
+ * GET /v1/installs/{app_install_id}/settings
431
+ * Gets stored app secrets for a setup form
432
+ */
433
+ router.get("/:app_install_id/settings", (req, res) => {
434
+ const { app_install_id } = req.params;
435
+ // Validate app_install_id (should be numeric for our implementation)
436
+ const installId = parseInt(app_install_id, 10);
437
+ if (isNaN(installId)) {
438
+ return res.status(400).json({
439
+ error: {
440
+ message: "app_install_id must be a valid number",
441
+ code: "INVALID_INSTALL_ID",
442
+ },
443
+ });
444
+ }
445
+ // Check if app is installed (for local dev, we use install ID 1)
446
+ if (!configStore.isInstalled()) {
447
+ return res.status(404).json({
448
+ error: {
449
+ message: "App installation not found",
450
+ code: "INSTALLATION_NOT_FOUND",
451
+ },
452
+ });
453
+ }
454
+ // For local development, we only support install ID 1
455
+ if (installId !== 1) {
456
+ return res.status(404).json({
457
+ error: {
458
+ message: `Installation with ID ${installId} not found`,
459
+ code: "INSTALLATION_NOT_FOUND",
460
+ },
461
+ });
462
+ }
463
+ try {
464
+ // Get form data with secret fields redacted (matches OCP behavior)
465
+ const formData = settingsStore.getRedactedFormData();
466
+ // Convert to JSON string
467
+ const formDataJson = JSON.stringify(formData);
468
+ // Return settings according to API specification
469
+ res.json({
470
+ form_data_json: formDataJson,
471
+ error: null, // No error if successful
472
+ });
473
+ }
474
+ catch (error) {
475
+ // Return error response
476
+ const errorMessage = error instanceof Error ? error.message : String(error);
477
+ res.json({
478
+ form_data_json: "{}",
479
+ error: {
480
+ message: errorMessage,
481
+ },
482
+ });
483
+ }
484
+ });
485
+ /**
486
+ * POST /v1/installs/{app_install_id}/settings
487
+ * Submits app settings form and calls onSettingsForm lifecycle method
488
+ */
489
+ router.post("/:app_install_id/settings", async (req, res) => {
490
+ const { app_install_id } = req.params;
491
+ const { form_page, action, form_data_json } = req.body;
492
+ // Validate app_install_id (should be numeric for our implementation)
493
+ const installId = parseInt(app_install_id, 10);
494
+ if (isNaN(installId)) {
495
+ return res.status(400).json({
496
+ error: {
497
+ message: "app_install_id must be a valid number",
498
+ code: "INVALID_INSTALL_ID",
499
+ },
500
+ });
501
+ }
502
+ // Check if app is installed (for local dev, we use install ID 1)
503
+ if (!configStore.isInstalled()) {
504
+ return res.status(404).json({
505
+ error: {
506
+ message: "App installation not found",
507
+ code: "INSTALLATION_NOT_FOUND",
508
+ },
509
+ });
510
+ }
511
+ // For local development, we only support install ID 1
512
+ if (installId !== 1) {
513
+ return res.status(404).json({
514
+ error: {
515
+ message: `Installation with ID ${installId} not found`,
516
+ code: "INSTALLATION_NOT_FOUND",
517
+ },
518
+ });
519
+ }
520
+ // Validate required fields
521
+ if (!form_page) {
522
+ return res.status(400).json({
523
+ error: {
524
+ message: "section is required",
525
+ code: "INVALID_REQUEST",
526
+ },
527
+ });
528
+ }
529
+ if (!action) {
530
+ return res.status(400).json({
531
+ error: {
532
+ message: "action is required",
533
+ code: "INVALID_REQUEST",
534
+ },
535
+ });
536
+ }
537
+ try {
538
+ // Parse form_data_json if it's a string
539
+ let formData;
540
+ if (typeof form_data_json === "string") {
541
+ try {
542
+ formData = JSON.parse(form_data_json);
543
+ }
544
+ catch (e) {
545
+ formData = {};
546
+ }
547
+ }
548
+ else {
549
+ formData = form_data_json || {};
550
+ }
551
+ // Execute the onSettingsForm lifecycle method first
552
+ const lifecycleResult = await lifecycleExecutor.executeSettingsForm(form_page, action, formData);
553
+ if (lifecycleResult.success) {
554
+ // Get the lifecycle result which should be in the format: { result: LifecycleSettingsResponse, data: FormData }
555
+ const lifecycleData = lifecycleResult.result;
556
+ // Extract the response component from the lifecycle result
557
+ let settingsResponse = {};
558
+ if (lifecycleData && typeof lifecycleData === "object") {
559
+ settingsResponse = lifecycleData.result || {};
560
+ }
561
+ // Get the updated form data with secret fields redacted (matches OCP behavior)
562
+ const updatedFormData = settingsStore.getRedactedFormData();
563
+ // Return response in the format expected by the REST API (matching AnduinServer.submitForm)
564
+ res.json({
565
+ form_data_json: JSON.stringify(updatedFormData),
566
+ response_json: JSON.stringify(settingsResponse),
567
+ });
568
+ }
569
+ else {
570
+ // Lifecycle execution failed
571
+ res.status(500).json({
572
+ error: {
573
+ message: "Settings form processing failed during lifecycle execution",
574
+ code: "LIFECYCLE_EXECUTION_FAILED",
575
+ details: {
576
+ logs: lifecycleResult.logs,
577
+ error: lifecycleResult.error,
578
+ executionTime: lifecycleResult.executionTime,
579
+ },
580
+ },
581
+ });
582
+ }
583
+ }
584
+ catch (error) {
585
+ // Unexpected error during settings form processing
586
+ const errorMessage = error instanceof Error ? error.message : String(error);
587
+ res.status(500).json({
588
+ error: {
589
+ message: `Settings form processing failed: ${errorMessage}`,
590
+ code: "SETTINGS_FORM_ERROR",
591
+ },
592
+ });
593
+ }
594
+ });
595
+ /**
596
+ * GET /v1/installs/{app_install_id}/functions
597
+ * Lists functions with their invocation URLs for the installation
598
+ * Used by frontend to resolve dataSource function references
599
+ */
600
+ router.get("/:app_install_id/functions", (req, res) => {
601
+ const { app_install_id } = req.params;
602
+ // Validate app_install_id
603
+ const installId = parseInt(app_install_id, 10);
604
+ if (isNaN(installId)) {
605
+ return res.status(400).json({
606
+ error: {
607
+ message: "app_install_id must be a valid number",
608
+ code: "INVALID_INSTALL_ID",
609
+ },
610
+ });
611
+ }
612
+ // Check if app is installed
613
+ if (!configStore.isInstalled()) {
614
+ return res.status(404).json({
615
+ error: {
616
+ message: "App installation not found",
617
+ code: "INSTALLATION_NOT_FOUND",
618
+ },
619
+ });
620
+ }
621
+ // For local development, we only support install ID 1
622
+ if (installId !== 1) {
623
+ return res.status(404).json({
624
+ error: {
625
+ message: `Installation with ID ${installId} not found`,
626
+ code: "INSTALLATION_NOT_FOUND",
627
+ },
628
+ });
629
+ }
630
+ // Build function URL map
631
+ const protocol = req.secure ? "https" : "http";
632
+ const host = req.get("host") || "localhost:3000";
633
+ const baseUrl = `${protocol}://${host}`;
634
+ const functionEndpoints = (0, functionEndpoints_1.buildAllFunctionEndpoints)({
635
+ baseUrl,
636
+ appId: app.manifest.meta.app_id,
637
+ functions: app.manifest.functions || {},
638
+ getGuid: (functionId) => configStore.getFunctionGuid(functionId),
639
+ });
640
+ res.json({
641
+ function_endpoints: functionEndpoints,
642
+ });
643
+ });
644
+ /**
645
+ * GET /v1/installs/{app_install_id}/canUninstall
646
+ * Checks if an app installation can be uninstalled
647
+ */
648
+ router.get("/:app_install_id/canUninstall", async (req, res) => {
649
+ const { app_install_id } = req.params;
650
+ // Validate app_install_id (should be numeric for our implementation)
651
+ const installId = parseInt(app_install_id, 10);
652
+ if (isNaN(installId)) {
653
+ return res.status(400).json({
654
+ error: {
655
+ message: "app_install_id must be a valid number",
656
+ code: "INVALID_INSTALL_ID",
657
+ },
658
+ });
659
+ }
660
+ // Check if app is installed (for local dev, we use install ID 1)
661
+ if (!configStore.isInstalled()) {
662
+ return res.status(404).json({
663
+ error: {
664
+ message: "App installation not found",
665
+ code: "INSTALLATION_NOT_FOUND",
666
+ },
667
+ });
668
+ }
669
+ // For local development, we only support install ID 1
670
+ if (installId !== 1) {
671
+ return res.status(404).json({
672
+ error: {
673
+ message: `Installation with ID ${installId} not found`,
674
+ code: "INSTALLATION_NOT_FOUND",
675
+ },
676
+ });
677
+ }
678
+ try {
679
+ // Execute the canUninstall lifecycle method
680
+ const lifecycleResult = await lifecycleExecutor.executeCanUninstall();
681
+ if (lifecycleResult.success) {
682
+ // Parse the result from the lifecycle method
683
+ const canUninstallResult = lifecycleResult.result;
684
+ // Return the response in the expected format
685
+ res.json({
686
+ uninstallable: canUninstallResult?.uninstallable || false,
687
+ message: canUninstallResult?.message,
688
+ });
689
+ }
690
+ else {
691
+ // Lifecycle execution failed - return error response
692
+ res.status(500).json({
693
+ error: {
694
+ message: "Failed to check uninstall status during lifecycle execution",
695
+ code: "LIFECYCLE_EXECUTION_FAILED",
696
+ details: {
697
+ logs: lifecycleResult.logs,
698
+ error: lifecycleResult.error,
699
+ executionTime: lifecycleResult.executionTime,
700
+ },
701
+ },
702
+ });
703
+ }
704
+ }
705
+ catch (error) {
706
+ // Unexpected error during canUninstall check - return error response
707
+ const errorMessage = error instanceof Error ? error.message : String(error);
708
+ res.status(500).json({
709
+ error: {
710
+ message: `Error checking uninstall status: ${errorMessage}`,
711
+ code: "CAN_UNINSTALL_ERROR",
712
+ },
713
+ });
714
+ }
715
+ });
716
+ return router;
717
+ }
718
+ //# sourceMappingURL=v1.js.map