@uns-kit/cli 2.0.29 → 2.0.30

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/README.md CHANGED
@@ -1,39 +1,33 @@
1
1
  # @uns-kit/cli
2
2
 
3
- Command line scaffolding tool for the UNS toolkit. It bootstraps a new project with `@uns-kit/core` preconfigured and ready to extend with additional plugins.
3
+ Command line scaffolding tool for the UNS toolkit. Bootstraps new projects with `@uns-kit/core` preconfigured and ready to extend with plugins. Also provides configure and upgrade commands for existing projects.
4
4
 
5
5
  Note: Apps built with uns-kit are intended to be managed by the **UNS Datahub controller**.
6
6
 
7
7
  ## uns-kit in context
8
8
 
9
- uns-kit is a batteries-included toolkit for Unified Namespace applications. It standardizes MQTT wiring, auth, config schemas, and scaffolding so you can focus on your domain logic. The toolkit packages are:
10
-
11
9
  | Package | Description |
12
10
  | --- | --- |
13
- | [`@uns-kit/core`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-core) | Base runtime utilities (UnsProxyProcess, MQTT helpers, configuration tooling, gRPC gateway support). |
14
- | [`@uns-kit/api`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-api) | Express plugin that exposes HTTP endpoints, handles JWT/JWKS auth, and republishes API metadata to UNS. |
11
+ | [`@uns-kit/core`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-core) | Base runtime (UnsProxyProcess, MQTT helpers, config tooling, gRPC gateway). |
12
+ | [`@uns-kit/api`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-api) | Express plugin HTTP endpoints, JWT/JWKS auth, Swagger, UNS metadata. |
15
13
  | [`@uns-kit/cron`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-cron) | Cron-driven scheduler that emits UNS events on a fixed cadence. |
