@kapeta/local-cluster-service 0.16.8 → 0.18.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 (96) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/index.js +6 -2
  3. package/dist/cjs/src/assetManager.d.ts +2 -2
  4. package/dist/cjs/src/assetManager.js +16 -16
  5. package/dist/cjs/src/assets/routes.js +2 -2
  6. package/dist/cjs/src/authManager.d.ts +12 -0
  7. package/dist/cjs/src/authManager.js +60 -0
  8. package/dist/cjs/src/codeGeneratorManager.d.ts +1 -1
  9. package/dist/cjs/src/codeGeneratorManager.js +3 -3
  10. package/dist/cjs/src/configManager.js +2 -2
  11. package/dist/cjs/src/definitionsManager.d.ts +7 -6
  12. package/dist/cjs/src/definitionsManager.js +102 -18
  13. package/dist/cjs/src/instanceManager.d.ts +1 -1
  14. package/dist/cjs/src/instanceManager.js +4 -4
  15. package/dist/cjs/src/instances/routes.js +2 -2
  16. package/dist/cjs/src/operatorManager.d.ts +1 -1
  17. package/dist/cjs/src/operatorManager.js +7 -9
  18. package/dist/cjs/src/providerManager.d.ts +2 -1
  19. package/dist/cjs/src/providerManager.js +23 -15
  20. package/dist/cjs/src/repositoryManager.d.ts +2 -2
  21. package/dist/cjs/src/repositoryManager.js +8 -9
  22. package/dist/cjs/src/socketManager.js +6 -0
  23. package/dist/cjs/src/utils/BlockInstanceRunner.js +6 -8
  24. package/dist/cjs/src/utils/DefaultProviderInstaller.d.ts +11 -0
  25. package/dist/cjs/src/utils/DefaultProviderInstaller.js +129 -0
  26. package/dist/esm/index.js +67 -58
  27. package/dist/esm/src/RepositoryWatcher.js +40 -33
  28. package/dist/esm/src/api.js +14 -9
  29. package/dist/esm/src/assetManager.d.ts +2 -2
  30. package/dist/esm/src/assetManager.js +73 -67
  31. package/dist/esm/src/assets/routes.js +23 -18
  32. package/dist/esm/src/attachments/routes.js +14 -9
  33. package/dist/esm/src/authManager.d.ts +12 -0
  34. package/dist/esm/src/authManager.js +60 -0
  35. package/dist/esm/src/cacheManager.js +13 -5
  36. package/dist/esm/src/clusterService.js +6 -3
  37. package/dist/esm/src/codeGeneratorManager.d.ts +1 -1
  38. package/dist/esm/src/codeGeneratorManager.js +20 -14
  39. package/dist/esm/src/config/routes.js +30 -25
  40. package/dist/esm/src/configManager.js +29 -26
  41. package/dist/esm/src/containerManager.js +48 -39
  42. package/dist/esm/src/definitionsManager.d.ts +7 -6
  43. package/dist/esm/src/definitionsManager.js +114 -24
  44. package/dist/esm/src/filesystem/routes.js +21 -16
  45. package/dist/esm/src/filesystemManager.js +23 -17
  46. package/dist/esm/src/identities/routes.js +13 -8
  47. package/dist/esm/src/instanceManager.d.ts +1 -1
  48. package/dist/esm/src/instanceManager.js +165 -158
  49. package/dist/esm/src/instances/routes.js +39 -34
  50. package/dist/esm/src/middleware/cors.js +5 -1
  51. package/dist/esm/src/middleware/kapeta.js +8 -4
  52. package/dist/esm/src/middleware/stringBody.js +5 -1
  53. package/dist/esm/src/networkManager.js +15 -9
  54. package/dist/esm/src/operatorManager.d.ts +1 -1
  55. package/dist/esm/src/operatorManager.js +48 -44
  56. package/dist/esm/src/progressListener.js +16 -12
  57. package/dist/esm/src/providerManager.d.ts +2 -1
  58. package/dist/esm/src/providerManager.js +43 -29
  59. package/dist/esm/src/providers/routes.js +14 -9
  60. package/dist/esm/src/proxy/routes.js +26 -21
  61. package/dist/esm/src/proxy/types/rest.js +29 -22
  62. package/dist/esm/src/proxy/types/web.js +18 -11
  63. package/dist/esm/src/repositoryManager.d.ts +2 -2
  64. package/dist/esm/src/repositoryManager.js +33 -28
  65. package/dist/esm/src/serviceManager.js +25 -19
  66. package/dist/esm/src/socketManager.js +31 -18
  67. package/dist/esm/src/storageService.js +18 -12
  68. package/dist/esm/src/taskManager.js +12 -8
  69. package/dist/esm/src/tasks/routes.js +14 -9
  70. package/dist/esm/src/traffic/routes.js +12 -7
  71. package/dist/esm/src/types.js +11 -8
  72. package/dist/esm/src/utils/BlockInstanceRunner.js +60 -55
  73. package/dist/esm/src/utils/DefaultProviderInstaller.d.ts +11 -0
  74. package/dist/esm/src/utils/DefaultProviderInstaller.js +129 -0
  75. package/dist/esm/src/utils/LogData.js +5 -1
  76. package/dist/esm/src/utils/commandLineUtils.js +12 -7
  77. package/dist/esm/src/utils/pathTemplateParser.js +7 -2
  78. package/dist/esm/src/utils/utils.js +30 -17
  79. package/dist/esm/start.js +7 -2
  80. package/index.ts +7 -2
  81. package/package.json +10 -4
  82. package/src/assetManager.ts +18 -16
  83. package/src/assets/routes.ts +2 -2
  84. package/src/authManager.ts +62 -0
  85. package/src/codeGeneratorManager.ts +3 -3
  86. package/src/configManager.ts +2 -2
  87. package/src/definitionsManager.ts +132 -17
  88. package/src/instanceManager.ts +5 -5
  89. package/src/instances/routes.ts +2 -2
  90. package/src/operatorManager.ts +7 -12
  91. package/src/providerManager.ts +27 -19
  92. package/src/repositoryManager.ts +8 -11
  93. package/src/socketManager.ts +6 -0
  94. package/src/utils/BlockInstanceRunner.ts +6 -8
  95. package/src/utils/DefaultProviderInstaller.ts +141 -0
  96. package/tsconfig.json +3 -2
