@bussolabs/closeyourit-cli 0.14.0 → 0.15.0
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 +14 -0
- package/dist/commands/matrix/categories/create.d.ts +13 -0
- package/dist/commands/matrix/categories/create.js +33 -0
- package/dist/commands/matrix/categories/delete.d.ts +13 -0
- package/dist/commands/matrix/categories/delete.js +27 -0
- package/dist/commands/matrix/categories/list.d.ts +12 -0
- package/dist/commands/matrix/categories/list.js +27 -0
- package/dist/commands/matrix/categories/update.d.ts +14 -0
- package/dist/commands/matrix/categories/update.js +37 -0
- package/dist/commands/matrix/cells/clear.d.ts +18 -0
- package/dist/commands/matrix/cells/clear.js +34 -0
- package/dist/commands/matrix/cells/set.d.ts +15 -0
- package/dist/commands/matrix/cells/set.js +42 -0
- package/dist/commands/matrix/features/create.d.ts +16 -0
- package/dist/commands/matrix/features/create.js +40 -0
- package/dist/commands/matrix/features/delete.d.ts +13 -0
- package/dist/commands/matrix/features/delete.js +27 -0
- package/dist/commands/matrix/features/list.d.ts +13 -0
- package/dist/commands/matrix/features/list.js +35 -0
- package/dist/commands/matrix/features/show.d.ts +10 -0
- package/dist/commands/matrix/features/show.js +33 -0
- package/dist/commands/matrix/features/update.d.ts +17 -0
- package/dist/commands/matrix/features/update.js +45 -0
- package/dist/commands/matrix/list.d.ts +9 -0
- package/dist/commands/matrix/list.js +18 -0
- package/dist/commands/matrix/show.d.ts +16 -0
- package/dist/commands/matrix/show.js +63 -0
- package/dist/commands/matrix/statuses.d.ts +6 -0
- package/dist/commands/matrix/statuses.js +22 -0
- package/oclif.manifest.json +4525 -3775
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -167,6 +167,20 @@ CLOSEYOURIT_TOKEN=cyi_u_… CLOSEYOURIT_API_URL=https://www.closeyour.it \
|
|
|
167
167
|
| `analytics goals create --project <id\|key> --kind pageview_path\|custom_event --display-name <name> [--event-name] [--path-pattern]` | Create a conversion goal. |
|
|
168
168
|
| `analytics goals delete <id> --project <id\|key> --confirm` | Delete a conversion goal. |
|
|
169
169
|
| `releases list --project <id\|key> [--page]` | List a project's releases (tracked from CI). |
|
|
170
|
+
| `matrix list [--page]` | List the products whose feature × platform matrix you can see. |
|
|
171
|
+
| `matrix show <product>` | Show the matrix: features in rows, platforms in columns, `status version` per cell (`-` = not set, `?` = released without a version). |
|
|
172
|
+
| `matrix statuses` | List the cell statuses of your org (the codes `matrix cells set` accepts). |
|
|
173
|
+
| `matrix categories list <product> [--page]` | List the feature groups of a product. |
|
|
174
|
+
| `matrix categories create <product> --name <name> [--position]` | Create a feature group. |
|
|
175
|
+
| `matrix categories update <product> <id\|name> [--name] [--position]` | Update a feature group (unpassed fields keep their value). |
|
|
176
|
+
| `matrix categories delete <product> <id\|name> --confirm` | Delete a feature group (only when empty). |
|
|
177
|
+
| `matrix features list <product> [--category] [--page]` | List the features; the REFERENCE column is the `Category/Name` form the other commands take. |
|
|
178
|
+
| `matrix features show <product> <id\|"Category/Name">` | Show one feature and the cells written for it. |
|
|
179
|
+
| `matrix features create <product> --category <id\|name> --name <name> [--description] [--position] [--knowledge-page]` | Create a feature (a row of the matrix). |
|
|
180
|
+
| `matrix features update <product> <id\|"Category/Name"> [--name] [--description] [--position] [--category] [--knowledge-page]` | Update a feature, or move it to another category of the same product. |
|
|
181
|
+
| `matrix features delete <product> <id\|"Category/Name"> --confirm` | Delete a feature and every cell written for it. |
|
|
182
|
+
| `matrix cells set <product> <feature> <platform> --status <code> [--release <version>]` | Write a cell: how far along a feature is on a platform, and since which version. |
|
|
183
|
+
| `matrix cells clear <product> <feature> <platform> --confirm` | Clear a cell: the crossing goes back to "not set". |
|
|
170
184
|
| `alerts channels list` | List the external alert channels (webhook / Telegram). |
|
|
171
185
|
| `alerts channels create <name> --kind telegram\|webhook …` | Create a channel (`--bot-token`/`--chat-id` or `--url`/`--secret`). |
|
|
172
186
|
| `alerts channels delete <id> --confirm` | Delete a channel. |
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixCategoriesCreate extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
position: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<unknown>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixCategoriesCreate extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Create a feature group (category) in a product matrix';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> matrix categories create CloseYourIt --name Auth',
|
|
13
|
+
'<%= config.bin %> matrix categories create CloseYourIt --name Notifications --position 2',
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
name: core_1.Flags.string({ description: 'Category name (unique within the product)', required: true }),
|
|
17
|
+
position: core_1.Flags.integer({ description: 'Sort position' }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(MatrixCategoriesCreate);
|
|
21
|
+
const productId = await this.resolveGroupId(args.product);
|
|
22
|
+
const body = { name: flags.name };
|
|
23
|
+
if (flags.position !== undefined)
|
|
24
|
+
body.position = flags.position;
|
|
25
|
+
const res = await this.api.post(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/categories`, body);
|
|
26
|
+
if (!this.jsonEnabled()) {
|
|
27
|
+
this.log('Category created:');
|
|
28
|
+
this.log((0, output_1.renderRecord)(res.data ?? {}));
|
|
29
|
+
}
|
|
30
|
+
return res;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.default = MatrixCategoriesCreate;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixCategoriesDelete extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
category: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
confirm: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<unknown>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
class MatrixCategoriesDelete extends base_1.BaseCommand {
|
|
6
|
+
static args = {
|
|
7
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
8
|
+
category: core_1.Args.string({ description: 'Category id (UUID) or name', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Delete a feature group (only when empty: move or delete its features first)';
|
|
11
|
+
static examples = ['<%= config.bin %> matrix categories delete CloseYourIt Auth --confirm'];
|
|
12
|
+
static flags = {
|
|
13
|
+
confirm: core_1.Flags.boolean({ description: 'Required: confirm the deletion' }),
|
|
14
|
+
};
|
|
15
|
+
async run() {
|
|
16
|
+
const { args, flags } = await this.parse(MatrixCategoriesDelete);
|
|
17
|
+
if (!flags.confirm) {
|
|
18
|
+
this.error('Refusing to delete without --confirm.', { exit: 2 });
|
|
19
|
+
}
|
|
20
|
+
const productId = await this.resolveGroupId(args.product);
|
|
21
|
+
await this.api.delete(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/categories/${encodeURIComponent(args.category)}`);
|
|
22
|
+
if (!this.jsonEnabled())
|
|
23
|
+
this.log(`Deleted category ${args.category}`);
|
|
24
|
+
return { deleted: args.category };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = MatrixCategoriesDelete;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixCategoriesList extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
page: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<unknown>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixCategoriesList extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'List the feature groups (categories) of a product matrix';
|
|
11
|
+
static examples = ['<%= config.bin %> matrix categories list CloseYourIt'];
|
|
12
|
+
static flags = { ...base_1.pageFlag };
|
|
13
|
+
async run() {
|
|
14
|
+
const { args, flags } = await this.parse(MatrixCategoriesList);
|
|
15
|
+
const productId = await this.resolveGroupId(args.product);
|
|
16
|
+
const res = await this.api.get(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/categories?page=${flags.page}`);
|
|
17
|
+
if (!this.jsonEnabled()) {
|
|
18
|
+
this.log((0, output_1.renderTable)(['NAME', 'POSITION', 'ID'], (res.data ?? []).map((category) => [
|
|
19
|
+
String(category.name ?? ''),
|
|
20
|
+
String(category.position ?? ''),
|
|
21
|
+
String(category.id ?? ''),
|
|
22
|
+
])));
|
|
23
|
+
}
|
|
24
|
+
return res;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = MatrixCategoriesList;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixCategoriesUpdate extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
category: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
position: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<unknown>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixCategoriesUpdate extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
category: core_1.Args.string({ description: 'Category id (UUID) or name', required: true }),
|
|
10
|
+
};
|
|
11
|
+
static description = 'Update a feature group (rename or reorder); unpassed fields keep their value';
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> matrix categories update CloseYourIt Auth --name "Access"',
|
|
14
|
+
'<%= config.bin %> matrix categories update CloseYourIt Auth --position 1',
|
|
15
|
+
];
|
|
16
|
+
static flags = {
|
|
17
|
+
name: core_1.Flags.string({ description: 'New name' }),
|
|
18
|
+
position: core_1.Flags.integer({ description: 'Sort position' }),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
const { args, flags } = await this.parse(MatrixCategoriesUpdate);
|
|
22
|
+
const productId = await this.resolveGroupId(args.product);
|
|
23
|
+
const body = {};
|
|
24
|
+
if (flags.name !== undefined)
|
|
25
|
+
body.name = flags.name;
|
|
26
|
+
if (flags.position !== undefined)
|
|
27
|
+
body.position = flags.position;
|
|
28
|
+
// The backend resolves the category by id-or-name within the product, so pass it through.
|
|
29
|
+
const res = await this.api.put(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/categories/${encodeURIComponent(args.category)}`, body);
|
|
30
|
+
if (!this.jsonEnabled()) {
|
|
31
|
+
this.log('Category updated:');
|
|
32
|
+
this.log((0, output_1.renderRecord)(res.data ?? {}));
|
|
33
|
+
}
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.default = MatrixCategoriesUpdate;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixCellsClear extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
feature: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
platform: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* "Not set" is not the same as "not applicable": the latter is an explicit status you write with
|
|
10
|
+
* `matrix cells set`. Clearing throws away the status and the version, hence --confirm.
|
|
11
|
+
*/
|
|
12
|
+
static description: string;
|
|
13
|
+
static examples: string[];
|
|
14
|
+
static flags: {
|
|
15
|
+
confirm: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<unknown>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
class MatrixCellsClear extends base_1.BaseCommand {
|
|
6
|
+
static args = {
|
|
7
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
8
|
+
feature: core_1.Args.string({ description: 'Feature id (UUID) or "Category/Name"', required: true }),
|
|
9
|
+
platform: core_1.Args.string({ description: 'Platform id (UUID) or code (e.g. web, ios)', required: true }),
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* "Not set" is not the same as "not applicable": the latter is an explicit status you write with
|
|
13
|
+
* `matrix cells set`. Clearing throws away the status and the version, hence --confirm.
|
|
14
|
+
*/
|
|
15
|
+
static description = 'Clear a matrix cell: the crossing goes back to "not set"';
|
|
16
|
+
static examples = ['<%= config.bin %> matrix cells clear CloseYourIt "Auth/2FA" web --confirm'];
|
|
17
|
+
static flags = {
|
|
18
|
+
confirm: core_1.Flags.boolean({ description: 'Required: confirm clearing the cell' }),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
const { args, flags } = await this.parse(MatrixCellsClear);
|
|
22
|
+
if (!flags.confirm) {
|
|
23
|
+
this.error('Refusing to clear without --confirm.', { exit: 2 });
|
|
24
|
+
}
|
|
25
|
+
const productId = await this.resolveGroupId(args.product);
|
|
26
|
+
const path = `/cli/v1/product/matrix/${encodeURIComponent(productId)}` +
|
|
27
|
+
`/features/${encodeURIComponent(args.feature)}/cells/${encodeURIComponent(args.platform)}`;
|
|
28
|
+
await this.api.delete(path);
|
|
29
|
+
if (!this.jsonEnabled())
|
|
30
|
+
this.log(`Cleared ${args.feature} on ${args.platform}`);
|
|
31
|
+
return { cleared: { feature: args.feature, platform: args.platform } };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.default = MatrixCellsClear;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixCellsSet extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
feature: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
platform: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static description: string;
|
|
9
|
+
static examples: string[];
|
|
10
|
+
static flags: {
|
|
11
|
+
status: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
release: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<unknown>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
class MatrixCellsSet extends base_1.BaseCommand {
|
|
6
|
+
static args = {
|
|
7
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
8
|
+
feature: core_1.Args.string({ description: 'Feature id (UUID) or "Category/Name"', required: true }),
|
|
9
|
+
platform: core_1.Args.string({ description: 'Platform id (UUID) or code (e.g. web, ios)', required: true }),
|
|
10
|
+
};
|
|
11
|
+
static description = 'Write a matrix cell: how far along a feature is on a platform, and since which version';
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> matrix cells set CloseYourIt "Auth/2FA" web --status available --release 2.1.0',
|
|
14
|
+
'<%= config.bin %> matrix cells set CloseYourIt "Auth/2FA" ios --status planned',
|
|
15
|
+
];
|
|
16
|
+
static flags = {
|
|
17
|
+
status: core_1.Flags.string({ description: 'Status code (see: matrix statuses) or id', required: true }),
|
|
18
|
+
release: core_1.Flags.string({
|
|
19
|
+
description: 'Version the feature became available in (a registered release of the product on that platform)',
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
const { args, flags } = await this.parse(MatrixCellsSet);
|
|
24
|
+
const productId = await this.resolveGroupId(args.product);
|
|
25
|
+
const body = { status: flags.status };
|
|
26
|
+
if (flags.release !== undefined)
|
|
27
|
+
body.release = flags.release;
|
|
28
|
+
const path = `/cli/v1/product/matrix/${encodeURIComponent(productId)}` +
|
|
29
|
+
`/features/${encodeURIComponent(args.feature)}/cells/${encodeURIComponent(args.platform)}`;
|
|
30
|
+
const res = await this.api.put(path, body);
|
|
31
|
+
if (!this.jsonEnabled()) {
|
|
32
|
+
// What was saved, in the words the command took: status and release are nested objects, so a
|
|
33
|
+
// flat record dump would drop exactly the two values the user just set.
|
|
34
|
+
const cell = res.data ?? {};
|
|
35
|
+
const where = cell.platform_code ?? args.platform;
|
|
36
|
+
const version = cell.release?.version ?? (cell.release_missing ? 'no version set' : 'no version');
|
|
37
|
+
this.log(`Saved: ${args.feature} on ${where} → ${cell.status?.code ?? flags.status} (${version})`);
|
|
38
|
+
}
|
|
39
|
+
return res;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = MatrixCellsSet;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixFeaturesCreate extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
category: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
position: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
'knowledge-page': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
};
|
|
15
|
+
run(): Promise<unknown>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixFeaturesCreate extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Create a feature (a row of the matrix) inside a category';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> matrix features create CloseYourIt --category Auth --name "2FA"',
|
|
13
|
+
'<%= config.bin %> matrix features create CloseYourIt --category Auth --name "Apple login" --knowledge-page <page-id>',
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
category: core_1.Flags.string({ description: 'Category id (UUID) or name', required: true }),
|
|
17
|
+
name: core_1.Flags.string({ description: 'Feature name (unique within the category)', required: true }),
|
|
18
|
+
description: core_1.Flags.string({ description: 'What the feature does' }),
|
|
19
|
+
position: core_1.Flags.integer({ description: 'Sort position' }),
|
|
20
|
+
'knowledge-page': core_1.Flags.string({ description: 'Knowledge page id explaining the feature' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
const { args, flags } = await this.parse(MatrixFeaturesCreate);
|
|
24
|
+
const productId = await this.resolveGroupId(args.product);
|
|
25
|
+
const body = { category: flags.category, name: flags.name };
|
|
26
|
+
if (flags.description !== undefined)
|
|
27
|
+
body.description = flags.description;
|
|
28
|
+
if (flags.position !== undefined)
|
|
29
|
+
body.position = flags.position;
|
|
30
|
+
if (flags['knowledge-page'] !== undefined)
|
|
31
|
+
body.knowledge_page_id = flags['knowledge-page'];
|
|
32
|
+
const res = await this.api.post(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/features`, body);
|
|
33
|
+
if (!this.jsonEnabled()) {
|
|
34
|
+
this.log('Feature created:');
|
|
35
|
+
this.log((0, output_1.renderRecord)(res.data ?? {}));
|
|
36
|
+
}
|
|
37
|
+
return res;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.default = MatrixFeaturesCreate;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixFeaturesDelete extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
feature: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
confirm: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<unknown>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
class MatrixFeaturesDelete extends base_1.BaseCommand {
|
|
6
|
+
static args = {
|
|
7
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
8
|
+
feature: core_1.Args.string({ description: 'Feature id (UUID) or "Category/Name"', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Delete a feature and every cell written for it (irreversible)';
|
|
11
|
+
static examples = ['<%= config.bin %> matrix features delete CloseYourIt "Auth/2FA" --confirm'];
|
|
12
|
+
static flags = {
|
|
13
|
+
confirm: core_1.Flags.boolean({ description: 'Required: confirm the deletion' }),
|
|
14
|
+
};
|
|
15
|
+
async run() {
|
|
16
|
+
const { args, flags } = await this.parse(MatrixFeaturesDelete);
|
|
17
|
+
if (!flags.confirm) {
|
|
18
|
+
this.error('Refusing to delete without --confirm.', { exit: 2 });
|
|
19
|
+
}
|
|
20
|
+
const productId = await this.resolveGroupId(args.product);
|
|
21
|
+
await this.api.delete(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/features/${encodeURIComponent(args.feature)}`);
|
|
22
|
+
if (!this.jsonEnabled())
|
|
23
|
+
this.log(`Deleted feature ${args.feature}`);
|
|
24
|
+
return { deleted: args.feature };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = MatrixFeaturesDelete;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixFeaturesList extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
category: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
page: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<unknown>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixFeaturesList extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'List the features of a product matrix';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> matrix features list CloseYourIt',
|
|
13
|
+
'<%= config.bin %> matrix features list CloseYourIt --category Auth',
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
...base_1.pageFlag,
|
|
17
|
+
category: core_1.Flags.string({ description: 'Only the features of this category (id or name)' }),
|
|
18
|
+
};
|
|
19
|
+
async run() {
|
|
20
|
+
const { args, flags } = await this.parse(MatrixFeaturesList);
|
|
21
|
+
const productId = await this.resolveGroupId(args.product);
|
|
22
|
+
const query = flags.category ? `&category=${encodeURIComponent(flags.category)}` : '';
|
|
23
|
+
const res = await this.api.get(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/features?page=${flags.page}${query}`);
|
|
24
|
+
if (!this.jsonEnabled()) {
|
|
25
|
+
// REFERENCE is the `Category/Name` form every other matrix command accepts.
|
|
26
|
+
this.log((0, output_1.renderTable)(['REFERENCE', 'DESCRIPTION', 'ID'], (res.data ?? []).map((feature) => [
|
|
27
|
+
`${String(feature.category_name ?? '')}/${String(feature.name ?? '')}`,
|
|
28
|
+
String(feature.description ?? ''),
|
|
29
|
+
String(feature.id ?? ''),
|
|
30
|
+
])));
|
|
31
|
+
}
|
|
32
|
+
return res;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = MatrixFeaturesList;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixFeaturesShow extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
feature: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
run(): Promise<unknown>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixFeaturesShow extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
feature: core_1.Args.string({ description: 'Feature id (UUID) or "Category/Name"', required: true }),
|
|
10
|
+
};
|
|
11
|
+
static description = 'Show one feature and the cells written for it';
|
|
12
|
+
static examples = ['<%= config.bin %> matrix features show CloseYourIt "Auth/2FA"'];
|
|
13
|
+
async run() {
|
|
14
|
+
const { args } = await this.parse(MatrixFeaturesShow);
|
|
15
|
+
const productId = await this.resolveGroupId(args.product);
|
|
16
|
+
const res = await this.api.get(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/features/${encodeURIComponent(args.feature)}`);
|
|
17
|
+
if (!this.jsonEnabled()) {
|
|
18
|
+
const { cells, ...feature } = res.data ?? {};
|
|
19
|
+
this.log((0, output_1.renderRecord)(feature));
|
|
20
|
+
const rows = cells ?? [];
|
|
21
|
+
if (rows.length > 0) {
|
|
22
|
+
this.log('');
|
|
23
|
+
this.log((0, output_1.renderTable)(['PLATFORM', 'STATUS', 'VERSION'], rows.map((cell) => [
|
|
24
|
+
String(cell.platform_code ?? cell.platform_id ?? ''),
|
|
25
|
+
String(cell.status?.code ?? ''),
|
|
26
|
+
cell.release?.version ? String(cell.release.version) : cell.release_missing ? '?' : '-',
|
|
27
|
+
])));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return res;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.default = MatrixFeaturesShow;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base';
|
|
2
|
+
export default class MatrixFeaturesUpdate extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
feature: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
position: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
category: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
'knowledge-page': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
};
|
|
16
|
+
run(): Promise<unknown>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../../../base");
|
|
5
|
+
const output_1 = require("../../../lib/output");
|
|
6
|
+
class MatrixFeaturesUpdate extends base_1.BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
product: core_1.Args.string({ description: 'Product id (UUID) or group name', required: true }),
|
|
9
|
+
feature: core_1.Args.string({ description: 'Feature id (UUID) or "Category/Name"', required: true }),
|
|
10
|
+
};
|
|
11
|
+
static description = 'Update a feature (rename, move to another category, …); unpassed fields keep their value';
|
|
12
|
+
static examples = [
|
|
13
|
+
'<%= config.bin %> matrix features update CloseYourIt "Auth/2FA" --name "Two-factor"',
|
|
14
|
+
'<%= config.bin %> matrix features update CloseYourIt "Auth/2FA" --category Notifications',
|
|
15
|
+
];
|
|
16
|
+
static flags = {
|
|
17
|
+
name: core_1.Flags.string({ description: 'New name' }),
|
|
18
|
+
description: core_1.Flags.string({ description: 'What the feature does' }),
|
|
19
|
+
position: core_1.Flags.integer({ description: 'Sort position' }),
|
|
20
|
+
category: core_1.Flags.string({ description: 'Move it to this category (id or name, same product)' }),
|
|
21
|
+
'knowledge-page': core_1.Flags.string({ description: 'Knowledge page id explaining the feature' }),
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
const { args, flags } = await this.parse(MatrixFeaturesUpdate);
|
|
25
|
+
const productId = await this.resolveGroupId(args.product);
|
|
26
|
+
const body = {};
|
|
27
|
+
if (flags.name !== undefined)
|
|
28
|
+
body.name = flags.name;
|
|
29
|
+
if (flags.description !== undefined)
|
|
30
|
+
body.description = flags.description;
|
|
31
|
+
if (flags.position !== undefined)
|
|
32
|
+
body.position = flags.position;
|
|
33
|
+
if (flags.category !== undefined)
|
|
34
|
+
body.category = flags.category;
|
|
35
|
+
if (flags['knowledge-page'] !== undefined)
|
|
36
|
+
body.knowledge_page_id = flags['knowledge-page'];
|
|
37
|
+
const res = await this.api.put(`/cli/v1/product/matrix/${encodeURIComponent(productId)}/features/${encodeURIComponent(args.feature)}`, body);
|
|
38
|
+
if (!this.jsonEnabled()) {
|
|
39
|
+
this.log('Feature updated:');
|
|
40
|
+
this.log((0, output_1.renderRecord)(res.data ?? {}));
|
|
41
|
+
}
|
|
42
|
+
return res;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.default = MatrixFeaturesUpdate;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base';
|
|
2
|
+
export default class MatrixList extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
page: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<unknown>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const base_1 = require("../../base");
|
|
4
|
+
const output_1 = require("../../lib/output");
|
|
5
|
+
class MatrixList extends base_1.BaseCommand {
|
|
6
|
+
static description = 'List the products (groups) whose feature matrix you can see';
|
|
7
|
+
static examples = ['<%= config.bin %> matrix list', '<%= config.bin %> matrix list --page 2 --json'];
|
|
8
|
+
static flags = { ...base_1.pageFlag };
|
|
9
|
+
async run() {
|
|
10
|
+
const { flags } = await this.parse(MatrixList);
|
|
11
|
+
const res = await this.api.get(`/cli/v1/product/matrix?page=${flags.page}`);
|
|
12
|
+
if (!this.jsonEnabled()) {
|
|
13
|
+
this.log((0, output_1.renderTable)(['NAME', 'ID'], (res.data ?? []).map((product) => [String(product.name ?? ''), String(product.id ?? '')])));
|
|
14
|
+
}
|
|
15
|
+
return res;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = MatrixList;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base';
|
|
2
|
+
export default class MatrixShow extends BaseCommand {
|
|
3
|
+
static args: {
|
|
4
|
+
product: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
run(): Promise<unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* The first column holds `Category/Feature` — the very reference `matrix cells set` and
|
|
11
|
+
* `matrix features` take, so a row can be acted on without a second lookup.
|
|
12
|
+
*/
|
|
13
|
+
private renderMatrix;
|
|
14
|
+
/** `-` = not set (different from an explicit "not applicable" status, which has its own code). */
|
|
15
|
+
private renderCell;
|
|
16
|
+
}
|