16
- | [`@uns-kit/temporal`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-temporal) | Temporal.io integration that wires workflows into UnsProxyProcess. |
17
- | [`@uns-kit/cli`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-cli) | Command line tool for scaffolding new UNS applications. |
14
+ | [`@uns-kit/cli`](https://github.com/uns-datahub/uns-kit/tree/main/packages/uns-cli) | CLI for scaffolding new UNS applications. |
18
15
 
19
16
  ## Prerequisites
20
17
 
21
- - Node.js 18 or newer (ES2022 runtime features)
22
- - A package manager such as `pnpm`, `npm`, or `yarn`
23
- - `git` available on PATH (required for `configure-devops`, used to initialize new projects automatically)
18
+ - Node.js 22 or newer
19
+ - `pnpm`, `npm`, or `yarn`
20
+ - `git` on PATH (used to initialise new projects and for `configure-devops`)
24
21
 
25
- ## Usage
22
+ ## Create a new project
26
23
 
27
24
  ```bash
28
25
  pnpm --package=@uns-kit/cli dlx uns-kit create my-uns-app
29
26
  # or with npx
30
27
  npx @uns-kit/cli create my-uns-app
31
- # or after installing globally
32
- npm install -g @uns-kit/cli
33
- uns-kit create my-uns-app
34
28
  ```
35
29
 
36
- The command creates a new directory, copies the starter template, and pins `@uns-kit/core` to the currently published version. After the scaffold finishes:
30
+ After scaffolding:
37
31
 
38
32
  ```bash
39
33
  cd my-uns-app
@@ -41,7 +35,7 @@ pnpm install
41
35
  pnpm run dev
42
36
  ```
43
37
 
44
- When `git` is available on your PATH the scaffold also initializes a fresh repository so you can commit immediately.
38
+ The scaffold creates a project directory from the default TypeScript template, pins `@uns-kit/core` to the current version, and initialises a git repository if `git` is available.
45
39
 
46
40
  ### Create from a service bundle
47
41
 
@@ -51,53 +45,38 @@ uns-kit create --bundle ./service.bundle.json --dest ./my-dir
51
45
  uns-kit create --bundle ./service.bundle.json --dest . --allow-existing
52
46
  ```
53
47
 
54
- Bundle-driven create uses `service.bundle.json` as the source of truth. The CLI:
55
-
56
- - scaffolds the base TypeScript app from the existing default template
57
- - copies the original bundle into the project root as `service.bundle.json`
58
- - generates `SERVICE_SPEC.md` and `AGENTS.md`
59
- - applies supported bundle features such as `vscode` and `devops`
60
-
61
- When `--bundle` is used, the default destination is `./<metadata.name>`. The TypeScript CLI only accepts bundles with `scaffold.stack = "ts"` and currently supports `scaffold.template = "default"` for this MVP. If the bundle targets Python instead, use `uns-kit-py create --bundle ...`.
48
+ Bundle-driven create uses `service.bundle.json` as the source of truth. The CLI scaffolds the base app, copies the bundle into the project root, generates `SERVICE_SPEC.md` and `AGENTS.md`, and applies supported bundle features (`vscode`, `devops`, etc.). Only bundles with `scaffold.stack = "ts"` are accepted by this CLI; use `uns-kit-py` for Python bundles.
62
49
 
63
50
  ## Commands
64
51
 
65
- - `uns-kit create <name>` – create a new UNS project in the specified directory.
66
- - `uns-kit create --bundle <path> [--dest <dir>] [--allow-existing]` – create a new TypeScript UNS project from `service.bundle.json`.
67
- - `uns-kit configure [path] [features...]` – run multiple configure templates in sequence (`--all`, `--overwrite`).
68
- - `uns-kit configure-templates [path] [templates...]` – copy any template directory (`--all`, `--overwrite`).
69
- - `uns-kit configure-devops [path]` – add Azure DevOps tooling (dependencies, script, config) to an existing project.
70
- - `uns-kit configure-vscode [path]` – copy VS Code launch/workspace files into an existing project.
71
- - `uns-kit configure-codegen [path]` – scaffold GraphQL code generation and UNS refresh scripts.
72
- - `uns-kit configure-api [path]` – copy UNS API examples and add `@uns-kit/api`.
73
- - `uns-kit configure-cron [path]` – copy UNS cron examples and add `@uns-kit/cron`.
74
- - `uns-kit configure-temporal [path]` – copy UNS Temporal examples and add `@uns-kit/temporal`.
75
- - `uns-kit configure-python [path]` – copy Python gateway client scaffolding (no npm dependency required).
76
- - `uns-kit help` – display usage information.
52
+ ### `uns-kit create <name>`
53
+ Scaffold a new project from the default TypeScript template.
77
54
 
78
- ### Configure multiple features at once
55
+ ### `uns-kit create --bundle <path> [--dest <dir>] [--allow-existing]`
56
+ Scaffold from a `service.bundle.json` descriptor.
79
57
 
80
- Chain several add-ons without running each subcommand manually:
58
+ ### `uns-kit configure [dir] [features...]`
59
+ Apply one or more feature templates to an existing project in one go.
81
60
 
82
61
  ```bash
83
- uns-kit configure --all
84
- uns-kit configure ./apps/gateway devops vscode codegen
62
+ uns-kit configure # prompts for features
63
+ uns-kit configure --all # apply all available features
64
+ uns-kit configure ./my-app api cron # add API and cron scaffolding
65
+ uns-kit configure ./my-app --overwrite # refresh existing files from latest templates
85
66
  ```
86
67
 
87
- Mix and match feature names after an optional target directory. Use `--all` to apply every available template in one shot. Add `--overwrite` to refresh files from newer template versions.
88
-
89
- ### Copy arbitrary templates
68
+ Available feature names: `devops`, `vscode`, `codegen`, `api`, `cron`, `python`, `uns-reference`.
90
69
 
91
- Need a template that is not wired into a configure feature (or added in a newer release)? Use:
70
+ ### `uns-kit configure-templates [dir] [templates...]`
71
+ Copy any template directory by name.
92
72
 
93
73
  ```bash
94
74
  uns-kit configure-templates --all
95
- uns-kit configure-templates ./apps/gateway uns-dictionary uns-measurements --overwrite
75
+ uns-kit configure-templates uns-dictionary uns-measurements --overwrite
96
76
  ```
97
77
 
98
- ### Configure Azure DevOps
99
-
100
- Run inside a scaffolded project to add the Azure DevOps pull-request tooling:
78
+ ### `uns-kit configure-devops [dir]`
79
+ Add Azure DevOps pull-request tooling. Requires a git repository.
101
80
 
102
81
  ```bash
103
82
  uns-kit configure-devops
@@ -105,70 +84,83 @@ pnpm install
105
84
  pnpm run pull-request
106
85
  ```
107
86
 
108
- The command prompts for your Azure DevOps organization/project, ensures the remote repository exists, and updates `config.json` along with the necessary dev dependencies.
109
-
110
- ### Configure VS Code workspace
111
-
112
- ```bash
113
- uns-kit configure-vscode
114
- ```
115
-
116
- Copies `.vscode/launch.json` plus a baseline workspace file into the project. Existing files are skipped unless you pass `--overwrite`.
87
+ ### `uns-kit configure-vscode [dir]`
88
+ Copy `.vscode/launch.json` and a workspace file. Skips existing files unless `--overwrite` is passed.
117
89
 
118
- ### Configure GraphQL code generation
90
+ ### `uns-kit configure-codegen [dir]`
91
+ Scaffold GraphQL code generation (`codegen.ts`, placeholder types in `src/uns/`).
119
92
 
120
93
  ```bash
121
94
  uns-kit configure-codegen
122
95
  pnpm install
123
- pnpm run codegen
124
- pnpm run refresh-uns
96
+ pnpm run generate-codegen # regenerate strongly-typed GraphQL operations
125
97
  ```
126
98
 
127
- Adds `codegen.ts`, seeds `src/uns/` placeholder types, and wires the GraphQL Code Generator / `refresh-uns` script into `package.json`. After installing the new dev dependencies you can regenerate strongly-typed operations (`pnpm run codegen`) and rebuild UNS topics/tags from your environment (`pnpm run refresh-uns`).
128
- After installing the new dev dependencies you can regenerate strongly-typed operations (`pnpm run codegen`) and rebuild UNS metadata (topics/tags/assets) from your environment (`pnpm run generate-uns-metadata`).
129
-
130
- ### Add UNS API scaffolding
99
+ ### `uns-kit configure-api [dir]`
100
+ Copy API example stubs (`src/examples/api-example.ts`) and add `@uns-kit/api`.
131
101
 
132
102
  ```bash
133
103
  uns-kit configure-api
134
104
  pnpm install
135
105
  ```
136
106
 
137
- Copies API-oriented examples (under `src/examples/`) and adds `@uns-kit/api` to your project dependencies.
138
- Use `--overwrite` to refresh the examples after updating `uns-kit`.
107
+ The example shows both GET and POST endpoint registration with JWT auth, query params, request body schemas, and event handlers. Rename and adapt `api-example.ts` to `index.ts` as your starting point.
139
108
 
140
- ### Add cron-based scaffolding
109
+ ### `uns-kit configure-cron [dir]`
110
+ Copy cron example stubs and add `@uns-kit/cron`.
141
111
 
142
112
  ```bash
143
113
  uns-kit configure-cron
144
114
  pnpm install
145
115
  ```
146
116
 
147
- Adds cron-oriented example stubs and installs `@uns-kit/cron`.
148
- Use `--overwrite` to refresh the examples after updating `uns-kit`.
117
+ ### `uns-kit configure-python [dir]`
118
+ Copy Python gRPC gateway client scaffolding (no npm dependency required).
149
119
 
150
- ### Add Temporal scaffolding
120
+ ```bash
121
+ uns-kit configure-python
122
+ ```
123
+
124
+ ### `uns-kit configure-uns-reference [dir]`
125
+ Copy UNS dictionary and measurements JSON files into the project and add the `sync-uns-schema` script to `package.json`.
151
126
 
152
127
  ```bash
153
- uns-kit configure-temporal
154
- pnpm install
128
+ uns-kit configure-uns-reference
129
+ pnpm run sync-uns-schema # pull latest schema from the controller
155
130
  ```
156
131
 
157
- Copies Temporal example placeholders and installs `@uns-kit/temporal`.
158
- Use `--overwrite` to refresh the examples after updating `uns-kit`.
132
+ ### `uns-kit upgrade [dir]`
133
+ Remove obsolete scripts from `package.json` and migrate to current conventions.
134
+
135
+ ```bash
136
+ uns-kit upgrade # upgrade current directory
137
+ uns-kit upgrade ./my-app # upgrade a specific project
138
+ ```
139
+
140
+ Removes scripts that have been superseded (`generate-uns-dictionary`, `generate-uns-measurements`, `generate-uns-reference`, `generate-uns-metadata`) and ensures `sync-uns-schema` is present.
141
+
142
+ ### `uns-kit help`
143
+ Display usage information.
159
144
 
160
- ### Add Python gateway scaffolding
145
+ ## Extend the config schema
146
+
147
+ Edit `src/config/project.config.extension.ts` inside your project and run:
161
148
 
162
149
  ```bash
163
- uns-kit configure-python
150
+ pnpm run generate-config-schema
164
151
  ```
165
152
 
166
- Copies the Python gateway client template (examples, scripts, requirements, proto) into your project so you can iterate on the gRPC gateway from Python alongside your TypeScript project.
167
- Use `--overwrite` to refresh the examples after updating `uns-kit`.
153
+ This regenerates `config.schema.json` and `src/config/app-config.ts` so editors and runtime types stay in sync with your extensions.
154
+
155
+ ## Sync the UNS schema
168
156
 
169
- ### Extend the Config Schema
157
+ After scaffolding (or at any time) pull the latest UNS dictionary and measurements from the controller:
158
+
159
+ ```bash
160
+ pnpm run sync-uns-schema
161
+ ```
170
162
 
171
- Edit `src/config/project.config.extension.ts` inside your generated project and run `pnpm run generate-config-schema`. This regenerates `config.schema.json` and `src/config/app-config.ts`, augmenting `@uns-kit/core`'s `AppConfig` so editors and runtime types stay in sync. If completions lag, reload the TypeScript server in your editor.
163
+ The controller URL is read from `config.json` (`uns.rest`) automatically. You will be prompted for the bearer token if `UNS_CONTROLLER_TOKEN` is not set.
172
164
 
173
165
  ## License
174
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uns-kit/cli",
3
- "version": "2.0.29",
3
+ "version": "2.0.30",
4
4
  "description": "Command line scaffolding tool for UNS applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,13 +26,13 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "azure-devops-node-api": "^15.1.1",
29
- "@uns-kit/core": "2.0.29"
29
+ "@uns-kit/core": "2.0.30"
30
30
  },
31
31
  "unsKitPackages": {
32
- "@uns-kit/core": "2.0.29",
33
- "@uns-kit/api": "2.0.29",
34
- "@uns-kit/cron": "2.0.29",
35
- "@uns-kit/temporal": "2.0.28"
32
+ "@uns-kit/core": "2.0.30",
33
+ "@uns-kit/api": "2.0.30",
34
+ "@uns-kit/cron": "2.0.30",
35
+ "@uns-kit/temporal": "2.0.30"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc -p tsconfig.build.json",
@@ -1,5 +1,17 @@
1
1
  /**
2
2
  * Change this file according to your specifications and rename it to index.ts
3
+ *
4
+ * This example shows how to register GET and POST API endpoints using @uns-kit/api.
5
+ * Each endpoint is tied to a UNS topic/asset/objectType/objectId/attribute path and
6
+ * is automatically registered with the UNS controller and exposed via Swagger.
7
+ *
8
+ * Endpoint signature:
9
+ * api.get(topic, asset, objectType, objectId, attribute, options?)
10
+ * api.post(topic, asset, objectType, objectId, attribute, options?)
11
+ *
12
+ * Events:
13
+ * apiGetEvent — fired for every incoming GET request
14
+ * apiPostEvent — fired for every incoming POST request
3
15
  */
4
16
  import { UnsProxyProcess, ConfigFile } from "@uns-kit/core";
5
17
  import { IApiProxyOptions } from "@uns-kit/core";
@@ -10,14 +22,16 @@ import { type UnsProxyProcessWithApi } from "@uns-kit/api";
10
22
  /**
11
23
  * Load the configuration from a file.
12
24
  * On the server, this file is provided by the `uns-datahub-controller`.
13
- * In the development environment, you are responsible for creating and maintaining this file and its contents.
25
+ * In the development environment, you are responsible for creating and maintaining this file.
14
26
  */
15
27
  const config = await ConfigFile.loadConfig();
16
28
 
17
29
  /**
18
- * Connect to the API proxy process
30
+ * Create the API proxy.
31
+ * Auth is automatically applied to every registered endpoint.
32
+ * Use jwksWellKnownUrl (preferred in production) or jwtSecret (dev/simple deployments).
19
33
  */
20
- const unsProxyProcess = new UnsProxyProcess(config.infra.host!, {processName: config.uns.processName}) as UnsProxyProcessWithApi;
34
+ const unsProxyProcess = new UnsProxyProcess(config.infra.host!, { processName: config.uns.processName }) as UnsProxyProcessWithApi;
21
35
  const apiOptions: IApiProxyOptions = config.uns?.jwksWellKnownUrl
22
36
  ? {
23
37
  jwks: {
@@ -32,60 +46,110 @@ const apiOptions: IApiProxyOptions = config.uns?.jwksWellKnownUrl
32
46
  };
33
47
  const apiInput = await unsProxyProcess.createApiProxy("templateUnsApiInput", apiOptions);
34
48
 
49
+ // ─── GET endpoints ────────────────────────────────────────────────────────────
50
+
35
51
  /**
36
- * Register an API endpoint and event handler
52
+ * Register a GET endpoint.
53
+ * Query params are validated automatically; required params return 400 when missing.
54
+ * chatCanonical maps natural-language field names to query params for LLM tooling.
37
55
  */
38
- apiInput.get(
56
+ await apiInput.get(
39
57
  "enterprise/site/area/line/",
40
58
  "line-3-furnace",
41
59
  "energy-resource",
42
60
  "main-bus",
43
- "summary-1",
61
+ "current",
44
62
  {
45
- tags: ["Tag1"],
46
- apiDescription: "Test API endpoint 1",
63
+ tags: ["Energy"],
64
+ apiDescription: "Current reading for line-3-furnace main-bus",
47
65
  queryParams: [
48
- { name: "filter", type: "string", required: true, description: "Filter za podatke" },
49
- { name: "limit", type: "number", required: false, description: "Koliko podatkov želiš" },
66
+ { name: "from", type: "string", required: false, description: "Start of time range (ISO 8601)", chatCanonical: "from" },
67
+ { name: "to", type: "string", required: false, description: "End of time range (ISO 8601)", chatCanonical: "to" },
68
+ { name: "limit", type: "number", required: false, description: "Maximum number of records", chatCanonical: "limit", defaultValue: 100 },
50
69
  ],
70
+ chatDefaults: { limit: 100 },
51
71
  }
52
72
  );
53
73
 
54
- apiInput.get(
74
+ await apiInput.get(
55
75
  "enterprise/site/area/line/",
56
76
  "line-3-compressor",
57
77
  "utility-resource",
58
78
  "air-loop-1",
59
- "summary-2",
79
+ "pressure",
60
80
  {
61
- tags: ["Tag2"],
62
- apiDescription: "Test API endpoint 2",
81
+ tags: ["Utility"],
82
+ apiDescription: "Pressure reading for line-3-compressor air-loop-1",
63
83
  queryParams: [
64
- { name: "filter", type: "string", required: true, description: "Filter za podatke" },
65
- { name: "limit", type: "number", required: false, description: "Koliko podatkov želiš" },
84
+ { name: "limit", type: "number", required: false, description: "Maximum number of records", defaultValue: 50 },
66
85
  ],
67
86
  }
68
87
  );
69
88
 
89
+ // ─── POST endpoints ───────────────────────────────────────────────────────────
90
+
70
91
  /**
71
- * Optional: register a catch-all API mapping for a topic prefix.
72
- * This does not create per-attribute API nodes; the controller treats it as a fallback handler.
73
- * You can provide a separate Swagger doc for catch-all so it stays distinct from normal APIs (optional).
92
+ * Register a POST endpoint.
93
+ * Use POST when the caller needs to send a request body (commands, write operations, etc.).
94
+ * The requestBody schema is published to Swagger so clients know what to send.
74
95
  */
75
- await apiInput.registerCatchAll("sij/acroni/#", {
76
- apiDescription: "Catch-all handler for sij/acroni/*",
77
- tags: ["CatchAll"],
78
- queryParams: [
79
- { name: "filter", type: "string", required: false, description: "Filter parameter" },
80
- ]
81
- });
96
+ await apiInput.post(
97
+ "enterprise/site/area/line/",
98
+ "line-3-furnace",
99
+ "energy-resource",
100
+ "main-bus",
101
+ "setpoint",
102
+ {
103
+ tags: ["Energy"],
104
+ apiDescription: "Write a new setpoint for line-3-furnace main-bus",
105
+ requestBody: {
106
+ description: "Setpoint payload",
107
+ required: true,
108
+ schema: {
109
+ type: "object",
110
+ required: ["value"],
111
+ properties: {
112
+ value: { type: "number", description: "Target setpoint value" },
113
+ unit: { type: "string", description: "Unit of measurement, e.g. A" },
114
+ },
115
+ },
116
+ },
117
+ }
118
+ );
119
+
120
+ // ─── Event handlers ───────────────────────────────────────────────────────────
82
121
 
122
+ /**
123
+ * Handle all GET requests.
124
+ * event.req is the Express Request; event.res is the Express Response.
125
+ * Use event.req.query for query parameters and event.req.appContext for UNS context.
126
+ */
83
127
  apiInput.event.on("apiGetEvent", (event: UnsEvents["apiGetEvent"]) => {
84
128
  try {
85
- const appContext = event.req.appContext;
86
- // Add SQL query or any other code here
87
- event.res.send("OK");
129
+ // const { from, to, limit } = event.req.query;
130
+ // Add your data-fetching logic here (e.g. SQL query, time-series lookup)
131
+ event.res.json({ status: "ok", data: [] });
88
132
  } catch (error) {
89
- event.res.status(400).send("Error");
90
- }
133
+ event.res.status(400).json({ error: "Bad request" });
134
+ }
91
135
  });
136
+
137
+ /**
138
+ * Handle all POST requests.
139
+ * event.req.body contains the parsed JSON body (Express json() middleware is pre-configured).
140
+ */
141
+ apiInput.event.on("apiPostEvent", (event: UnsEvents["apiPostEvent"]) => {
142
+ try {
143
+ const body = event.req.body as { value?: number; unit?: string };
144
+ // Add your write/command logic here
145
+ event.res.json({ status: "ok", received: body });
146
+ } catch (error) {
147
+ event.res.status(400).json({ error: "Bad request" });
148
+ }
149
+ });
150
+
151
+ // ─── NOTE: registerCatchAll ───────────────────────────────────────────────────
152
+ //
153
+ // registerCatchAll() is used ONLY by the uns-api-global microservice, which acts
154
+ // as a catch-all gateway for an entire topic namespace. Regular microservices
155
+ // do NOT call this — use get() / post() above for per-attribute endpoints.