@laioutr/cli 0.3.0 → 0.3.2
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 +31 -0
- package/README.md +32 -3
- package/dist/api/fetchRc.js +12 -5
- package/dist/api/releaseAppVersion.d.ts +13 -0
- package/dist/api/releaseAppVersion.js +27 -0
- package/dist/commands/app/release.d.ts +12 -0
- package/dist/commands/app/release.js +63 -0
- package/oclif.manifest.json +70 -1
- package/package.json +9 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @laioutr/cli
|
|
2
|
+
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 93b327e: Accept --project flag input with /p/ in string
|
|
8
|
+
|
|
9
|
+
## 0.3.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Move `project fetch-rc` to `rc fetch`, introduce `rc update` command
|
|
14
|
+
|
|
15
|
+
## 0.2.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Update readme
|
|
20
|
+
|
|
21
|
+
## 1.2.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- Make fetch-rc more convenient
|
|
26
|
+
|
|
27
|
+
## 1.1.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- Media Library upload handling, improved documentation-generation from canonical-types
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ $ npm install -g @laioutr/cli
|
|
|
20
20
|
$ laioutr COMMAND
|
|
21
21
|
running command...
|
|
22
22
|
$ laioutr (--version)
|
|
23
|
-
@laioutr/cli/0.3.
|
|
23
|
+
@laioutr/cli/0.3.2 darwin-arm64 node-v22.22.2
|
|
24
24
|
$ laioutr --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ laioutr COMMAND
|
|
@@ -31,6 +31,7 @@ USAGE
|
|
|
31
31
|
# Commands
|
|
32
32
|
|
|
33
33
|
<!-- commands -->
|
|
34
|
+
* [`laioutr app release`](#laioutr-app-release)
|
|
34
35
|
* [`laioutr help [COMMAND]`](#laioutr-help-command)
|
|
35
36
|
* [`laioutr plugins`](#laioutr-plugins)
|
|
36
37
|
* [`laioutr plugins add PLUGIN`](#laioutr-plugins-add-plugin)
|
|
@@ -46,6 +47,34 @@ USAGE
|
|
|
46
47
|
* [`laioutr rc fetch [FILENAME]`](#laioutr-rc-fetch-filename)
|
|
47
48
|
* [`laioutr rc update [FILENAME]`](#laioutr-rc-update-filename)
|
|
48
49
|
|
|
50
|
+
## `laioutr app release`
|
|
51
|
+
|
|
52
|
+
Publish an app version to the Laioutr platform.
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
USAGE
|
|
56
|
+
$ laioutr app release --cockpitApiHost <value> --cwd <value> -k <value> [-c stable|testing]
|
|
57
|
+
|
|
58
|
+
FLAGS
|
|
59
|
+
-c, --channel=<option> Release channel (auto-detected from version if omitted)
|
|
60
|
+
<options: stable|testing>
|
|
61
|
+
-k, --key=<value> (required) API key for authentication
|
|
62
|
+
--cockpitApiHost=<value> (required) [default: https://cockpit.laioutr.cloud] cockpit api host
|
|
63
|
+
--cwd=<value> (required) [default: /Users/sl/src/laioutr/apps/cli] current working directory
|
|
64
|
+
|
|
65
|
+
DESCRIPTION
|
|
66
|
+
Publish an app version to the Laioutr platform.
|
|
67
|
+
|
|
68
|
+
EXAMPLES
|
|
69
|
+
$ laioutr app release
|
|
70
|
+
|
|
71
|
+
$ laioutr app release --channel testing
|
|
72
|
+
|
|
73
|
+
LAIOUTR_API_KEY=orgKey_xxx laioutr app release
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
_See code: [src/commands/app/release.ts](https://github.com/laioutr/laioutr/blob/v0.3.2/src/commands/app/release.ts)_
|
|
77
|
+
|
|
49
78
|
## `laioutr help [COMMAND]`
|
|
50
79
|
|
|
51
80
|
Display help for laioutr.
|
|
@@ -406,7 +435,7 @@ EXAMPLES
|
|
|
406
435
|
$ laioutr rc fetch
|
|
407
436
|
```
|
|
408
437
|
|
|
409
|
-
_See code: [src/commands/rc/fetch.ts](https://github.com/
|
|
438
|
+
_See code: [src/commands/rc/fetch.ts](https://github.com/laioutr/laioutr/blob/v0.3.2/src/commands/rc/fetch.ts)_
|
|
410
439
|
|
|
411
440
|
## `laioutr rc update [FILENAME]`
|
|
412
441
|
|
|
@@ -427,5 +456,5 @@ EXAMPLES
|
|
|
427
456
|
$ laioutr rc update
|
|
428
457
|
```
|
|
429
458
|
|
|
430
|
-
_See code: [src/commands/rc/update.ts](https://github.com/
|
|
459
|
+
_See code: [src/commands/rc/update.ts](https://github.com/laioutr/laioutr/blob/v0.3.2/src/commands/rc/update.ts)_
|
|
431
460
|
<!-- commandsstop -->
|
package/dist/api/fetchRc.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
import { z } from 'zod/v4';
|
|
2
3
|
const apiResponseSchema = z.object({
|
|
3
4
|
content: z.string(),
|
|
4
5
|
});
|
|
5
6
|
export const fetchRc = async (flags) => {
|
|
6
7
|
const url = `${flags.cockpitApiHost}/api/v1/project/fetch-rc`;
|
|
7
|
-
const [organizationSlug, projectSlug] = flags.project.split('/');
|
|
8
|
+
const [organizationSlug, projectSlug] = flags.project.replace('/p/', '').split('/');
|
|
8
9
|
const response = await fetch(url, {
|
|
9
10
|
body: JSON.stringify({
|
|
10
11
|
environmentName: flags.environmentName,
|
|
@@ -17,11 +18,17 @@ export const fetchRc = async (flags) => {
|
|
|
17
18
|
},
|
|
18
19
|
method: 'POST',
|
|
19
20
|
});
|
|
20
|
-
const
|
|
21
|
+
const body = await response.text();
|
|
22
|
+
let data = null;
|
|
21
23
|
if (response.status !== 200) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
throw new Error(`Failed to fetch RC file. Status: ${response.status} ${response.statusText}. Body: ${body}`);
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
data = JSON.parse(body);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(error, response);
|
|
31
|
+
throw new Error('Failed to parse RC file. See error message above.');
|
|
25
32
|
}
|
|
26
33
|
const parsed = apiResponseSchema.parse(data);
|
|
27
34
|
return parsed.content;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ReleaseOptions {
|
|
2
|
+
cockpitApiHost: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
packageName: string;
|
|
5
|
+
version: string;
|
|
6
|
+
configSchema: Record<string, unknown>;
|
|
7
|
+
peerDependencies: Record<string, string>;
|
|
8
|
+
channel?: 'stable' | 'testing';
|
|
9
|
+
}
|
|
10
|
+
export declare const releaseAppVersion: (options: ReleaseOptions) => Promise<{
|
|
11
|
+
message: string;
|
|
12
|
+
versionId?: string | undefined;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
const releaseResponseSchema = z.object({
|
|
3
|
+
message: z.string(),
|
|
4
|
+
versionId: z.string().optional(),
|
|
5
|
+
});
|
|
6
|
+
export const releaseAppVersion = async (options) => {
|
|
7
|
+
const url = `${options.cockpitApiHost}/api/v1/app/release`;
|
|
8
|
+
const response = await fetch(url, {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({
|
|
15
|
+
packageName: options.packageName,
|
|
16
|
+
version: options.version,
|
|
17
|
+
configSchema: options.configSchema,
|
|
18
|
+
peerDependencies: options.peerDependencies,
|
|
19
|
+
channel: options.channel,
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
const body = await response.text();
|
|
23
|
+
if (response.status !== 200) {
|
|
24
|
+
throw new Error(`Release failed (${response.status}): ${body}`);
|
|
25
|
+
}
|
|
26
|
+
return releaseResponseSchema.parse(JSON.parse(body));
|
|
27
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import LaioutrBaseCommand from '../../laioutr-base-command.js';
|
|
2
|
+
export default class AppRelease extends LaioutrBaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
key: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
channel: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
cockpitApiHost: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
cwd: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { Flags } from '@oclif/core';
|
|
4
|
+
import { releaseAppVersion } from '../../api/releaseAppVersion.js';
|
|
5
|
+
import LaioutrBaseCommand from '../../laioutr-base-command.js';
|
|
6
|
+
export default class AppRelease extends LaioutrBaseCommand {
|
|
7
|
+
static description = 'Publish an app version to the Laioutr platform.';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> app release',
|
|
10
|
+
'<%= config.bin %> app release --channel testing',
|
|
11
|
+
'LAIOUTR_API_KEY=orgKey_xxx <%= config.bin %> app release',
|
|
12
|
+
];
|
|
13
|
+
static flags = {
|
|
14
|
+
...LaioutrBaseCommand.flags,
|
|
15
|
+
key: Flags.string({
|
|
16
|
+
char: 'k',
|
|
17
|
+
description: 'API key for authentication',
|
|
18
|
+
env: 'LAIOUTR_API_KEY',
|
|
19
|
+
required: true,
|
|
20
|
+
}),
|
|
21
|
+
channel: Flags.string({
|
|
22
|
+
char: 'c',
|
|
23
|
+
description: 'Release channel (auto-detected from version if omitted)',
|
|
24
|
+
options: ['stable', 'testing'],
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
const { flags } = await this.parse(AppRelease);
|
|
29
|
+
// 1. Read package.json
|
|
30
|
+
const pkgPath = path.join(flags.cwd, 'package.json');
|
|
31
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
32
|
+
if (!pkg.name || !pkg.version) {
|
|
33
|
+
this.error('package.json must have "name" and "version" fields');
|
|
34
|
+
}
|
|
35
|
+
// 2. Import configSchema via jiti
|
|
36
|
+
let configSchema = {};
|
|
37
|
+
try {
|
|
38
|
+
const { createJiti } = await import('jiti');
|
|
39
|
+
const jiti = createJiti(flags.cwd);
|
|
40
|
+
const mod = await jiti.import(path.join(flags.cwd, 'src/module.ts'));
|
|
41
|
+
configSchema = mod.configSchema ?? {};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
this.warn('Could not import configSchema from src/module.ts — publishing without config schema');
|
|
45
|
+
}
|
|
46
|
+
// 3. Extract peer dependencies
|
|
47
|
+
const peerDependencies = pkg.peerDependencies ?? {};
|
|
48
|
+
// 4. Detect channel
|
|
49
|
+
const channel = flags.channel;
|
|
50
|
+
this.log(`Publishing ${pkg.name}@${pkg.version}...`);
|
|
51
|
+
// 5. Call the release API
|
|
52
|
+
const result = await releaseAppVersion({
|
|
53
|
+
cockpitApiHost: flags.cockpitApiHost,
|
|
54
|
+
apiKey: flags.key,
|
|
55
|
+
packageName: pkg.name,
|
|
56
|
+
version: pkg.version,
|
|
57
|
+
configSchema,
|
|
58
|
+
peerDependencies,
|
|
59
|
+
channel,
|
|
60
|
+
});
|
|
61
|
+
this.log(result.message);
|
|
62
|
+
}
|
|
63
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"commands": {
|
|
3
|
+
"app:release": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": "Publish an app version to the Laioutr platform.",
|
|
7
|
+
"examples": [
|
|
8
|
+
"<%= config.bin %> app release",
|
|
9
|
+
"<%= config.bin %> app release --channel testing",
|
|
10
|
+
"LAIOUTR_API_KEY=orgKey_xxx <%= config.bin %> app release"
|
|
11
|
+
],
|
|
12
|
+
"flags": {
|
|
13
|
+
"cockpitApiHost": {
|
|
14
|
+
"description": "cockpit api host",
|
|
15
|
+
"env": "COCKPIT_API_HOST",
|
|
16
|
+
"name": "cockpitApiHost",
|
|
17
|
+
"required": true,
|
|
18
|
+
"default": "https://cockpit.laioutr.cloud",
|
|
19
|
+
"hasDynamicHelp": false,
|
|
20
|
+
"multiple": false,
|
|
21
|
+
"type": "option"
|
|
22
|
+
},
|
|
23
|
+
"cwd": {
|
|
24
|
+
"description": "current working directory",
|
|
25
|
+
"env": "CWD",
|
|
26
|
+
"name": "cwd",
|
|
27
|
+
"required": true,
|
|
28
|
+
"default": "/Users/sl/src/laioutr/apps/cli",
|
|
29
|
+
"hasDynamicHelp": false,
|
|
30
|
+
"multiple": false,
|
|
31
|
+
"type": "option"
|
|
32
|
+
},
|
|
33
|
+
"key": {
|
|
34
|
+
"char": "k",
|
|
35
|
+
"description": "API key for authentication",
|
|
36
|
+
"env": "LAIOUTR_API_KEY",
|
|
37
|
+
"name": "key",
|
|
38
|
+
"required": true,
|
|
39
|
+
"hasDynamicHelp": false,
|
|
40
|
+
"multiple": false,
|
|
41
|
+
"type": "option"
|
|
42
|
+
},
|
|
43
|
+
"channel": {
|
|
44
|
+
"char": "c",
|
|
45
|
+
"description": "Release channel (auto-detected from version if omitted)",
|
|
46
|
+
"name": "channel",
|
|
47
|
+
"hasDynamicHelp": false,
|
|
48
|
+
"multiple": false,
|
|
49
|
+
"options": [
|
|
50
|
+
"stable",
|
|
51
|
+
"testing"
|
|
52
|
+
],
|
|
53
|
+
"type": "option"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"hasDynamicHelp": false,
|
|
57
|
+
"hiddenAliases": [],
|
|
58
|
+
"id": "app:release",
|
|
59
|
+
"pluginAlias": "@laioutr/cli",
|
|
60
|
+
"pluginName": "@laioutr/cli",
|
|
61
|
+
"pluginType": "core",
|
|
62
|
+
"strict": true,
|
|
63
|
+
"enableJsonFlag": false,
|
|
64
|
+
"isESM": true,
|
|
65
|
+
"relativePath": [
|
|
66
|
+
"dist",
|
|
67
|
+
"commands",
|
|
68
|
+
"app",
|
|
69
|
+
"release.js"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
3
72
|
"rc:fetch": {
|
|
4
73
|
"aliases": [
|
|
5
74
|
"project:fetch-rc"
|
|
@@ -137,5 +206,5 @@
|
|
|
137
206
|
]
|
|
138
207
|
}
|
|
139
208
|
},
|
|
140
|
-
"version": "0.3.
|
|
209
|
+
"version": "0.3.2"
|
|
141
210
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laioutr/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Laioutr CLI",
|
|
5
|
-
"repository":
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/laioutr/laioutr.git",
|
|
8
|
+
"directory": "apps/cli"
|
|
9
|
+
},
|
|
6
10
|
"author": "Laioutr GmbH",
|
|
7
11
|
"type": "module",
|
|
8
12
|
"main": "dist/index.js",
|
|
@@ -13,7 +17,8 @@
|
|
|
13
17
|
"files": [
|
|
14
18
|
"/bin",
|
|
15
19
|
"/dist",
|
|
16
|
-
"/oclif.manifest.json"
|
|
20
|
+
"/oclif.manifest.json",
|
|
21
|
+
"/CHANGELOG.md"
|
|
17
22
|
],
|
|
18
23
|
"lint-staged": {
|
|
19
24
|
"*.{js,mjs,jsx,ts,tsx,vue}": [
|
|
@@ -36,6 +41,7 @@
|
|
|
36
41
|
"@oclif/core": "^4",
|
|
37
42
|
"@oclif/plugin-help": "^6",
|
|
38
43
|
"@oclif/plugin-plugins": "^5",
|
|
44
|
+
"jiti": "^2.6.1",
|
|
39
45
|
"zod": "3.25.61"
|
|
40
46
|
},
|
|
41
47
|
"devDependencies": {
|