@kapeta/local-cluster-service 0.19.3 → 0.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/cjs/src/definitionsManager.js +10 -2
- package/dist/cjs/src/proxy/types/rest.d.ts +2 -0
- package/dist/cjs/src/proxy/types/rest.js +2 -1
- package/dist/cjs/src/repositoryManager.js +5 -2
- package/dist/cjs/src/utils/pathTemplateParser.js +13 -3
- package/dist/cjs/test/proxy/types/rest.test.d.ts +1 -0
- package/dist/cjs/test/proxy/types/rest.test.js +45 -0
- package/dist/cjs/test/utils/pathTemplateParser.test.d.ts +1 -0
- package/dist/cjs/test/utils/pathTemplateParser.test.js +23 -0
- package/dist/esm/src/definitionsManager.js +10 -2
- package/dist/esm/src/proxy/types/rest.d.ts +2 -0
- package/dist/esm/src/proxy/types/rest.js +2 -1
- package/dist/esm/src/repositoryManager.js +5 -2
- package/dist/esm/src/utils/pathTemplateParser.js +13 -3
- package/dist/esm/test/proxy/types/rest.test.d.ts +1 -0
- package/dist/esm/test/proxy/types/rest.test.js +45 -0
- package/dist/esm/test/utils/pathTemplateParser.test.d.ts +1 -0
- package/dist/esm/test/utils/pathTemplateParser.test.js +23 -0
- package/jest.config.js +8 -0
- package/package.json +5 -2
- package/src/definitionsManager.ts +12 -4
- package/src/proxy/types/rest.ts +1 -1
- package/src/repositoryManager.ts +5 -2
- package/src/utils/pathTemplateParser.ts +17 -3
- package/test/proxy/types/rest.test.ts +49 -0
- package/test/utils/pathTemplateParser.test.ts +24 -0
- package/tsconfig.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.19.5](https://github.com/kapetacom/local-cluster-service/compare/v0.19.4...v0.19.5) (2023-09-07)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Handle query and hash in path matching ([#70](https://github.com/kapetacom/local-cluster-service/issues/70)) ([e743cf8](https://github.com/kapetacom/local-cluster-service/commit/e743cf80c6754f43c948fd25967f04808429a784))
|
7
|
+
|
8
|
+
## [0.19.4](https://github.com/kapetacom/local-cluster-service/compare/v0.19.3...v0.19.4) (2023-09-05)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Do not rename local sample if we already have ([095737e](https://github.com/kapetacom/local-cluster-service/commit/095737e7cfd94ec1e5dc8efcb178fbf88f67d783))
|
14
|
+
|
1
15
|
## [0.19.3](https://github.com/kapetacom/local-cluster-service/compare/v0.19.2...v0.19.3) (2023-09-05)
|
2
16
|
|
3
17
|
|
@@ -15,9 +15,12 @@ const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
|
|
15
15
|
const progressListener_1 = require("./progressListener");
|
16
16
|
const path_1 = __importDefault(require("path"));
|
17
17
|
exports.SAMPLE_PLAN_NAME = 'kapeta/sample-nodejs-plan';
|
18
|
-
function
|
18
|
+
function getRenamed(definition, targetHandle) {
|
19
19
|
const originalUri = (0, nodejs_utils_1.parseKapetaUri)(definition.definition.metadata.name);
|
20
|
-
|
20
|
+
return `${targetHandle}/${originalUri.name}`;
|
21
|
+
}
|
22
|
+
function applyHandleChange(definition, targetHandle) {
|
23
|
+
definition.definition.metadata.name = getRenamed(definition, targetHandle);
|
21
24
|
return definition;
|
22
25
|
}
|
23
26
|
function normalizeFilters(kindFilter) {
|
@@ -50,6 +53,11 @@ class DefinitionsManager {
|
|
50
53
|
// Not logged in yet, so we can't rewrite the sample plan
|
51
54
|
return definitions;
|
52
55
|
}
|
56
|
+
const newName = getRenamed(samplePlan, profile.handle);
|
57
|
+
if (definitions.some((d) => d.definition.metadata.name === newName && d.version === 'local')) {
|
58
|
+
// We already have a local version of the sample plan
|
59
|
+
return definitions;
|
60
|
+
}
|
53
61
|
console.log('Rewriting sample plan to use handle %s', profile.handle);
|
54
62
|
applyHandleChange(samplePlan, profile.handle);
|
55
63
|
const planDef = samplePlan.definition;
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import { Response } from 'express';
|
2
2
|
import { ProxyRequestInfo } from '../../types';
|
3
3
|
import { StringBodyRequest } from '../../middleware/stringBody';
|
4
|
+
import { Resource } from '@kapeta/schemas';
|
5
|
+
export declare function getRestMethodId(restResource: Resource, httpMethod: string, httpPath: string): string | undefined;
|
4
6
|
export declare function proxyRestRequest(req: StringBodyRequest, res: Response, opts: ProxyRequestInfo): void;
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.proxyRestRequest = void 0;
|
6
|
+
exports.proxyRestRequest = exports.getRestMethodId = void 0;
|
7
7
|
const lodash_1 = __importDefault(require("lodash"));
|
8
8
|
const request_1 = __importDefault(require("request"));
|
9
9
|
const path_1 = __importDefault(require("path"));
|
@@ -24,6 +24,7 @@ function getRestMethodId(restResource, httpMethod, httpPath) {
|
|
24
24
|
return pathTemplate.matches(httpPath);
|
25
25
|
});
|
26
26
|
}
|
27
|
+
exports.getRestMethodId = getRestMethodId;
|
27
28
|
/**
|
28
29
|
*
|
29
30
|
* @param req {Request}
|
@@ -26,9 +26,9 @@ const DEFAULT_PROVIDERS = [
|
|
26
26
|
'kapeta/resource-type-web-fragment',
|
27
27
|
'kapeta/resource-type-mongodb',
|
28
28
|
'kapeta/resource-type-postgresql',
|
29
|
+
'kapeta/resource-type-smtp-client',
|
29
30
|
'kapeta/language-target-react-ts',
|
30
31
|
'kapeta/language-target-nodejs',
|
31
|
-
'kapeta/language-target-java-spring-boot',
|
32
32
|
];
|
33
33
|
class RepositoryManager extends node_events_1.EventEmitter {
|
34
34
|
_registryService;
|
@@ -84,7 +84,10 @@ class RepositoryManager extends node_events_1.EventEmitter {
|
|
84
84
|
throw e;
|
85
85
|
}
|
86
86
|
cacheManager_1.cacheManager.flush();
|
87
|
-
|
87
|
+
if (await definitionsManager_1.definitionsManager.exists(ref)) {
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
throw new Error(`Failed to install asset: ${ref}`);
|
88
91
|
};
|
89
92
|
};
|
90
93
|
const tasks = [];
|
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pathTemplateParser = exports.PathTemplate = void 0;
|
4
4
|
const TYPE_VARIABLE = 'variable';
|
5
5
|
const TYPE_PATH = 'path';
|
6
|
+
function normalizePath(path) {
|
7
|
+
if (!path.startsWith('/')) {
|
8
|
+
path = '/' + path;
|
9
|
+
}
|
10
|
+
if (path.includes('#')) {
|
11
|
+
path = path.split('#')[0];
|
12
|
+
}
|
13
|
+
if (path.includes('?')) {
|
14
|
+
path = path.split('?')[0];
|
15
|
+
}
|
16
|
+
return path;
|
17
|
+
}
|
6
18
|
/**
|
7
19
|
* A path template is a string that can be used to match a path and extract variables from it.
|
8
20
|
*
|
@@ -62,9 +74,7 @@ class PathTemplate {
|
|
62
74
|
return this.parse(path) !== null;
|
63
75
|
}
|
64
76
|
parse(path) {
|
65
|
-
|
66
|
-
path = '/' + path;
|
67
|
-
}
|
77
|
+
path = normalizePath(path);
|
68
78
|
const values = {};
|
69
79
|
for (let i = 0; i < this._parts.length; i++) {
|
70
80
|
const part = this._parts[i];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const rest_1 = require("../../../src/proxy/types/rest");
|
4
|
+
describe('getRestMethodId', () => {
|
5
|
+
it('should match @Query in url', () => {
|
6
|
+
const restResource = new TestResource();
|
7
|
+
const restMethodId = (0, rest_1.getRestMethodId)(restResource, "POST", "/names?name=Ib");
|
8
|
+
expect(restMethodId).toBeDefined();
|
9
|
+
});
|
10
|
+
});
|
11
|
+
class TestResource {
|
12
|
+
kind = "";
|
13
|
+
metadata = new TestResourceMetaData();
|
14
|
+
get spec() {
|
15
|
+
return {
|
16
|
+
methods: [
|
17
|
+
{
|
18
|
+
responseType: {
|
19
|
+
ref: "Name[]"
|
20
|
+
},
|
21
|
+
method: "GET",
|
22
|
+
path: "/names",
|
23
|
+
arguments: {}
|
24
|
+
},
|
25
|
+
{
|
26
|
+
responseType: {
|
27
|
+
ref: "Name"
|
28
|
+
},
|
29
|
+
method: "POST",
|
30
|
+
path: "/names",
|
31
|
+
arguments: {
|
32
|
+
name: {
|
33
|
+
type: "string",
|
34
|
+
transport: "QUERY"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
]
|
39
|
+
};
|
40
|
+
}
|
41
|
+
;
|
42
|
+
}
|
43
|
+
class TestResourceMetaData {
|
44
|
+
name = "";
|
45
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const pathTemplateParser_1 = require("../../src/utils/pathTemplateParser");
|
4
|
+
describe('pathTemplateParser', () => {
|
5
|
+
it('must return parameters for query parameters from parse', () => {
|
6
|
+
const template = new pathTemplateParser_1.PathTemplate('/names');
|
7
|
+
const parse = template.parse('/names?name=Ib#test');
|
8
|
+
console.log(parse);
|
9
|
+
expect(parse).toBeTruthy();
|
10
|
+
});
|
11
|
+
it('must return parameters defined in url', () => {
|
12
|
+
const template = new pathTemplateParser_1.PathTemplate('/names/{identityId}');
|
13
|
+
const parse = template.parse('/names/idn_xxyyzz');
|
14
|
+
expect(parse).toBeTruthy();
|
15
|
+
expect(parse).toMatchObject({ identityId: 'idn_xxyyzz' });
|
16
|
+
});
|
17
|
+
it('must return parameters defined in url regardless of query parameters', () => {
|
18
|
+
const template = new pathTemplateParser_1.PathTemplate('/names/{identityId}');
|
19
|
+
const parse = template.parse('/names/idn_xxyyzz?name=Ib#test');
|
20
|
+
expect(parse).toBeTruthy();
|
21
|
+
expect(parse).toMatchObject({ identityId: 'idn_xxyyzz' });
|
22
|
+
});
|
23
|
+
});
|
@@ -15,9 +15,12 @@ const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
|
|
15
15
|
const progressListener_1 = require("./progressListener");
|
16
16
|
const path_1 = __importDefault(require("path"));
|
17
17
|
exports.SAMPLE_PLAN_NAME = 'kapeta/sample-nodejs-plan';
|
18
|
-
function
|
18
|
+
function getRenamed(definition, targetHandle) {
|
19
19
|
const originalUri = (0, nodejs_utils_1.parseKapetaUri)(definition.definition.metadata.name);
|
20
|
-
|
20
|
+
return `${targetHandle}/${originalUri.name}`;
|
21
|
+
}
|
22
|
+
function applyHandleChange(definition, targetHandle) {
|
23
|
+
definition.definition.metadata.name = getRenamed(definition, targetHandle);
|
21
24
|
return definition;
|
22
25
|
}
|
23
26
|
function normalizeFilters(kindFilter) {
|
@@ -50,6 +53,11 @@ class DefinitionsManager {
|
|
50
53
|
// Not logged in yet, so we can't rewrite the sample plan
|
51
54
|
return definitions;
|
52
55
|
}
|
56
|
+
const newName = getRenamed(samplePlan, profile.handle);
|
57
|
+
if (definitions.some((d) => d.definition.metadata.name === newName && d.version === 'local')) {
|
58
|
+
// We already have a local version of the sample plan
|
59
|
+
return definitions;
|
60
|
+
}
|
53
61
|
console.log('Rewriting sample plan to use handle %s', profile.handle);
|
54
62
|
applyHandleChange(samplePlan, profile.handle);
|
55
63
|
const planDef = samplePlan.definition;
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import { Response } from 'express';
|
2
2
|
import { ProxyRequestInfo } from '../../types';
|
3
3
|
import { StringBodyRequest } from '../../middleware/stringBody';
|
4
|
+
import { Resource } from '@kapeta/schemas';
|
5
|
+
export declare function getRestMethodId(restResource: Resource, httpMethod: string, httpPath: string): string | undefined;
|
4
6
|
export declare function proxyRestRequest(req: StringBodyRequest, res: Response, opts: ProxyRequestInfo): void;
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.proxyRestRequest = void 0;
|
6
|
+
exports.proxyRestRequest = exports.getRestMethodId = void 0;
|
7
7
|
const lodash_1 = __importDefault(require("lodash"));
|
8
8
|
const request_1 = __importDefault(require("request"));
|
9
9
|
const path_1 = __importDefault(require("path"));
|
@@ -24,6 +24,7 @@ function getRestMethodId(restResource, httpMethod, httpPath) {
|
|
24
24
|
return pathTemplate.matches(httpPath);
|
25
25
|
});
|
26
26
|
}
|
27
|
+
exports.getRestMethodId = getRestMethodId;
|
27
28
|
/**
|
28
29
|
*
|
29
30
|
* @param req {Request}
|
@@ -26,9 +26,9 @@ const DEFAULT_PROVIDERS = [
|
|
26
26
|
'kapeta/resource-type-web-fragment',
|
27
27
|
'kapeta/resource-type-mongodb',
|
28
28
|
'kapeta/resource-type-postgresql',
|
29
|
+
'kapeta/resource-type-smtp-client',
|
29
30
|
'kapeta/language-target-react-ts',
|
30
31
|
'kapeta/language-target-nodejs',
|
31
|
-
'kapeta/language-target-java-spring-boot',
|
32
32
|
];
|
33
33
|
class RepositoryManager extends node_events_1.EventEmitter {
|
34
34
|
_registryService;
|
@@ -84,7 +84,10 @@ class RepositoryManager extends node_events_1.EventEmitter {
|
|
84
84
|
throw e;
|
85
85
|
}
|
86
86
|
cacheManager_1.cacheManager.flush();
|
87
|
-
|
87
|
+
if (await definitionsManager_1.definitionsManager.exists(ref)) {
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
throw new Error(`Failed to install asset: ${ref}`);
|
88
91
|
};
|
89
92
|
};
|
90
93
|
const tasks = [];
|
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.pathTemplateParser = exports.PathTemplate = void 0;
|
4
4
|
const TYPE_VARIABLE = 'variable';
|
5
5
|
const TYPE_PATH = 'path';
|
6
|
+
function normalizePath(path) {
|
7
|
+
if (!path.startsWith('/')) {
|
8
|
+
path = '/' + path;
|
9
|
+
}
|
10
|
+
if (path.includes('#')) {
|
11
|
+
path = path.split('#')[0];
|
12
|
+
}
|
13
|
+
if (path.includes('?')) {
|
14
|
+
path = path.split('?')[0];
|
15
|
+
}
|
16
|
+
return path;
|
17
|
+
}
|
6
18
|
/**
|
7
19
|
* A path template is a string that can be used to match a path and extract variables from it.
|
8
20
|
*
|
@@ -62,9 +74,7 @@ class PathTemplate {
|
|
62
74
|
return this.parse(path) !== null;
|
63
75
|
}
|
64
76
|
parse(path) {
|
65
|
-
|
66
|
-
path = '/' + path;
|
67
|
-
}
|
77
|
+
path = normalizePath(path);
|
68
78
|
const values = {};
|
69
79
|
for (let i = 0; i < this._parts.length; i++) {
|
70
80
|
const part = this._parts[i];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const rest_1 = require("../../../src/proxy/types/rest");
|
4
|
+
describe('getRestMethodId', () => {
|
5
|
+
it('should match @Query in url', () => {
|
6
|
+
const restResource = new TestResource();
|
7
|
+
const restMethodId = (0, rest_1.getRestMethodId)(restResource, "POST", "/names?name=Ib");
|
8
|
+
expect(restMethodId).toBeDefined();
|
9
|
+
});
|
10
|
+
});
|
11
|
+
class TestResource {
|
12
|
+
kind = "";
|
13
|
+
metadata = new TestResourceMetaData();
|
14
|
+
get spec() {
|
15
|
+
return {
|
16
|
+
methods: [
|
17
|
+
{
|
18
|
+
responseType: {
|
19
|
+
ref: "Name[]"
|
20
|
+
},
|
21
|
+
method: "GET",
|
22
|
+
path: "/names",
|
23
|
+
arguments: {}
|
24
|
+
},
|
25
|
+
{
|
26
|
+
responseType: {
|
27
|
+
ref: "Name"
|
28
|
+
},
|
29
|
+
method: "POST",
|
30
|
+
path: "/names",
|
31
|
+
arguments: {
|
32
|
+
name: {
|
33
|
+
type: "string",
|
34
|
+
transport: "QUERY"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
]
|
39
|
+
};
|
40
|
+
}
|
41
|
+
;
|
42
|
+
}
|
43
|
+
class TestResourceMetaData {
|
44
|
+
name = "";
|
45
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const pathTemplateParser_1 = require("../../src/utils/pathTemplateParser");
|
4
|
+
describe('pathTemplateParser', () => {
|
5
|
+
it('must return parameters for query parameters from parse', () => {
|
6
|
+
const template = new pathTemplateParser_1.PathTemplate('/names');
|
7
|
+
const parse = template.parse('/names?name=Ib#test');
|
8
|
+
console.log(parse);
|
9
|
+
expect(parse).toBeTruthy();
|
10
|
+
});
|
11
|
+
it('must return parameters defined in url', () => {
|
12
|
+
const template = new pathTemplateParser_1.PathTemplate('/names/{identityId}');
|
13
|
+
const parse = template.parse('/names/idn_xxyyzz');
|
14
|
+
expect(parse).toBeTruthy();
|
15
|
+
expect(parse).toMatchObject({ identityId: 'idn_xxyyzz' });
|
16
|
+
});
|
17
|
+
it('must return parameters defined in url regardless of query parameters', () => {
|
18
|
+
const template = new pathTemplateParser_1.PathTemplate('/names/{identityId}');
|
19
|
+
const parse = template.parse('/names/idn_xxyyzz?name=Ib#test');
|
20
|
+
expect(parse).toBeTruthy();
|
21
|
+
expect(parse).toMatchObject({ identityId: 'idn_xxyyzz' });
|
22
|
+
});
|
23
|
+
});
|
package/jest.config.js
ADDED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@kapeta/local-cluster-service",
|
3
|
-
"version": "0.19.
|
3
|
+
"version": "0.19.5",
|
4
4
|
"description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
|
5
5
|
"type": "commonjs",
|
6
6
|
"exports": {
|
@@ -32,7 +32,7 @@
|
|
32
32
|
"scripts": {
|
33
33
|
"start": "node ./dist/cjs/start.js",
|
34
34
|
"dev": "nodemon -e js,ts,json ./start.ts",
|
35
|
-
"test": "
|
35
|
+
"test": "jest",
|
36
36
|
"clean": "rm -rf ./dist",
|
37
37
|
"build:esm": "tsc --module nodenext --moduleResolution nodenext --outDir ./dist/esm && echo '{\"type\":\"module\"}' > ./dist/esm/package.json",
|
38
38
|
"build:cjs": "tsc --outDir ./dist/cjs && echo '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
|
@@ -80,6 +80,7 @@
|
|
80
80
|
"@types/fs-extra": "^11.0.1",
|
81
81
|
"@types/glob": "^8.1.0",
|
82
82
|
"@types/gunzip-maybe": "^1.4.0",
|
83
|
+
"@types/jest": "^29.5.4",
|
83
84
|
"@types/lodash": "^4.14.195",
|
84
85
|
"@types/md5": "^2.3.2",
|
85
86
|
"@types/node": "^20.5.8",
|
@@ -88,8 +89,10 @@
|
|
88
89
|
"@types/tar-stream": "^2.2.2",
|
89
90
|
"eslint": "^8.42.0",
|
90
91
|
"eslint-config-prettier": "^8.8.0",
|
92
|
+
"jest": "^29.6.4",
|
91
93
|
"nodemon": "^2.0.2",
|
92
94
|
"prettier": "^2.8.8",
|
95
|
+
"ts-jest": "^29.1.1",
|
93
96
|
"ts-node": "^10.9.1"
|
94
97
|
},
|
95
98
|
"prettier": "@kapeta/prettier-config",
|
@@ -12,9 +12,12 @@ import Path from 'path';
|
|
12
12
|
|
13
13
|
export const SAMPLE_PLAN_NAME = 'kapeta/sample-nodejs-plan';
|
14
14
|
|
15
|
-
function
|
15
|
+
function getRenamed(definition: DefinitionInfo, targetHandle: string) {
|
16
16
|
const originalUri = parseKapetaUri(definition.definition.metadata.name);
|
17
|
-
|
17
|
+
return `${targetHandle}/${originalUri.name}`;
|
18
|
+
}
|
19
|
+
function applyHandleChange(definition: DefinitionInfo, targetHandle: string) {
|
20
|
+
definition.definition.metadata.name = getRenamed(definition, targetHandle);
|
18
21
|
return definition;
|
19
22
|
}
|
20
23
|
|
@@ -55,10 +58,15 @@ class DefinitionsManager {
|
|
55
58
|
return definitions;
|
56
59
|
}
|
57
60
|
|
58
|
-
|
61
|
+
const newName = getRenamed(samplePlan, profile.handle);
|
59
62
|
|
60
|
-
|
63
|
+
if (definitions.some((d) => d.definition.metadata.name === newName && d.version === 'local')) {
|
64
|
+
// We already have a local version of the sample plan
|
65
|
+
return definitions;
|
66
|
+
}
|
61
67
|
|
68
|
+
console.log('Rewriting sample plan to use handle %s', profile.handle);
|
69
|
+
applyHandleChange(samplePlan, profile.handle);
|
62
70
|
const planDef = samplePlan.definition as Plan;
|
63
71
|
|
64
72
|
const blockRefs = new Set<string>();
|
package/src/proxy/types/rest.ts
CHANGED
@@ -10,7 +10,7 @@ import { ProxyRequestInfo, SimpleRequest, StringMap } from '../../types';
|
|
10
10
|
import { StringBodyRequest } from '../../middleware/stringBody';
|
11
11
|
import { Resource } from '@kapeta/schemas';
|
12
12
|
|
13
|
-
function getRestMethodId(restResource: Resource, httpMethod: string, httpPath: string) {
|
13
|
+
export function getRestMethodId(restResource: Resource, httpMethod: string, httpPath: string) {
|
14
14
|
return _.findKey(restResource.spec.methods, (method) => {
|
15
15
|
let methodType = method.method ? method.method.toUpperCase() : 'GET';
|
16
16
|
|
package/src/repositoryManager.ts
CHANGED
@@ -24,9 +24,9 @@ const DEFAULT_PROVIDERS = [
|
|
24
24
|
'kapeta/resource-type-web-fragment',
|
25
25
|
'kapeta/resource-type-mongodb',
|
26
26
|
'kapeta/resource-type-postgresql',
|
27
|
+
'kapeta/resource-type-smtp-client',
|
27
28
|
'kapeta/language-target-react-ts',
|
28
29
|
'kapeta/language-target-nodejs',
|
29
|
-
'kapeta/language-target-java-spring-boot',
|
30
30
|
];
|
31
31
|
|
32
32
|
class RepositoryManager extends EventEmitter {
|
@@ -90,7 +90,10 @@ class RepositoryManager extends EventEmitter {
|
|
90
90
|
throw e;
|
91
91
|
}
|
92
92
|
cacheManager.flush();
|
93
|
-
|
93
|
+
if (await definitionsManager.exists(ref)) {
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
throw new Error(`Failed to install asset: ${ref}`);
|
94
97
|
};
|
95
98
|
};
|
96
99
|
|
@@ -3,6 +3,22 @@ import { StringMap } from '../types';
|
|
3
3
|
const TYPE_VARIABLE = 'variable';
|
4
4
|
const TYPE_PATH = 'path';
|
5
5
|
|
6
|
+
function normalizePath(path: string) {
|
7
|
+
if (!path.startsWith('/')) {
|
8
|
+
path = '/' + path;
|
9
|
+
}
|
10
|
+
|
11
|
+
if (path.includes('#')) {
|
12
|
+
path = path.split('#')[0];
|
13
|
+
}
|
14
|
+
|
15
|
+
if (path.includes('?')) {
|
16
|
+
path = path.split('?')[0];
|
17
|
+
}
|
18
|
+
|
19
|
+
return path;
|
20
|
+
}
|
21
|
+
|
6
22
|
/**
|
7
23
|
* A path template is a string that can be used to match a path and extract variables from it.
|
8
24
|
*
|
@@ -71,9 +87,7 @@ export class PathTemplate {
|
|
71
87
|
}
|
72
88
|
|
73
89
|
parse(path: string) {
|
74
|
-
|
75
|
-
path = '/' + path;
|
76
|
-
}
|
90
|
+
path = normalizePath(path);
|
77
91
|
|
78
92
|
const values: StringMap = {};
|
79
93
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import {getRestMethodId} from "../../../src/proxy/types/rest";
|
2
|
+
import {Resource, ResourceMetadata} from '@kapeta/schemas';
|
3
|
+
|
4
|
+
describe('getRestMethodId', () => {
|
5
|
+
it('should match @Query in url', () => {
|
6
|
+
const restResource = new TestResource();
|
7
|
+
|
8
|
+
const restMethodId = getRestMethodId(restResource, "POST", "/names?name=Ib");
|
9
|
+
expect(restMethodId).toBeDefined();
|
10
|
+
})
|
11
|
+
});
|
12
|
+
|
13
|
+
class TestResource implements Resource {
|
14
|
+
kind = "";
|
15
|
+
metadata = new TestResourceMetaData();
|
16
|
+
|
17
|
+
get spec(): { [p: string]: any } {
|
18
|
+
return {
|
19
|
+
methods: [
|
20
|
+
{
|
21
|
+
responseType: {
|
22
|
+
ref: "Name[]"
|
23
|
+
},
|
24
|
+
method: "GET",
|
25
|
+
path: "/names",
|
26
|
+
arguments: {}
|
27
|
+
},
|
28
|
+
{
|
29
|
+
responseType: {
|
30
|
+
ref: "Name"
|
31
|
+
},
|
32
|
+
method: "POST",
|
33
|
+
path: "/names",
|
34
|
+
arguments: {
|
35
|
+
name: {
|
36
|
+
type: "string",
|
37
|
+
transport: "QUERY"
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
43
|
+
};
|
44
|
+
}
|
45
|
+
|
46
|
+
class TestResourceMetaData implements ResourceMetadata {
|
47
|
+
[property: string]: any;
|
48
|
+
name: string = "";
|
49
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { PathTemplate } from '../../src/utils/pathTemplateParser';
|
2
|
+
|
3
|
+
describe('pathTemplateParser', () => {
|
4
|
+
it('must return parameters for query parameters from parse', () => {
|
5
|
+
const template = new PathTemplate('/names');
|
6
|
+
const parse = template.parse('/names?name=Ib#test');
|
7
|
+
console.log(parse);
|
8
|
+
expect(parse).toBeTruthy();
|
9
|
+
});
|
10
|
+
|
11
|
+
it('must return parameters defined in url', () => {
|
12
|
+
const template = new PathTemplate('/names/{identityId}');
|
13
|
+
const parse = template.parse('/names/idn_xxyyzz');
|
14
|
+
expect(parse).toBeTruthy();
|
15
|
+
expect(parse).toMatchObject({ identityId: 'idn_xxyyzz' });
|
16
|
+
});
|
17
|
+
|
18
|
+
it('must return parameters defined in url regardless of query parameters', () => {
|
19
|
+
const template = new PathTemplate('/names/{identityId}');
|
20
|
+
const parse = template.parse('/names/idn_xxyyzz?name=Ib#test');
|
21
|
+
expect(parse).toBeTruthy();
|
22
|
+
expect(parse).toMatchObject({ identityId: 'idn_xxyyzz' });
|
23
|
+
});
|
24
|
+
});
|
package/tsconfig.json
CHANGED