@@ -1,13 +1,19 @@
1
- import FS from 'node:fs';
2
- import ClusterConfig from '@kapeta/local-cluster-config';
3
- import { getBindHost, getBlockInstanceContainerName, normalizeKapetaUri, readYML } from './utils';
4
- import { parseKapetaUri } from '@kapeta/nodejs-utils';
5
- import { serviceManager } from '../serviceManager';
6
- import { containerManager, toLocalBindVolume } from '../containerManager';
7
- import { LogData } from './LogData';
8
- import { clusterService } from '../clusterService';
9
- import { InstanceType } from '../types';
10
- import { definitionsManager } from '../definitionsManager';
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.BlockInstanceRunner = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
9
+ const utils_1 = require("./utils");
10
+ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
11
+ const serviceManager_1 = require("../serviceManager");
12
+ const containerManager_1 = require("../containerManager");
13
+ const LogData_1 = require("./LogData");
14
+ const clusterService_1 = require("../clusterService");
15
+ const types_1 = require("../types");
16
+ const definitionsManager_1 = require("../definitionsManager");
11
17
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
12
18
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
13
19
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
@@ -21,10 +27,11 @@ const DOCKER_ENV_VARS = [
21
27
  `KAPETA_LOCAL_CLUSTER_HOST=host.docker.internal`,
22
28
  `KAPETA_ENVIRONMENT_TYPE=docker`,
23
29
  ];
