@vertexvis/plm-cli 0.1.3
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 +373 -0
- package/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/lib/commands/configure.d.ts +30 -0
- package/lib/commands/configure.js +162 -0
- package/lib/commands/set-overwrite.d.ts +13 -0
- package/lib/commands/set-overwrite.js +75 -0
- package/lib/commands/view-part-jobs.d.ts +13 -0
- package/lib/commands/view-part-jobs.js +58 -0
- package/lib/commands/view-part-structure.d.ts +13 -0
- package/lib/commands/view-part-structure.js +53 -0
- package/lib/commands/view-part.d.ts +13 -0
- package/lib/commands/view-part.js +83 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +5 -0
- package/lib/lib/args.d.ts +11 -0
- package/lib/lib/args.js +20 -0
- package/lib/lib/base.d.ts +7 -0
- package/lib/lib/base.js +13 -0
- package/lib/lib/config.d.ts +15 -0
- package/lib/lib/config.js +59 -0
- package/lib/lib/plm-api/find-registered-part-revision.d.ts +6 -0
- package/lib/lib/plm-api/find-registered-part-revision.js +24 -0
- package/lib/lib/plm-api/get-registered-part-revision-jobs.d.ts +3 -0
- package/lib/lib/plm-api/get-registered-part-revision-jobs.js +25 -0
- package/lib/lib/plm-api/index.d.ts +4 -0
- package/lib/lib/plm-api/index.js +7 -0
- package/lib/lib/plm-api/plm-api.d.ts +9 -0
- package/lib/lib/plm-api/plm-api.js +14 -0
- package/lib/lib/plm-api/set-overwrite-policy.d.ts +7 -0
- package/lib/lib/plm-api/set-overwrite-policy.js +24 -0
- package/lib/lib/prompt.d.ts +2 -0
- package/lib/lib/prompt.js +19 -0
- package/lib/lib/tree/tree-node.d.ts +64 -0
- package/lib/lib/tree/tree-node.js +150 -0
- package/lib/lib/vertex-api/client.d.ts +2 -0
- package/lib/lib/vertex-api/client.js +26 -0
- package/lib/lib/vertex-api/get-part-revision-instance-tree.d.ts +10 -0
- package/lib/lib/vertex-api/get-part-revision-instance-tree.js +97 -0
- package/lib/lib/vertex-api/index.d.ts +2 -0
- package/lib/lib/vertex-api/index.js +5 -0
- package/oclif.manifest.json +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# vertex-plm-cli
|
|
2
|
+
|
|
3
|
+
**Vertex PLM CLI Utilities**
|
|
4
|
+
|
|
5
|
+
A cross-platform CLI for interacting with **Vertex PLM** services and workflows. Built with **Node.js + TypeScript** using the [oclif](https://oclif.io) framework.
|
|
6
|
+
|
|
7
|
+
Commands available:
|
|
8
|
+
|
|
9
|
+
- `configure` — manage credentials and service hosts via a local config file
|
|
10
|
+
- `set-overwrite` — set overwrite policy for a part revision and all related parts
|
|
11
|
+
- `view-part` — look up a registered part revision
|
|
12
|
+
- `view-part-jobs` — view PLM kernel jobs for a part revision
|
|
13
|
+
- `view-part-structure` — view the instance tree (BOM) for a part revision
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- Node.js >= 16.0.0
|
|
20
|
+
- Yarn
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Quick Start (Dev)
|
|
25
|
+
|
|
26
|
+
Install dependencies:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
yarn
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Build (compile TypeScript to `lib/`):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
yarn build
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Run the CLI:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
./bin/run --help
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or link it globally so it's available as `vertex-plm`:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
yarn link
|
|
48
|
+
vertex-plm --help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
This CLI requires the following environment variables (or stored config values):
|
|
56
|
+
|
|
57
|
+
| Variable | Purpose |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `VERTEX_CLIENT_ID` | Vertex Platform OAuth2 client ID |
|
|
60
|
+
| `VERTEX_CLIENT_SECRET` | Vertex Platform OAuth2 client secret |
|
|
61
|
+
| `VERTEX_API_HOST` | Vertex Platform API base URL (e.g. `https://api.vertexvis.com`) |
|
|
62
|
+
| `VERTEX_PLM_HOST` | Vertex PLM Integration Service base URL |
|
|
63
|
+
| `VERTEX_PLM_API_KEY` | Vertex PLM Integration Service API key |
|
|
64
|
+
|
|
65
|
+
### How config works
|
|
66
|
+
|
|
67
|
+
On startup, the CLI loads:
|
|
68
|
+
|
|
69
|
+
1. **Environment variables already in your shell / CI** (highest priority)
|
|
70
|
+
2. Config file at `~/.vertex-plm/config.json` (fallback)
|
|
71
|
+
|
|
72
|
+
Config file values only populate `process.env.*` if the env var is not already set. This means you can safely override stored config in CI:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
VERTEX_PLM_API_KEY="ci-key" vertex-plm view-part-structure P123 A
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Configure (interactive)
|
|
79
|
+
|
|
80
|
+
Prompts for each value; leave blank to keep the current stored value:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
vertex-plm configure --interactive
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Configure (flags)
|
|
87
|
+
|
|
88
|
+
Set any subset of values directly:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
vertex-plm configure \
|
|
92
|
+
--VERTEX_API_HOST https://api.vertexvis.com \
|
|
93
|
+
--VERTEX_PLM_HOST https://plm.example.com \
|
|
94
|
+
--VERTEX_CLIENT_ID "abc" \
|
|
95
|
+
--VERTEX_CLIENT_SECRET "super-secret" \
|
|
96
|
+
--VERTEX_PLM_API_KEY "plm-key"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Show config
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
vertex-plm configure --show
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Secrets are redacted in output:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"VERTEX_CLIENT_ID": "abc",
|
|
110
|
+
"VERTEX_CLIENT_SECRET": "********",
|
|
111
|
+
"VERTEX_API_HOST": "https://api.vertexvis.com",
|
|
112
|
+
"VERTEX_PLM_HOST": "https://plm.example.com",
|
|
113
|
+
"VERTEX_PLM_API_KEY": "********"
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Unset keys
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
vertex-plm configure --unset VERTEX_PLM_API_KEY VERTEX_CLIENT_SECRET
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Reset config
|
|
124
|
+
|
|
125
|
+
Deletes the config file entirely:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
vertex-plm configure --reset
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Config file location
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
~/.vertex-plm/config.json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Commands
|
|
140
|
+
|
|
141
|
+
### `set-overwrite`
|
|
142
|
+
|
|
143
|
+
Sets the overwrite policy in the PLM Integration Service for the given part revision and **all related part revisions** found in the Vertex Platform instance tree.
|
|
144
|
+
|
|
145
|
+
**Usage**
|
|
146
|
+
```bash
|
|
147
|
+
vertex-plm set-overwrite <plm-part-id> <plm-revision-id> [plm-iteration-id]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Examples**
|
|
151
|
+
```bash
|
|
152
|
+
vertex-plm set-overwrite P123 A
|
|
153
|
+
vertex-plm set-overwrite P123 A 7
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### `view-part`
|
|
159
|
+
|
|
160
|
+
Looks up a registered part revision in the PLM Integration Service and its corresponding entry in the Vertex Platform. If not found in the PLM service, falls back to searching the Vertex Platform directly.
|
|
161
|
+
|
|
162
|
+
**Usage**
|
|
163
|
+
```bash
|
|
164
|
+
vertex-plm view-part <plm-part-id> <plm-revision-id> [plm-iteration-id]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Examples**
|
|
168
|
+
```bash
|
|
169
|
+
vertex-plm view-part P123 A
|
|
170
|
+
vertex-plm view-part P123 A 7
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### `view-part-jobs`
|
|
176
|
+
|
|
177
|
+
Displays PLM kernel jobs associated with a registered part revision.
|
|
178
|
+
|
|
179
|
+
**Usage**
|
|
180
|
+
```bash
|
|
181
|
+
vertex-plm view-part-jobs <plm-part-id> <plm-revision-id> [plm-iteration-id]
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Examples**
|
|
185
|
+
```bash
|
|
186
|
+
vertex-plm view-part-jobs P123 A
|
|
187
|
+
vertex-plm view-part-jobs P123 A 7
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### `view-part-structure`
|
|
193
|
+
|
|
194
|
+
Fetches and displays the full part revision instance tree (BOM hierarchy) from the Vertex Platform for the given PLM part revision.
|
|
195
|
+
|
|
196
|
+
**Usage**
|
|
197
|
+
```bash
|
|
198
|
+
vertex-plm view-part-structure <plm-part-id> <plm-revision-id> [plm-iteration-id]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Examples**
|
|
202
|
+
```bash
|
|
203
|
+
vertex-plm view-part-structure P123 A
|
|
204
|
+
vertex-plm view-part-structure P123 A 7
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Development
|
|
210
|
+
|
|
211
|
+
### Project structure
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
src/
|
|
215
|
+
index.ts # oclif entrypoint (re-exports run)
|
|
216
|
+
commands/
|
|
217
|
+
configure.ts # config file management
|
|
218
|
+
set-overwrite.ts # set-overwrite command
|
|
219
|
+
view-part.ts # view-part command
|
|
220
|
+
view-part-jobs.ts # view-part-jobs command
|
|
221
|
+
view-part-structure.ts # view-part-structure command
|
|
222
|
+
lib/
|
|
223
|
+
args.ts # shared arg parsing/types
|
|
224
|
+
base.ts # BaseCommand (loads config on init)
|
|
225
|
+
config.ts # config file load/save/env injection
|
|
226
|
+
prompt.ts # interactive prompts (secrets masked)
|
|
227
|
+
plm-api/ # PLM Integration Service client
|
|
228
|
+
vertex-api/ # Vertex Platform API client
|
|
229
|
+
tree/ # generic tree structure for BOM traversal
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Running tests
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
yarn test
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Lint and format
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
yarn lint
|
|
242
|
+
yarn format
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Pre-commit checks
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
yarn pre-commit
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
This runs lint and format together.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Contributing
|
|
256
|
+
|
|
257
|
+
1. Clone and install:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
git clone <repo-url>
|
|
261
|
+
cd vertex-plm-cli
|
|
262
|
+
yarn
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
2. Make changes in `src/`. Keep `BaseCommand` as the base for all commands — it handles config loading automatically.
|
|
266
|
+
|
|
267
|
+
3. Build and verify:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
yarn build
|
|
271
|
+
./bin/run --help
|
|
272
|
+
./bin/run --version
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
4. A good PR should include:
|
|
276
|
+
- A clear description of what changed and why
|
|
277
|
+
- Example command usage
|
|
278
|
+
- Updates to this README if behavior changes
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Release Process
|
|
283
|
+
|
|
284
|
+
This project uses [semantic versioning](https://semver.org): `MAJOR.MINOR.PATCH`.
|
|
285
|
+
|
|
286
|
+
### 1) Bump the version
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
npm version patch # or minor / major
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
This updates `package.json` and runs `git add package.json` (via the `version` script).
|
|
293
|
+
|
|
294
|
+
### 2) Build and verify
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
yarn build
|
|
298
|
+
./bin/run --version
|
|
299
|
+
./bin/run --help
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 3) Commit and tag
|
|
303
|
+
|
|
304
|
+
If not auto-committed by `npm version`:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
git commit -m "chore(release): vX.Y.Z"
|
|
308
|
+
git tag vX.Y.Z
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 4) Push
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
git push origin main
|
|
315
|
+
git push origin vX.Y.Z
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 5) Create a GitHub Release
|
|
319
|
+
|
|
320
|
+
1. Go to **Releases** → **Draft a new release**
|
|
321
|
+
2. Select the tag `vX.Y.Z`
|
|
322
|
+
3. Add release notes summarizing changes
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Troubleshooting
|
|
327
|
+
|
|
328
|
+
### `vertex-plm: command not found`
|
|
329
|
+
|
|
330
|
+
If developing locally without linking:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
./bin/run --help
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Or link globally:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
yarn link
|
|
340
|
+
vertex-plm --help
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Config isn't being applied
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
vertex-plm configure --show
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Remember: environment variables override config file values at runtime.
|
|
350
|
+
|
|
351
|
+
### Host validation errors
|
|
352
|
+
|
|
353
|
+
`VERTEX_API_HOST` and `VERTEX_PLM_HOST` must be valid URLs:
|
|
354
|
+
|
|
355
|
+
✅ Valid:
|
|
356
|
+
- `https://api.vertexvis.com`
|
|
357
|
+
- `http://localhost:3000`
|
|
358
|
+
|
|
359
|
+
❌ Invalid:
|
|
360
|
+
- `api.vertexvis.com` (missing protocol)
|
|
361
|
+
- `vertex-plm-host` (not a URL)
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Security Notes
|
|
366
|
+
|
|
367
|
+
The config file stores secrets (client secret + API key) as plain JSON in your home directory. Prefer environment variables in CI and shared environments. Treat `~/.vertex-plm/config.json` as sensitive.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## License
|
|
372
|
+
|
|
373
|
+
Internal / TBD.
|
package/bin/run
ADDED
package/bin/run.cmd
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { flags } from '@oclif/command';
|
|
2
|
+
import BaseCommand from '../lib/base';
|
|
3
|
+
export interface ConfigureInput {
|
|
4
|
+
VERTEX_CLIENT_ID?: string;
|
|
5
|
+
VERTEX_CLIENT_SECRET?: string;
|
|
6
|
+
VERTEX_API_HOST?: string;
|
|
7
|
+
VERTEX_PLM_HOST?: string;
|
|
8
|
+
VERTEX_PLM_API_KEY?: string;
|
|
9
|
+
show?: boolean;
|
|
10
|
+
interactive?: boolean;
|
|
11
|
+
reset?: boolean;
|
|
12
|
+
unset?: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function configureFn(input: ConfigureInput): Promise<void>;
|
|
15
|
+
export default class Configure extends BaseCommand {
|
|
16
|
+
static description: string;
|
|
17
|
+
static flags: {
|
|
18
|
+
VERTEX_CLIENT_ID: flags.IOptionFlag<string | undefined>;
|
|
19
|
+
VERTEX_CLIENT_SECRET: flags.IOptionFlag<string | undefined>;
|
|
20
|
+
VERTEX_API_HOST: flags.IOptionFlag<string | undefined>;
|
|
21
|
+
VERTEX_PLM_HOST: flags.IOptionFlag<string | undefined>;
|
|
22
|
+
VERTEX_PLM_API_KEY: flags.IOptionFlag<string | undefined>;
|
|
23
|
+
interactive: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
24
|
+
unset: flags.IOptionFlag<string[]>;
|
|
25
|
+
reset: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
26
|
+
show: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
27
|
+
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
28
|
+
};
|
|
29
|
+
run(): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureFn = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const command_1 = require("@oclif/command");
|
|
6
|
+
const base_1 = (0, tslib_1.__importDefault)(require("../lib/base"));
|
|
7
|
+
const config_1 = require("../lib/config");
|
|
8
|
+
const prompt_1 = require("../lib/prompt");
|
|
9
|
+
function requireNonEmptyString(v, name) {
|
|
10
|
+
if (typeof v !== 'string' || v.trim().length === 0) {
|
|
11
|
+
throw new Error(`${name} must be a non-empty string`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function validateHostUrl(value, name) {
|
|
15
|
+
let u;
|
|
16
|
+
try {
|
|
17
|
+
u = new URL(value);
|
|
18
|
+
}
|
|
19
|
+
catch (_a) {
|
|
20
|
+
throw new Error(`${name} must be a valid URL (e.g. https://example.com)`);
|
|
21
|
+
}
|
|
22
|
+
if (u.protocol !== 'https:' && u.protocol !== 'http:') {
|
|
23
|
+
throw new Error(`${name} must start with http:// or https://`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function normalizeKey(k) {
|
|
27
|
+
const upper = k.trim().toUpperCase();
|
|
28
|
+
return config_1.CONFIG_KEYS.includes(upper)
|
|
29
|
+
? upper
|
|
30
|
+
: undefined;
|
|
31
|
+
}
|
|
32
|
+
function applyFlagValues(existing, input) {
|
|
33
|
+
const merged = Object.assign({}, existing);
|
|
34
|
+
for (const k of config_1.CONFIG_KEYS) {
|
|
35
|
+
const v = input[k];
|
|
36
|
+
if (v === null || v === undefined)
|
|
37
|
+
continue;
|
|
38
|
+
requireNonEmptyString(v, k);
|
|
39
|
+
merged[k] = v;
|
|
40
|
+
}
|
|
41
|
+
if (merged.VERTEX_API_HOST)
|
|
42
|
+
validateHostUrl(merged.VERTEX_API_HOST, 'VERTEX_API_HOST');
|
|
43
|
+
if (merged.VERTEX_PLM_HOST)
|
|
44
|
+
validateHostUrl(merged.VERTEX_PLM_HOST, 'VERTEX_PLM_HOST');
|
|
45
|
+
return merged;
|
|
46
|
+
}
|
|
47
|
+
async function applyInteractive(existing, merged) {
|
|
48
|
+
// Capture all current values before any awaits to avoid require-atomic-updates
|
|
49
|
+
const existingApiHost = merged.VERTEX_API_HOST;
|
|
50
|
+
const existingPlmHost = merged.VERTEX_PLM_HOST;
|
|
51
|
+
const existingClientId = merged.VERTEX_CLIENT_ID;
|
|
52
|
+
const existingClientSecret = merged.VERTEX_CLIENT_SECRET;
|
|
53
|
+
const existingPlmKey = merged.VERTEX_PLM_API_KEY;
|
|
54
|
+
const result = Object.assign({}, merged);
|
|
55
|
+
const wantApiHost = existingApiHost !== null && existingApiHost !== void 0 ? existingApiHost : (await (0, prompt_1.promptText)('VERTEX_API_HOST', existingApiHost));
|
|
56
|
+
if (wantApiHost) {
|
|
57
|
+
requireNonEmptyString(wantApiHost, 'VERTEX_API_HOST');
|
|
58
|
+
validateHostUrl(wantApiHost, 'VERTEX_API_HOST');
|
|
59
|
+
result.VERTEX_API_HOST = wantApiHost;
|
|
60
|
+
}
|
|
61
|
+
const wantPlmHost = existingPlmHost !== null && existingPlmHost !== void 0 ? existingPlmHost : (await (0, prompt_1.promptText)('VERTEX_PLM_HOST', existingPlmHost));
|
|
62
|
+
if (wantPlmHost) {
|
|
63
|
+
requireNonEmptyString(wantPlmHost, 'VERTEX_PLM_HOST');
|
|
64
|
+
validateHostUrl(wantPlmHost, 'VERTEX_PLM_HOST');
|
|
65
|
+
result.VERTEX_PLM_HOST = wantPlmHost;
|
|
66
|
+
}
|
|
67
|
+
const wantClientId = existingClientId !== null && existingClientId !== void 0 ? existingClientId : (await (0, prompt_1.promptText)('VERTEX_CLIENT_ID', existingClientId));
|
|
68
|
+
if (wantClientId) {
|
|
69
|
+
requireNonEmptyString(wantClientId, 'VERTEX_CLIENT_ID');
|
|
70
|
+
result.VERTEX_CLIENT_ID = wantClientId;
|
|
71
|
+
}
|
|
72
|
+
const wantClientSecret = existingClientSecret !== null && existingClientSecret !== void 0 ? existingClientSecret : (await (0, prompt_1.promptSecret)('VERTEX_CLIENT_SECRET', Boolean(existing.VERTEX_CLIENT_SECRET)));
|
|
73
|
+
if (wantClientSecret) {
|
|
74
|
+
requireNonEmptyString(wantClientSecret, 'VERTEX_CLIENT_SECRET');
|
|
75
|
+
result.VERTEX_CLIENT_SECRET = wantClientSecret;
|
|
76
|
+
}
|
|
77
|
+
const wantPlmKey = existingPlmKey !== null && existingPlmKey !== void 0 ? existingPlmKey : (await (0, prompt_1.promptSecret)('VERTEX_PLM_API_KEY', Boolean(existing.VERTEX_PLM_API_KEY)));
|
|
78
|
+
if (wantPlmKey) {
|
|
79
|
+
requireNonEmptyString(wantPlmKey, 'VERTEX_PLM_API_KEY');
|
|
80
|
+
result.VERTEX_PLM_API_KEY = wantPlmKey;
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
function inputIsEmpty(input) {
|
|
85
|
+
const flagValues = config_1.CONFIG_KEYS.map((k) => input[k]);
|
|
86
|
+
const hasFlagValues = flagValues.some((v) => v !== null && v !== undefined);
|
|
87
|
+
const hasUnsets = input.unset !== null && input.unset !== undefined && input.unset.length > 0;
|
|
88
|
+
return (!hasFlagValues &&
|
|
89
|
+
!hasUnsets &&
|
|
90
|
+
!input.reset &&
|
|
91
|
+
!input.show &&
|
|
92
|
+
!input.interactive);
|
|
93
|
+
}
|
|
94
|
+
function existingIsEmpty(existing) {
|
|
95
|
+
return config_1.CONFIG_KEYS.every((k) => !(k in existing));
|
|
96
|
+
}
|
|
97
|
+
async function configureFn(input) {
|
|
98
|
+
var _a;
|
|
99
|
+
const existing = await (0, config_1.readConfig)();
|
|
100
|
+
if (input.reset) {
|
|
101
|
+
await (0, config_1.deleteConfigFile)();
|
|
102
|
+
console.log(`Config reset (deleted): ${(0, config_1.getConfigPath)()}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (input.show) {
|
|
106
|
+
console.log(JSON.stringify((0, config_1.redactConfig)(existing), null, 2));
|
|
107
|
+
console.log(`Path: ${(0, config_1.getConfigPath)()}`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let merged = Object.assign({}, existing);
|
|
111
|
+
if ((_a = input.unset) === null || _a === void 0 ? void 0 : _a.length) {
|
|
112
|
+
for (const raw of input.unset) {
|
|
113
|
+
const key = normalizeKey(raw);
|
|
114
|
+
if (!key)
|
|
115
|
+
throw new Error(`Unknown key to unset: ${raw}. Valid: ${config_1.CONFIG_KEYS.join(', ')}`);
|
|
116
|
+
delete merged[key];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
merged = applyFlagValues(existing, Object.assign({}, input));
|
|
120
|
+
if (input.interactive || (inputIsEmpty(input) && existingIsEmpty(existing))) {
|
|
121
|
+
merged = await applyInteractive(existing, merged);
|
|
122
|
+
}
|
|
123
|
+
await (0, config_1.writeConfig)(merged);
|
|
124
|
+
console.log(`Saved config to ${(0, config_1.getConfigPath)()}:`);
|
|
125
|
+
console.log(JSON.stringify((0, config_1.redactConfig)(merged), null, 2));
|
|
126
|
+
}
|
|
127
|
+
exports.configureFn = configureFn;
|
|
128
|
+
class Configure extends base_1.default {
|
|
129
|
+
async run() {
|
|
130
|
+
const { flags: f } = this.parse(Configure);
|
|
131
|
+
await configureFn({
|
|
132
|
+
VERTEX_CLIENT_ID: f.VERTEX_CLIENT_ID,
|
|
133
|
+
VERTEX_CLIENT_SECRET: f.VERTEX_CLIENT_SECRET,
|
|
134
|
+
VERTEX_API_HOST: f.VERTEX_API_HOST,
|
|
135
|
+
VERTEX_PLM_HOST: f.VERTEX_PLM_HOST,
|
|
136
|
+
VERTEX_PLM_API_KEY: f.VERTEX_PLM_API_KEY,
|
|
137
|
+
interactive: f.interactive,
|
|
138
|
+
unset: f.unset,
|
|
139
|
+
reset: f.reset,
|
|
140
|
+
show: f.show,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.default = Configure;
|
|
145
|
+
Configure.description = `Manage config at ${(0, config_1.getConfigPath)()} (env vars override config at runtime)`;
|
|
146
|
+
Configure.flags = Object.assign(Object.assign({}, base_1.default.flags), { VERTEX_CLIENT_ID: command_1.flags.string({ description: 'Vertex client id' }), VERTEX_CLIENT_SECRET: command_1.flags.string({ description: 'Vertex client secret' }), VERTEX_API_HOST: command_1.flags.string({
|
|
147
|
+
description: 'Vertex API host (e.g. https://api.example.com)',
|
|
148
|
+
}), VERTEX_PLM_HOST: command_1.flags.string({
|
|
149
|
+
description: 'Vertex PLM host (e.g. https://plm.example.com)',
|
|
150
|
+
}), VERTEX_PLM_API_KEY: command_1.flags.string({ description: 'Vertex PLM API key' }), interactive: command_1.flags.boolean({
|
|
151
|
+
description: 'Prompt for missing values (leave blank to keep current)',
|
|
152
|
+
default: false,
|
|
153
|
+
}), unset: command_1.flags.string({
|
|
154
|
+
multiple: true,
|
|
155
|
+
description: 'Unset one or more config keys',
|
|
156
|
+
}), reset: command_1.flags.boolean({
|
|
157
|
+
description: 'Delete config file and reset all values',
|
|
158
|
+
default: false,
|
|
159
|
+
}), show: command_1.flags.boolean({
|
|
160
|
+
description: 'Show current config (secrets redacted)',
|
|
161
|
+
default: false,
|
|
162
|
+
}) });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import BaseCommand from '../lib/base';
|
|
2
|
+
export default class SetOverwrite extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
name: string;
|
|
6
|
+
required: boolean;
|
|
7
|
+
description: string;
|
|
8
|
+
}[];
|
|
9
|
+
static flags: {
|
|
10
|
+
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const args_1 = require("../lib/args");
|
|
5
|
+
const base_1 = (0, tslib_1.__importDefault)(require("../lib/base"));
|
|
6
|
+
const plm_api_1 = require("../lib/plm-api");
|
|
7
|
+
const vertex_api_1 = require("../lib/vertex-api");
|
|
8
|
+
class SetOverwrite extends base_1.default {
|
|
9
|
+
async run() {
|
|
10
|
+
const { args } = this.parse(SetOverwrite);
|
|
11
|
+
const ids = (0, args_1.parsePlmIds)({
|
|
12
|
+
plmPartId: args.plmPartId,
|
|
13
|
+
plmRevisionId: args.plmRevisionId,
|
|
14
|
+
plmIterationId: args.plmIterationId,
|
|
15
|
+
});
|
|
16
|
+
console.log('Applying overwrite policy for the following IDs and any instance children:');
|
|
17
|
+
console.log(JSON.stringify(ids, null, 2));
|
|
18
|
+
const registeredPart = await (0, plm_api_1.findRegisteredPartRevision)({
|
|
19
|
+
partId: ids.plmPartId,
|
|
20
|
+
partRevisionId: ids.plmRevisionId,
|
|
21
|
+
iterationId: ids.plmIterationId,
|
|
22
|
+
});
|
|
23
|
+
if (registeredPart === null) {
|
|
24
|
+
console.log('Part revision not found in PLM.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
console.log('Found registered part revision in PLM:');
|
|
28
|
+
console.log(JSON.stringify(registeredPart, null, 2));
|
|
29
|
+
console.log('Fetching related part revision structure data from the platform...');
|
|
30
|
+
const partRevisions = await (0, vertex_api_1.getUniquePartRevisionsForInstanceTree)(registeredPart.vertexPartRevisionId);
|
|
31
|
+
console.log(`Found total of ${partRevisions.length} unique related part revisions in the platform.`);
|
|
32
|
+
await Promise.all(partRevisions.map(async (pr) => {
|
|
33
|
+
const suppliedPartId = pr.part.attributes.suppliedId;
|
|
34
|
+
const suppliedRevisionId = pr.partRevision.attributes.suppliedId;
|
|
35
|
+
if (!suppliedPartId || !suppliedRevisionId) {
|
|
36
|
+
console.warn(`Skipping part revision with missing supplied IDs. [Part: ${suppliedPartId}, Revision: ${suppliedRevisionId}]`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const partToOverwrite = await (0, plm_api_1.findRegisteredPartRevision)({
|
|
40
|
+
partId: suppliedPartId,
|
|
41
|
+
partRevisionId: suppliedRevisionId,
|
|
42
|
+
});
|
|
43
|
+
if (partToOverwrite === null || partToOverwrite === undefined) {
|
|
44
|
+
console.warn(`Registered part revision not found in PLM for referenced part revision. [Part: ${pr.part.attributes.suppliedId}, Revision: ${pr.partRevision.attributes.suppliedId}]`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.log(`Setting Part Revision to Overwrite. [Part: ${pr.part.attributes.suppliedId}, Revision: ${pr.partRevision.attributes.suppliedId}, RPR: ${partToOverwrite.id}]`);
|
|
48
|
+
await (0, plm_api_1.setOverwritePolicy)({
|
|
49
|
+
registeredPartRevisionId: partToOverwrite.id,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}));
|
|
53
|
+
console.log(`Completed setting all related part revisions to overwrite. (${partRevisions.length} revisions processed.)`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.default = SetOverwrite;
|
|
57
|
+
SetOverwrite.description = 'Set overwrite flag for a given part revision';
|
|
58
|
+
SetOverwrite.args = [
|
|
59
|
+
{
|
|
60
|
+
name: 'plmPartId',
|
|
61
|
+
required: true,
|
|
62
|
+
description: 'PLM part ID (string)',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'plmRevisionId',
|
|
66
|
+
required: true,
|
|
67
|
+
description: 'PLM revision ID (string)',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'plmIterationId',
|
|
71
|
+
required: false,
|
|
72
|
+
description: 'PLM iteration ID (string, optional)',
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
SetOverwrite.flags = Object.assign({}, base_1.default.flags);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import BaseCommand from '../lib/base';
|
|
2
|
+
export default class ViewPartJobs extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
name: string;
|
|
6
|
+
required: boolean;
|
|
7
|
+
description: string;
|
|
8
|
+
}[];
|
|
9
|
+
static flags: {
|
|
10
|
+
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|