@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 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.0 darwin-arm64 node-v22.12.0
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/packages/cli/blob/v0.3.0/src/commands/rc/fetch.ts)_
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/packages/cli/blob/v0.3.0/src/commands/rc/update.ts)_
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 -->
@@ -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 data = await response.json();
21
+ const body = await response.text();
22
+ let data = null;
21
23
  if (response.status !== 200) {
22
- // eslint-disable-next-line no-console
23
- console.error(data);
24
- throw new Error('Failed to fetch RC file. See error message above.');
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
+ }
@@ -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.0"
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.0",
3
+ "version": "0.3.2",
4
4
  "description": "Laioutr CLI",
5
- "repository": "packages/cli",
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": {