@flowcore/cli 4.6.0 → 4.7.1

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 CHANGED
@@ -10,6 +10,25 @@
10
10
 
11
11
  * added description to start that includes week ([58687a7](https://github.com/flowcore-io/flowcore-cli/commit/58687a7bbb66aaa5d6da26af88e555cbb1e72467))
12
12
 
13
+ ## [4.7.1](https://github.com/flowcore-io/flowcore-cli/compare/v4.7.0...v4.7.1) (2024-10-23)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * add npmrc file ([7bd67a4](https://github.com/flowcore-io/flowcore-cli/commit/7bd67a4e9bfd08332070c5398c928458e7069b27))
19
+
20
+ ## [4.7.0](https://github.com/flowcore-io/flowcore-cli/compare/v4.6.0...v4.7.0) (2024-10-21)
21
+
22
+
23
+ ### Features
24
+
25
+ * **apply:** :sparkles: allow input from std-in, but it disables confirmation ([5e73503](https://github.com/flowcore-io/flowcore-cli/commit/5e73503038d1381eafad6b964ab1015fa9241282))
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * **configuration:** :rotating_light: fixed linting errors ([6741b7d](https://github.com/flowcore-io/flowcore-cli/commit/6741b7d58c267b1566333c5c0a7e3049a364e272))
31
+
13
32
  ## [4.6.0](https://github.com/flowcore-io/flowcore-cli/compare/v4.5.0...v4.6.0) (2024-10-21)
14
33
 
15
34
 
package/README.md CHANGED
@@ -18,7 +18,7 @@ $ npm install -g @flowcore/cli
18
18
  $ flowcore COMMAND
19
19
  running command...
20
20
  $ flowcore (--version)
21
- @flowcore/cli/4.6.0 linux-x64 node-v20.18.0
21
+ @flowcore/cli/4.7.1 linux-x64 node-v20.18.0
22
22
  $ flowcore --help [COMMAND]
23
23
  USAGE
24
24
  $ flowcore COMMAND
@@ -97,7 +97,7 @@ EXAMPLES
97
97
  $ flowcore apply -f ./path/to/manifest.yml
98
98
  ```
99
99
 
100
- _See code: [src/commands/apply.ts](https://github.com/flowcore-io/flowcore-cli/blob/v4.6.0/src/commands/apply.ts)_
100
+ _See code: [src/commands/apply.ts](https://github.com/flowcore-io/flowcore-cli/blob/v4.7.1/src/commands/apply.ts)_
101
101
 
102
102
  ## `flowcore auth delete key API_KEY_NAME`
103
103
 
@@ -468,7 +468,7 @@ USAGE
468
468
  $ flowcore delete -f <value> [--profile <value>] [-y]
469
469
 
470
470
  FLAGS
471
- -f, --file=<value>... (required) file to delete
471
+ -f, --file=<value> (required) file that contains the resources to delete or '-' for stdin
472
472
  -y, --yes skip confirmation
473
473
  --profile=<value> Specify the configuration profile to use
474
474
 
@@ -477,9 +477,11 @@ DESCRIPTION
477
477
 
478
478
  EXAMPLES
479
479
  $ flowcore delete -f ./path/to/manifest.yml
480
+
481
+ cat ./path/to/manifest.yml | flowcore delete -f -
480
482
  ```
481
483
 
482
- _See code: [src/commands/delete.ts](https://github.com/flowcore-io/flowcore-cli/blob/v4.6.0/src/commands/delete.ts)_
484
+ _See code: [src/commands/delete.ts](https://github.com/flowcore-io/flowcore-cli/blob/v4.7.1/src/commands/delete.ts)_
483
485
 
484
486
  ## `flowcore generate nextjs-entity NAME`
485
487
 
@@ -4,8 +4,10 @@ export default class Delete extends BaseCommand<typeof Delete> {
4
4
  static description: string;
5
5
  static examples: string[];
6
6
  static flags: {
7
- file: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
7
+ file: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
8
  yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
9
  };
10
10
  run(): Promise<void>;
11
+ private getDocuments;
12
+ private readFromStdin;
11
13
  }
@@ -4,6 +4,7 @@ import { Flags } from "@oclif/core";
4
4
  import dayjs from "dayjs";
5
5
  import isSameOrBefore from "dayjs/plugin/isSameOrBefore.js";
6
6
  import utc from "dayjs/plugin/utc.js";
7
+ import enquirer from "enquirer";
7
8
  import * as yaml from "js-yaml";
8
9
  import fs from "node:fs";
9
10
  import { join } from "node:path";
@@ -14,44 +15,106 @@ export default class Delete extends BaseCommand {
14
15
  static description = "Delete a resource manifest from the Flowcore Platform";
15
16
  static examples = [
16
17
  "<%= config.bin %> <%= command.id %> -f ./path/to/manifest.yml",
18
+ "cat ./path/to/manifest.yml | <%= config.bin %> <%= command.id %> -f -",
17
19
  ];
18
20
  static flags = {
19
- file: Flags.string({
21
+ file: Flags.file({
20
22
  char: "f",
21
- description: "file to delete",
22
- multiple: true,
23
+ description: "file that contains the resources to delete or '-' for stdin",
23
24
  required: true,
24
25
  }),
25
26
  yes: Flags.boolean({ char: "y", default: false, description: "skip confirmation" }),
26
27
  };
27
28
  async run() {
28
- const { flags } = await this.parse(Delete);
29
- const apiRegistry = ApiRegistryService.getInstance(this.logger);
30
- await this.config.runHook("register-api", {
31
- apiRegistry,
32
- cliConfiguration: this.cliConfiguration,
33
- logger: this.logger,
34
- });
35
29
  try {
36
- let documents = [];
37
- if (fs.statSync(flags.file[0]).isDirectory()) {
38
- const files = fs.readdirSync(flags.file[0]);
39
- documents = files.flatMap((file) => {
40
- const content = fs.readFileSync(join(flags.file[0], file), "utf8");
41
- return yaml.loadAll(content);
42
- });
43
- }
44
- else {
45
- documents = flags.file.flatMap((file) => {
46
- const content = fs.readFileSync(file, "utf8");
47
- return yaml.loadAll(content);
48
- });
30
+ const { flags } = await this.parse(Delete);
31
+ const apiRegistry = ApiRegistryService.getInstance(this.logger);
32
+ await this.config.runHook("register-api", {
33
+ apiRegistry,
34
+ cliConfiguration: this.cliConfiguration,
35
+ logger: this.logger,
36
+ });
37
+ if (flags.file === "-") {
38
+ flags.yes = true;
49
39
  }
40
+ const documents = await this.getDocuments(flags.file);
50
41
  documents.map((doc) => baseResourceDto.parse(doc));
42
+ if (documents.length === 0 && !flags.yes) {
43
+ try {
44
+ const { confirm } = await enquirer.prompt({
45
+ message: "No resources to delete, are you sure you want to continue?",
46
+ name: "confirm",
47
+ type: "confirm",
48
+ });
49
+ if (!confirm) {
50
+ this.logger.info('Operation cancelled by user');
51
+ return;
52
+ }
53
+ }
54
+ catch (promptError) {
55
+ if (promptError instanceof Error && promptError.name === 'ExitPromptError') {
56
+ this.logger.info('Operation cancelled by user');
57
+ return;
58
+ }
59
+ throw promptError;
60
+ }
61
+ }
51
62
  await apiRegistry.delete(documents, flags.yes);
63
+ this.logger.info('Resources deleted successfully');
52
64
  }
53
65
  catch (error) {
54
- this.logger.fatal(`Failed to delete documents with error: ${error}`);
66
+ if (error instanceof Error && error.name === 'ExitPromptError') {
67
+ this.logger.info('Operation cancelled by user');
68
+ }
69
+ else {
70
+ this.logger.error(`Failed to delete documents with error: ${error}`);
71
+ }
55
72
  }
56
73
  }
74
+ async getDocuments(input) {
75
+ if (input === "-") {
76
+ this.logger.info("Reading from stdin, applying all resources");
77
+ const stdinContent = await this.readFromStdin();
78
+ return yaml.loadAll(stdinContent);
79
+ }
80
+ if (Array.isArray(input)) {
81
+ return input.flatMap((file) => {
82
+ const content = fs.readFileSync(file, "utf8");
83
+ return yaml.loadAll(content);
84
+ });
85
+ }
86
+ if (fs.statSync(input).isDirectory()) {
87
+ const files = fs.readdirSync(input);
88
+ return files.flatMap((file) => {
89
+ const content = fs.readFileSync(join(input, file), "utf8");
90
+ return yaml.loadAll(content);
91
+ });
92
+ }
93
+ const content = fs.readFileSync(input, "utf8");
94
+ return yaml.loadAll(content);
95
+ }
96
+ async readFromStdin() {
97
+ return new Promise((resolve, reject) => {
98
+ let input = '';
99
+ process.stdin.setEncoding('utf8');
100
+ process.stdin.on('data', (chunk) => {
101
+ input += chunk;
102
+ });
103
+ process.stdin.on('end', () => {
104
+ resolve(input);
105
+ });
106
+ process.stdin.on('error', (err) => {
107
+ reject(err);
108
+ });
109
+ // Set a timeout to prevent hanging indefinitely
110
+ const timeout = setTimeout(() => {
111
+ reject(new Error('Stdin read timeout'));
112
+ }, 30000); // 30 seconds timeout
113
+ process.stdin.on('end', () => {
114
+ clearTimeout(timeout);
115
+ });
116
+ // Ensure stdin is released after reading
117
+ process.stdin.resume();
118
+ });
119
+ }
57
120
  }
@@ -58,7 +58,8 @@
58
58
  "args": {},
59
59
  "description": "Delete a resource manifest from the Flowcore Platform",
60
60
  "examples": [
61
- "<%= config.bin %> <%= command.id %> -f ./path/to/manifest.yml"
61
+ "<%= config.bin %> <%= command.id %> -f ./path/to/manifest.yml",
62
+ "cat ./path/to/manifest.yml | <%= config.bin %> <%= command.id %> -f -"
62
63
  ],
63
64
  "flags": {
64
65
  "profile": {
@@ -70,11 +71,11 @@
70
71
  },
71
72
  "file": {
72
73
  "char": "f",
73
- "description": "file to delete",
74
+ "description": "file that contains the resources to delete or '-' for stdin",
74
75
  "name": "file",
75
76
  "required": true,
76
77
  "hasDynamicHelp": false,
77
- "multiple": true,
78
+ "multiple": false,
78
79
  "type": "option"
79
80
  },
80
81
  "yes": {
@@ -101,5 +102,5 @@
101
102
  ]
102
103
  }
103
104
  },
104
- "version": "4.6.0"
105
+ "version": "4.7.1"
105
106
  }
package/package.json CHANGED
@@ -108,7 +108,7 @@
108
108
  "prestart": "npm run build",
109
109
  "update-schema": "rover graph introspect https://graph.api.staging.flowcore.io/graphql -o schema.gql"
110
110
  },
111
- "version": "4.6.0",
111
+ "version": "4.7.1",
112
112
  "bugs": "https://github.com/flowcore-io/flowcore-cli/issues",
113
113
  "keywords": [
114
114
  "flowcore",