@devkong/cli-nx 0.0.67-alpha.19 → 0.0.67-alpha.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devkong/cli-nx",
3
- "version": "0.0.67-alpha.19",
3
+ "version": "0.0.67-alpha.20",
4
4
  "type": "commonjs",
5
5
  "main": "./src/index.js",
6
6
  "typings": "./src/index.d.ts",
@@ -0,0 +1,9 @@
1
+ from input_data import MySecret
2
+ from kong.sdk.kong_frontend import KongFrontend, KongFrontendBuilder
3
+
4
+ frontend: KongFrontend = (
5
+ KongFrontendBuilder()
6
+ .with_secret_types("primary", {"my-secret": MySecret})
7
+ .with_form()
8
+ .build()
9
+ )
@@ -0,0 +1,47 @@
1
+ from typing import Optional
2
+
3
+ from kong.sdk.kong_function_request import KongFunctionRequest
4
+ from pydantic import BaseModel, Field
5
+
6
+
7
+ class MySecret(BaseModel):
8
+ my_key: str = Field(
9
+ examples=["example-0123456789"],
10
+ description="An example of secret field",
11
+ )
12
+
13
+
14
+ class OperationData(BaseModel):
15
+ a: int = Field(
16
+ examples=[1],
17
+ description="An integer number",
18
+ )
19
+
20
+ b: int = Field(
21
+ examples=[2],
22
+ description="An integer number",
23
+ )
24
+
25
+
26
+ class InputData(BaseModel):
27
+ request: KongFunctionRequest
28
+
29
+ sum: Optional[OperationData] = Field(
30
+ default=None,
31
+ description="Operands for the 'sum' operation",
32
+ )
33
+
34
+ sub: Optional[OperationData] = Field(
35
+ default=None,
36
+ description="Operands for the 'sub' operation",
37
+ )
38
+
39
+ multiply: Optional[OperationData] = Field(
40
+ default=None,
41
+ description="Operands for the 'multiply' operation",
42
+ )
43
+
44
+ divide: Optional[OperationData] = Field(
45
+ default=None,
46
+ description="Operands for the 'divide' operation",
47
+ )
@@ -0,0 +1,51 @@
1
+ import sys
2
+
3
+ from frontend import frontend
4
+ from input_data import InputData, OperationData
5
+ from kong.sdk.app import App
6
+ from kong.sdk.kong_function import KongFunction
7
+ from kong.sdk.kong_function_context import KongFunctionContext
8
+ from output_data import OutputData
9
+
10
+
11
+ class Main(KongFunction):
12
+ async def handle(self, data: InputData, context: KongFunctionContext) -> OutputData:
13
+ operation = data.request.operation
14
+ operands = getattr(data, operation, None)
15
+ if not isinstance(operands, OperationData):
16
+ raise ValueError(f"Missing or unsupported operation '{operation}'")
17
+
18
+ if operation == "sum":
19
+ result = operands.a + operands.b
20
+ elif operation == "sub":
21
+ result = operands.a - operands.b
22
+ elif operation == "multiply":
23
+ result = operands.a * operands.b
24
+ elif operation == "divide":
25
+ if operands.b == 0:
26
+ raise ValueError("Cannot divide by zero")
27
+ result = operands.a // operands.b
28
+ else:
29
+ raise ValueError(f"Unsupported operation '{operation}'")
30
+
31
+ comment = f"{operation} result is {result}"
32
+
33
+ secret = context.secret.find("primary")
34
+ if secret is not None:
35
+ comment += " (authenticated)"
36
+
37
+ return OutputData(
38
+ result=result,
39
+ comment=comment,
40
+ )
41
+
42
+
43
+ app = App(
44
+ InputData,
45
+ OutputData,
46
+ Main,
47
+ frontend,
48
+ )
49
+
50
+ if __name__ == "__main__":
51
+ app.run(sys.argv)
@@ -0,0 +1,46 @@
1
+ import json
2
+
3
+ from frontend import frontend
4
+ from input_data import InputData, OperationData
5
+ from kong.sdk.conftest import ExtensionFixture, extension_test_context
6
+ from kong.sdk.kong_function_request import KongFunctionRequest
7
+ from main import Main
8
+
9
+
10
+ async def test_should_add_operands_when_operation_is_sum(
11
+ create_extension: ExtensionFixture,
12
+ ):
13
+ extension = create_extension(Main, InputData)
14
+
15
+ input_data = InputData(
16
+ request=KongFunctionRequest(operation="sum"),
17
+ sum=OperationData(a=1, b=2),
18
+ )
19
+
20
+ output = await extension.handle(input_data, extension_test_context(frontend))
21
+ assert output.result == 3
22
+
23
+
24
+ async def test_should_note_authentication_when_secret_is_provided(
25
+ create_extension: ExtensionFixture,
26
+ ):
27
+ extension = create_extension(Main, InputData)
28
+
29
+ input_data = InputData(
30
+ request=KongFunctionRequest(operation="sum"),
31
+ sum=OperationData(a=1, b=2),
32
+ )
33
+
34
+ # Secrets arrive as a `{"type", "data"}` JSON envelope keyed by purpose, exactly
35
+ # as the executor materializes them at runtime.
36
+ secrets = {
37
+ "primary": json.dumps(
38
+ {"type": "my-secret", "data": {"my_key": "example-0123456789"}}
39
+ )
40
+ }
41
+
42
+ context = extension_test_context(frontend, secrets)
43
+ output = await extension.handle(input_data, context)
44
+
45
+ assert output.result == 3
46
+ assert output.comment == "sum result is 3 (authenticated)"
@@ -0,0 +1,16 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class OutputData(BaseModel):
7
+ result: int = Field(
8
+ examples=[3],
9
+ description="Result of applying the operation to a and b",
10
+ )
11
+
12
+ comment: Optional[str] = Field(
13
+ default=None,
14
+ examples=["sum result is 3"],
15
+ description="A string field",
16
+ )
@@ -6,6 +6,7 @@ const devkit_1 = require("@nx/devkit");
6
6
  const path = tslib_1.__importStar(require("path"));