24
- function getProvider(uri) {
25
- return definitionsManager.getProviderDefinitions().find((provider) => {
30
+ async function getProvider(uri) {
31
+ const providers = await definitionsManager_1.definitionsManager.getProviderDefinitions();
32
+ return providers.find((provider) => {
26
33
  const ref = `${provider.definition.metadata.name}:${provider.version}`;
27
- return parseKapetaUri(ref).id === uri.id;
34
+ return (0, nodejs_utils_1.parseKapetaUri)(ref).id === uri.id;
28
35
  });
29
36
  }
30
37
  function getProviderPorts(assetVersion) {
@@ -34,7 +41,7 @@ function getProviderPorts(assetVersion) {
34
41
  })
35
42
  .filter((t) => !!t) ?? []);
36
43
  }
37
- export class BlockInstanceRunner {
44
+ class BlockInstanceRunner {
38
45
  _systemId;
39
46
  constructor(systemId) {
40
47
  /**
@@ -42,7 +49,7 @@ export class BlockInstanceRunner {
42
49
  * @type {string}
43
50
  * @private
44
51
  */
45
- this._systemId = normalizeKapetaUri(systemId);
52
+ this._systemId = (0, utils_1.normalizeKapetaUri)(systemId);
46
53
  }
47
54
  /**
48
55
  * Start a block
@@ -66,19 +73,16 @@ export class BlockInstanceRunner {
66
73
  if (blockInstance.id) {
67
74
  env[KAPETA_INSTANCE_ID] = blockInstance.id;
68
75
  }
69
- const blockUri = parseKapetaUri(blockInstance.ref);
76
+ const blockUri = (0, nodejs_utils_1.parseKapetaUri)(blockInstance.ref);
70
77
  if (!blockUri.version) {
71
78
  blockUri.version = 'local';
72
79
  }
73
- const assetVersion = definitionsManager.getDefinitions().find((definitions) => {
74
- const ref = `${definitions.definition.metadata.name}:${definitions.version}`;
75
- return parseKapetaUri(ref).id === blockUri.id;
76
- });
80
+ const assetVersion = await definitionsManager_1.definitionsManager.getDefinition(blockUri.id);
77
81
  if (!assetVersion) {
78
82
  throw new Error(`Block definition not found: ${blockUri.id}`);
79
83
  }
80
- const kindUri = parseKapetaUri(assetVersion.definition.kind);
81
- const providerVersion = getProvider(kindUri);
84
+ const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.kind);
85
+ const providerVersion = await getProvider(kindUri);
82
86
  if (!providerVersion) {
83
87
  throw new Error(`Kind not found: ${kindUri.id}`);
84
88
  }
@@ -105,16 +109,16 @@ export class BlockInstanceRunner {
105
109
  * Starts local process
106
110
  */
107
111
  async _startLocalProcess(blockInstance, blockInfo, env, assetVersion) {
108
- const baseDir = ClusterConfig.getRepositoryAssetPath(blockInfo.handle, blockInfo.name, blockInfo.version);
109
- if (!FS.existsSync(baseDir)) {
112
+ const baseDir = local_cluster_config_1.default.getRepositoryAssetPath(blockInfo.handle, blockInfo.name, blockInfo.version);
113
+ if (!node_fs_1.default.existsSync(baseDir)) {
110
114
  throw new Error(`Local block not registered correctly - expected symlink here: ${baseDir}.\n` +
111
115
  `Make sure you've run "blockctl registry link" in your local directory to connect it to Kapeta`);
112
116
  }
113
117
  if (!assetVersion.definition.spec?.target?.kind) {
114
118
  throw new Error('Missing target kind in block definition');
115
119
  }
116
- const kindUri = parseKapetaUri(assetVersion.definition.spec?.target?.kind);
117
- const targetVersion = getProvider(kindUri);
120
+ const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.spec?.target?.kind);
121
+ const targetVersion = await getProvider(kindUri);
118
122
  if (!targetVersion) {
119
123
  throw new Error(`Target not found: ${kindUri.id}`);
120
124
  }
@@ -126,7 +130,7 @@ export class BlockInstanceRunner {
126
130
  if (!dockerImage) {
127
131
  throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
128
132
  }
129
- const containerName = getBlockInstanceContainerName(this._systemId, blockInstance.id);
133
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
130
134
  const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
131
135
  const dockerOpts = localContainer.options ?? {};
132
136
  const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
@@ -134,7 +138,7 @@ export class BlockInstanceRunner {
134
138
  const { PortBindings, ExposedPorts, addonEnv } = await this.getDockerPortBindings(blockInstance, assetVersion);
135
139
  let HealthCheck = undefined;
136
140
  if (localContainer.healthcheck) {
137
- HealthCheck = containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
141
+ HealthCheck = containerManager_1.containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
138
142
  }
139
143
  return this.ensureContainer({
140
144
  Image: dockerImage,
@@ -148,7 +152,7 @@ export class BlockInstanceRunner {
148
152
  Cmd: startCmd ? startCmd.split(/\s+/g) : [],
149
153
  Env: [
150
154
  ...DOCKER_ENV_VARS,
151
- `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
155
+ `KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
152
156
  ...Object.entries({
153
157
  ...env,
154
158
  ...addonEnv,
@@ -156,8 +160,8 @@ export class BlockInstanceRunner {
156
160
  ],
157
161
  HostConfig: {
158
162
  Binds: [
159
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${homeDir}/.kapeta`,
160
- `${toLocalBindVolume(baseDir)}:${workingDir}`,
163
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`,
164
+ `${(0, containerManager_1.toLocalBindVolume)(baseDir)}:${workingDir}`,
161
165
  ],
162
166
  PortBindings,
163
167
  },
@@ -165,12 +169,12 @@ export class BlockInstanceRunner {
165
169
  });
166
170
  }
167
171
  async _startDockerProcess(blockInstance, blockInfo, env, assetVersion) {
168
- const { versionFile } = ClusterConfig.getRepositoryAssetInfoPath(blockInfo.handle, blockInfo.name, blockInfo.version);
172
+ const { versionFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockInfo.handle, blockInfo.name, blockInfo.version);
169
173
  const versionYml = versionFile;
170
- if (!FS.existsSync(versionYml)) {
174
+ if (!node_fs_1.default.existsSync(versionYml)) {
171
175
  throw new Error(`Did not find version info at the expected path: ${versionYml}`);
172
176
  }
173
- const versionInfo = readYML(versionYml);
177
+ const versionInfo = (0, utils_1.readYML)(versionYml);
174
178
  if (versionInfo?.artifact?.type !== 'docker') {
175
179
  throw new Error(`Unsupported artifact type: ${versionInfo?.artifact?.type}`);
176
180
  }
@@ -179,9 +183,9 @@ export class BlockInstanceRunner {
179
183
  throw new Error(`Missing docker image information: ${JSON.stringify(versionInfo?.artifact?.details)}`);
180
184
  }
181
185
  const { PortBindings, ExposedPorts, addonEnv } = await this.getDockerPortBindings(blockInstance, assetVersion);
182
- const containerName = getBlockInstanceContainerName(this._systemId, blockInstance.id);
186
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
183
187
  // For windows we need to default to root
184
- const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
188
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
185
189
  return this.ensureContainer({
186
190
  Image: dockerImage,
187
191
  name: containerName,
@@ -191,14 +195,14 @@ export class BlockInstanceRunner {
191
195
  },
192
196
  Env: [
193
197
  ...DOCKER_ENV_VARS,
194
- `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
198
+ `KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
195
199
  ...Object.entries({
196
200
  ...env,
197
201
  ...addonEnv,
198
202
  }).map(([key, value]) => `${key}=${value}`),
199
203
  ],
200
204
  HostConfig: {
201
- Binds: [`${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`],
205
+ Binds: [`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`],
202
206
  PortBindings,
203
207
  },
204
208
  });
@@ -213,9 +217,9 @@ export class BlockInstanceRunner {
213
217
  * @private
214
218
  */
215
219
  async _startOperatorProcess(blockInstance, blockUri, providerDefinition, env) {
216
- const { assetFile } = ClusterConfig.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
220
+ const { assetFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
217
221
  const kapetaYmlPath = assetFile;
218
- if (!FS.existsSync(kapetaYmlPath)) {
222
+ if (!node_fs_1.default.existsSync(kapetaYmlPath)) {
219
223
  throw new Error(`Did not find kapeta.yml at the expected path: ${kapetaYmlPath}`);
220
224
  }
221
225
  const spec = providerDefinition.definition.spec;
@@ -225,9 +229,9 @@ export class BlockInstanceRunner {
225
229
  }
226
230
  const dockerImage = spec?.local?.image;
227
231
  //We only want 1 operator per operator type - across all local systems
228
- const containerName = getBlockInstanceContainerName(this._systemId, blockInstance.id);
229
- const logs = new LogData();
230
- const bindHost = getBindHost();
232
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
233
+ const logs = new LogData_1.LogData();
234
+ const bindHost = (0, utils_1.getBindHost)();
231
235
  const ExposedPorts = {};
232
236
  const addonEnv = {};
233
237
  const PortBindings = {};
@@ -237,7 +241,7 @@ export class BlockInstanceRunner {
237
241
  const dockerPort = `${value.port}/${value.type}`;
238
242
  ExposedPorts[dockerPort] = {};
239
243
  addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = value.port;
240
- const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
244
+ const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
241
245
  PortBindings[dockerPort] = [
242
246
  {
243
247
  HostIp: bindHost,
@@ -252,14 +256,14 @@ export class BlockInstanceRunner {
252
256
  });
253
257
  }
254
258
  if (spec.local?.mounts) {
255
- const mounts = await containerManager.createMounts(this._systemId, blockUri.id, spec.local.mounts);
256
- Mounts = containerManager.toDockerMounts(mounts);
259
+ const mounts = await containerManager_1.containerManager.createMounts(this._systemId, blockUri.id, spec.local.mounts);
260
+ Mounts = containerManager_1.containerManager.toDockerMounts(mounts);
257
261
  }
258
262
  if (spec.local?.health) {
259
- HealthCheck = containerManager.toDockerHealth(spec.local?.health);
263
+ HealthCheck = containerManager_1.containerManager.toDockerHealth(spec.local?.health);
260
264
  }
261
265
  // For windows we need to default to root
262
- const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
266
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
263
267
  logs.addLog(`Creating new container for block: ${containerName}`);
264
268
  const out = await this.ensureContainer({
265
269
  Image: dockerImage,
@@ -268,8 +272,8 @@ export class BlockInstanceRunner {
268
272
  HealthCheck,
269
273
  HostConfig: {
270
274
  Binds: [
271
- `${toLocalBindVolume(kapetaYmlPath)}:/kapeta.yml:ro`,
272
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
275
+ `${(0, containerManager_1.toLocalBindVolume)(kapetaYmlPath)}:/kapeta.yml:ro`,
276
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`,
273
277
  ],
274
278
  PortBindings,
275
279
  Mounts,
@@ -279,7 +283,7 @@ export class BlockInstanceRunner {
279
283
  },
280
284
  Env: [
281
285
  `KAPETA_INSTANCE_NAME=${blockInstance.ref}`,
282
- `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
286
+ `KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
283
287
  ...DOCKER_ENV_VARS,
284
288
  ...Object.entries({
285
289
  ...env,
@@ -294,14 +298,14 @@ export class BlockInstanceRunner {
294
298
  return out;
295
299
  }
296
300
  async getDockerPortBindings(blockInstance, assetVersion) {
297
- const bindHost = getBindHost();
301
+ const bindHost = (0, utils_1.getBindHost)();
298
302
  const ExposedPorts = {};
299
303
  const addonEnv = {};
300
304
  const PortBindings = {};
301
305
  const portTypes = getProviderPorts(assetVersion);
302
306
  let port = 80;
303
307
  const promises = portTypes.map(async (portType) => {
304
- const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
308
+ const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
305
309
  const thisPort = port++; //TODO: Not sure how we should handle multiple ports or non-HTTP ports
306
310
  const dockerPort = `${thisPort}/tcp`;
307
311
  ExposedPorts[dockerPort] = {};
@@ -317,13 +321,14 @@ export class BlockInstanceRunner {
317
321
  return { PortBindings, ExposedPorts, addonEnv };
318
322
  }
319
323
  async ensureContainer(opts) {
320
- const container = await containerManager.ensureContainer(opts);
324
+ const container = await containerManager_1.containerManager.ensureContainer(opts);
321
325
  return this._handleContainer(container);
322
326
  }
323
327
  async _handleContainer(container) {
324
328
  return {
325
- type: InstanceType.DOCKER,
329
+ type: types_1.InstanceType.DOCKER,
326
330
  pid: container.id,
327
331
  };
328
332
  }
329
333
  }
334
+ exports.BlockInstanceRunner = BlockInstanceRunner;
@@ -0,0 +1,11 @@
1
+ declare class DefaultProviderInstaller {
2
+ private readonly progressListener;
3
+ checkForDefault(): Promise<void>;
4
+ private install;
5
+ private linkLocal;
6
+ private scanProjectBase;
7
+ private ensureDefaultProjectHome;
8
+ private download;
9
+ }
10
+ export declare const defaultProviderInstaller: DefaultProviderInstaller;
11
+ export {};
@@ -0,0 +1,129 @@
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.defaultProviderInstaller = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_os_1 = __importDefault(require("node:os"));
9
+ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
10
+ const fs_extra_1 = __importDefault(require("fs-extra"));
11
+ const request_1 = __importDefault(require("request"));
12
+ const tar_stream_1 = require("tar-stream");
13
+ const gunzip_maybe_1 = __importDefault(require("gunzip-maybe"));
14
+ const filesystemManager_1 = require("../filesystemManager");
15
+ const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
16
+ const progressListener_1 = require("../progressListener");
17
+ const glob_1 = require("glob");
18
+ const DEFAULT_PROVIDERS_URL = 'https://storage.googleapis.com/kapeta-production-cdn/archives/default-providers.tar.gz';
19
+ const DEFAULT_PROJECT_HOME_DIR = 'KapetaProjects';
20
+ const ARCHIVE_LOCAL_PREFIX = 'local';
21
+ class DefaultProviderInstaller {
22
+ progressListener = new progressListener_1.ProgressListener();
23
+ async checkForDefault() {
24
+ const definitions = local_cluster_config_1.default.getDefinitions();
25
+ if (definitions.length < 1) {
26
+ console.log('Installing default providers');
27
+ try {
28
+ await this.install();
29
+ }
30
+ catch (e) {
31
+ console.warn('Failed to install defaults', e);
32
+ }
33
+ }
34
+ }
35
+ async install() {
36
+ await this.download();
37
+ await this.linkLocal();
38
+ }
39
+ async linkLocal() {
40
+ const projectBase = await this.ensureDefaultProjectHome();
41
+ const folders = this.scanProjectBase(projectBase);
42
+ for (let folder of folders) {
43
+ console.log('Linking %s', folder);
44
+ await nodejs_registry_utils_1.Actions.link(this.progressListener, folder);
45
+ }
46
+ }
47
+ scanProjectBase(projectBase) {
48
+ const assetFiles = glob_1.glob.sync('*/**/kapeta.yml', { cwd: projectBase });
49
+ return assetFiles.map((assetFile) => {
50
+ return node_path_1.default.dirname(node_path_1.default.join(projectBase, assetFile));
51
+ });
52
+ }
53
+ async ensureDefaultProjectHome() {
54
+ const defaultProjectHome = node_path_1.default.join(node_os_1.default.homedir(), DEFAULT_PROJECT_HOME_DIR);
55
+ let projectBase = filesystemManager_1.filesystemManager.getProjectRootFolder();
56
+ if (!projectBase) {
57
+ filesystemManager_1.filesystemManager.setProjectRootFolder(defaultProjectHome);
58
+ projectBase = defaultProjectHome;
59
+ if (!(await fs_extra_1.default.pathExists(projectBase))) {
60
+ await fs_extra_1.default.mkdirp(projectBase);
61
+ }
62
+ }
63
+ return projectBase;
64
+ }
65
+ async download() {
66
+ const projectBase = await this.ensureDefaultProjectHome();
67
+ const repoBase = local_cluster_config_1.default.getRepositoryBasedir();
68
+ return new Promise((resolve, reject) => {
69
+ const extractor = (0, tar_stream_1.extract)();
70
+ const dirCache = new Set();
71
+ extractor.on('entry', async function (header, stream, next) {
72
+ if (header.type !== 'file') {
73
+ stream.on('end', function () {
74
+ next(); // ready for next entry
75
+ });
76
+ stream.resume(); // just auto drain the stream
77
+ return;
78
+ }
79
+ // Local (editable) assets should be stored in the project folder
80
+ // - installed assets goes into the repository folder
81
+ const baseDir = header.name.startsWith(ARCHIVE_LOCAL_PREFIX) ? projectBase : repoBase;
82
+ const parts = header.name.split(/\//g);
83
+ parts.shift();
84
+ const filename = parts.join(node_path_1.default.sep);
85
+ try {
86
+ const dirname = node_path_1.default.join(baseDir, node_path_1.default.dirname(filename));
87
+ if (!dirCache.has(dirname)) {
88
+ let dirExists = false;
89
+ try {
90
+ await fs_extra_1.default.stat(dirname);
91
+ dirExists = true;
92
+ }
93
+ catch (e) { }
94
+ if (!dirExists) {
95
+ await fs_extra_1.default.mkdirp(dirname);
96
+ }
97
+ dirCache.add(dirname);
98
+ }
99
+ const fileTarget = node_path_1.default.join(baseDir, filename);
100
+ stream.on('error', (err) => {
101
+ reject(err);
102
+ });
103
+ stream.on('end', next);
104
+ stream.pipe(fs_extra_1.default.createWriteStream(fileTarget, {
105
+ mode: header.mode,
106
+ }));
107
+ }
108
+ catch (e) {
109
+ reject(e);
110
+ }
111
+ });
112
+ extractor.on('finish', function () {
113
+ // all entries done - lets finalize it
114
+ console.log('Default providers installed');
115
+ resolve();
116
+ });
117
+ extractor.on('error', function (err) {
118
+ reject(err);
119
+ });
120
+ console.log('Downloading default providers from %s', DEFAULT_PROVIDERS_URL);
121
+ const response = (0, request_1.default)(DEFAULT_PROVIDERS_URL);
122
+ response.on('error', function (err) {
123
+ reject(err);
124
+ });
125
+ response.pipe((0, gunzip_maybe_1.default)()).pipe(extractor);
126
+ });
127
+ }
128
+ }
129
+ exports.defaultProviderInstaller = new DefaultProviderInstaller();
@@ -1,5 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogData = void 0;
1
4
  const MAX_LINES = 1000;
2
- export class LogData {
5
+ class LogData {
3
6
  static MAX_LINES = MAX_LINES;
4
7
  entries = [];
5
8
  constructor() { }
@@ -36,3 +39,4 @@ export class LogData {
36
39
  .join('\n');
37
40
  }
38
41
  }
42
+ exports.LogData = LogData;
@@ -1,14 +1,18 @@
1
- import { spawn, hasApp } from '@kapeta/nodejs-process';
2
- import { taskManager } from '../taskManager';
3
- export async function hasCLI() {
4
- return hasApp('kap');
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureCLI = exports.hasCLI = void 0;
4
+ const nodejs_process_1 = require("@kapeta/nodejs-process");
5
+ const taskManager_1 = require("../taskManager");
6
+ async function hasCLI() {
7
+ return (0, nodejs_process_1.hasApp)('kap');
5
8
  }
6
- export async function ensureCLI() {
9
+ exports.hasCLI = hasCLI;
10
+ async function ensureCLI() {
7
11
  if (await hasCLI()) {
8
12
  return null;
9
13
  }
10
- return taskManager.add(`cli:install`, () => {
11
- const process = spawn('npm', ['install', '-g', '@kapeta/kap'], {
14
+ return taskManager_1.taskManager.add(`cli:install`, () => {
15
+ const process = (0, nodejs_process_1.spawn)('npm', ['install', '-g', '@kapeta/kap'], {
12
16
  shell: true,
13
17
  });
14
18
  return process.wait();
@@ -16,3 +20,4 @@ export async function ensureCLI() {
16
20
  name: `Installing Kapeta CLI`,
17
21
  });
18
22
  }
23
+ exports.ensureCLI = ensureCLI;
@@ -1,3 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pathTemplateParser = exports.PathTemplate = void 0;
1
4
  const TYPE_VARIABLE = 'variable';
2
5
  const TYPE_PATH = 'path';
3
6
  /**
@@ -11,7 +14,7 @@ const TYPE_PATH = 'path';
11
14
  * /foo/{bar:[0-9]+}/baz
12
15
  *
13
16
  */
14
- export class PathTemplate {
17
+ class PathTemplate {
15
18
  _path;
16
19
  _parts = [];
17
20
  constructor(pathTemplate) {
@@ -108,9 +111,11 @@ export class PathTemplate {
108
111
  return 'tmpl: ' + this.path;
109
112
  }
110
113
  }
114
+ exports.PathTemplate = PathTemplate;
111
115
  /**
112
116
  * Parses a path into a RESTPath
113
117
  */
114
- export function pathTemplateParser(path) {
118
+ function pathTemplateParser(path) {
115
119
  return new PathTemplate(path);
116
120
  }
121
+ exports.pathTemplateParser = pathTemplateParser;
@@ -1,40 +1,53 @@
1
- import FS from 'node:fs';
2
- import YAML from 'yaml';
3
- import { parseKapetaUri } from '@kapeta/nodejs-utils';
4
- import md5 from 'md5';
5
- export function getBlockInstanceContainerName(systemId, instanceId) {
6
- return `kapeta-block-instance-${md5(systemId + instanceId)}`;
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.getBindHost = exports.isLinux = exports.isMac = exports.isWindows = exports.readYML = exports.normalizeKapetaUri = exports.getBlockInstanceContainerName = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const yaml_1 = __importDefault(require("yaml"));
9
+ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
10
+ const md5_1 = __importDefault(require("md5"));
11
+ function getBlockInstanceContainerName(systemId, instanceId) {
12
+ return `kapeta-block-instance-${(0, md5_1.default)(systemId + instanceId)}`;
7
13
  }
8
- export function normalizeKapetaUri(uri) {
14
+ exports.getBlockInstanceContainerName = getBlockInstanceContainerName;
15
+ function normalizeKapetaUri(uri) {
9
16
  if (!uri) {
10
17
  return '';
11
18
  }
12
- const uriObj = parseKapetaUri(uri);
19
+ const uriObj = (0, nodejs_utils_1.parseKapetaUri)(uri);
13
20
  if (!uriObj.version) {
14
- return `kapeta://${parseKapetaUri(uri).fullName}`;
21
+ return `kapeta://${(0, nodejs_utils_1.parseKapetaUri)(uri).fullName}`;
15
22
  }
16
- return `kapeta://${parseKapetaUri(uri).id}`;
23
+ return `kapeta://${(0, nodejs_utils_1.parseKapetaUri)(uri).id}`;
17
24
  }
18
- export function readYML(path) {
19
- const rawYaml = FS.readFileSync(path);
25
+ exports.normalizeKapetaUri = normalizeKapetaUri;
26
+ function readYML(path) {
27
+ const rawYaml = node_fs_1.default.readFileSync(path);
20
28
  try {
21
- return YAML.parse(rawYaml.toString());
29
+ return yaml_1.default.parse(rawYaml.toString());
22
30
  }
23
31
  catch (err) {
24
32
  throw new Error(`Failed to parse plan YAML: ${err}`);
25
33
  }
26
34
  }
27
- export function isWindows() {
35
+ exports.readYML = readYML;
36
+ function isWindows() {
28
37
  return 'win32' === process.platform;
29
38
  }
30
- export function isMac() {
39
+ exports.isWindows = isWindows;
40
+ function isMac() {
31
41
  return 'darwin' === process.platform;
32
42
  }
33
- export function isLinux() {
43
+ exports.isMac = isMac;
44
+ function isLinux() {
34
45
  return !isWindows() && !isMac();
35
46
  }
36
- export function getBindHost(preferredHost = '127.0.0.1') {
47
+ exports.isLinux = isLinux;
48
+ function getBindHost(preferredHost = '127.0.0.1') {
37
49
  // On Linux we need to bind to 0.0.0.0 to be able to connect to it from docker containers.
38
50
  // TODO: This might pose a security risk - so we should authenticate all requests using a shared secret/nonce that we pass around.
39
51
  return isLinux() ? '0.0.0.0' : preferredHost;
40
52
  }
53
+ exports.getBindHost = getBindHost;
package/dist/esm/start.js CHANGED
@@ -1,5 +1,10 @@
1
- import localClusterService from './index';
2
- localClusterService
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
+ const index_1 = __importDefault(require("./index"));
7
+ index_1.default
3
8
  .start()
4
9
  .then(({ host, port }) => console.log('Listening on port %s:%s', host, port))
5
10
  .catch((e) => {
package/index.ts CHANGED
@@ -22,6 +22,8 @@ import { getBindHost } from './src/utils/utils';
22
22
  import request from 'request';
23
23
  import { repositoryManager } from './src/repositoryManager';
24
24
  import { ensureCLI } from './src/utils/commandLineUtils';
25
+ import { defaultProviderInstaller } from './src/utils/DefaultProviderInstaller';
26
+ import { authManager } from './src/authManager';
25
27
 
26
28
  export type LocalClusterService = HTTP.Server & { host?: string; port?: number };
27
29
 
@@ -122,6 +124,8 @@ export default {
122
124
  );
123
125
  }
124
126
 
127
+ await defaultProviderInstaller.checkForDefault();
128
+
125
129
  const clusterPort = storageService.get('cluster', 'port');
126
130
  if (clusterPort) {
127
131
  clusterService.setClusterServicePort(clusterPort);
@@ -144,6 +148,7 @@ export default {
144
148
  }
145
149
 
146
150
  await clusterService.init();
151
+ await authManager.listenForChanges();
147
152
 
148
153
  currentServer = createServer();
149
154
 
@@ -174,7 +179,7 @@ export default {
174
179
 
175
180
  const bindHost = getBindHost(host);
176
181
 
177
- currentServer.listen(port, bindHost, () => {
182
+ currentServer.listen(port, bindHost, async () => {
178
183
  try {
179
184
  ensureCLI().catch((e: any) => console.error('Failed to install CLI.', e));
180
185
  } catch (e: any) {
@@ -183,7 +188,7 @@ export default {
183
188
 
184
189
  try {
185
190
  // Start installation process for all default providers
186
- repositoryManager.ensureDefaultProviders();
191
+ await repositoryManager.ensureDefaultProviders();
187
192
  } catch (e: any) {
188
193
  console.error('Failed to install default providers.', e);
189
194
  }