7
7
  function presetGenerator(tree, options) {
8
8
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
9
+ var _a;
9
10
  const projectRoot = ".";
10
11
  const projectName = "";
11
12
  (0, devkit_1.addProjectConfiguration)(tree, projectName, {
@@ -13,7 +14,14 @@ function presetGenerator(tree, options) {
13
14
  projectType: "application",
14
15
  });
15
16
  options.os = process.platform;
17
+ options.variant = (_a = options.variant) !== null && _a !== void 0 ? _a : "basic";
16
18
  (0, devkit_1.generateFiles)(tree, path.join(__dirname, `files/${options.platform}`), "", options);
19
+ // The python preset ships a "basic" (single sum) and an "advanced" (multi-operation
20
+ // + secret example) template. The advanced sources are layered on top of the shared
21
+ // base, overwriting the basic src/*.py files.
22
+ if (options.platform === "python" && options.variant === "advanced") {
23
+ (0, devkit_1.generateFiles)(tree, path.join(__dirname, "files/python-advanced"), "", options);
24
+ }
17
25
  yield (0, devkit_1.formatFiles)(tree);
18
26
  try {
19
27
  const gradlewPath = (0, devkit_1.joinPathFragments)(projectRoot, "gradlew");
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/generators/preset/generator.ts"],"names":[],"mappings":";;AAUA,0CAoBC;;AA9BD,uCAMoB;AACpB,mDAA6B;AAG7B,SAAsB,eAAe,CAAC,IAAU,EAAE,OAA8B;;QAC9E,MAAM,WAAW,GAAG,GAAG,CAAC;QACxB,MAAM,WAAW,GAAG,EAAE,CAAC;QACvB,IAAA,gCAAuB,EAAC,IAAI,EAAE,WAAW,EAAE;YACzC,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,aAAa;SAC3B,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC9B,IAAA,sBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QACpF,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAA,0BAAiB,EAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC9D,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY;YAC1D,CAAC;QACH,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;CAAA;AAED,kBAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../src/generators/preset/generator.ts"],"names":[],"mappings":";;AAUA,0CA6BC;;AAvCD,uCAMoB;AACpB,mDAA6B;AAG7B,SAAsB,eAAe,CAAC,IAAU,EAAE,OAA8B;;;QAC9E,MAAM,WAAW,GAAG,GAAG,CAAC;QACxB,MAAM,WAAW,GAAG,EAAE,CAAC;QACvB,IAAA,gCAAuB,EAAC,IAAI,EAAE,WAAW,EAAE;YACzC,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,aAAa;SAC3B,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;QAC9B,OAAO,CAAC,OAAO,GAAG,MAAA,OAAO,CAAC,OAAO,mCAAI,OAAO,CAAC;QAC7C,IAAA,sBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAEpF,oFAAoF;QACpF,oFAAoF;QACpF,8CAA8C;QAC9C,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;YACpE,IAAA,sBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;QAExB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAA,0BAAiB,EAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC9D,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY;YAC1D,CAAC;QACH,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;CAAA;AAED,kBAAe,eAAe,CAAC"}
@@ -1,5 +1,11 @@
1
1
  export interface PresetGeneratorSchema {
2
2
  name: string;
3
- os: string;
3
+ // Extension id, forwarded by the CLI and rendered into kong.json.
4
+ id?: string;
5
+ // Set by the generator at runtime from `process.platform`.
6
+ os?: string;
4
7
  platform: "python" | "kotlin";
8
+ // Which starter template to scaffold. Only the python preset currently ships more
9
+ // than "basic"; "advanced" adds the multi-operation + secret example variant.
10
+ variant?: "basic" | "advanced";
5
11
  }
@@ -21,7 +21,32 @@
21
21
  "index": 1
22
22
  },
23
23
  "x-prompt": "What platform would you like to use?"
24
+ },
25
+ "variant": {
26
+ "type": "string",
27
+ "description": "Which starter template to scaffold",
28
+ "enum": [
29
+ "basic",
30
+ "advanced"
31
+ ],
32
+ "default": "basic",
33
+ "x-prompt": {
34
+ "message": "Which template would you like to use?",
35
+ "type": "list",
36
+ "items": [
37
+ {
38
+ "value": "basic",
39
+ "label": "basic - a single operation"
40
+ },
41
+ {
42
+ "value": "advanced",
43
+ "label": "advanced - multiple operations with a secret example"
44
+ }
45
+ ]
46
+ }
24
47
  }
25
48
  },
26
- "required": ["name"]
27
- }
49
+ "required": [
50
+ "name"
51
+ ]
52
+ }