@pmate/cli 0.21.18 → 0.22.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/dist/index.d.ts +31 -0
- package/dist/index.js +456 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -349,6 +349,23 @@ type RoleCommandArgs = {
|
|
|
349
349
|
json: boolean;
|
|
350
350
|
};
|
|
351
351
|
type AccountCommandArgs = {
|
|
352
|
+
type: Command.Account;
|
|
353
|
+
action: "list";
|
|
354
|
+
page?: number;
|
|
355
|
+
pageSize?: number;
|
|
356
|
+
mobile?: string;
|
|
357
|
+
nickName?: string;
|
|
358
|
+
baseUrl?: string;
|
|
359
|
+
json: boolean;
|
|
360
|
+
} | {
|
|
361
|
+
type: Command.Account;
|
|
362
|
+
action: "app-users";
|
|
363
|
+
app: string;
|
|
364
|
+
page?: number;
|
|
365
|
+
pageSize?: number;
|
|
366
|
+
baseUrl?: string;
|
|
367
|
+
json: boolean;
|
|
368
|
+
} | {
|
|
352
369
|
type: Command.Account;
|
|
353
370
|
action: "view";
|
|
354
371
|
account?: string;
|
|
@@ -721,6 +738,7 @@ type AppCommandArgs = {
|
|
|
721
738
|
type: Command.App;
|
|
722
739
|
action: "icon";
|
|
723
740
|
id: string;
|
|
741
|
+
subAction?: "export";
|
|
724
742
|
preset?: "android" | "ios";
|
|
725
743
|
width?: number;
|
|
726
744
|
height?: number;
|
|
@@ -729,6 +747,19 @@ type AppCommandArgs = {
|
|
|
729
747
|
outDir?: string;
|
|
730
748
|
baseUrl?: string;
|
|
731
749
|
json: boolean;
|
|
750
|
+
} | {
|
|
751
|
+
type: Command.App;
|
|
752
|
+
action: "icon-add";
|
|
753
|
+
id: string;
|
|
754
|
+
name: string;
|
|
755
|
+
filePath?: string;
|
|
756
|
+
width?: number;
|
|
757
|
+
height?: number;
|
|
758
|
+
format?: "png" | "webp" | "svg" | "ico";
|
|
759
|
+
output?: string;
|
|
760
|
+
force: boolean;
|
|
761
|
+
baseUrl?: string;
|
|
762
|
+
json: boolean;
|
|
732
763
|
};
|
|
733
764
|
type ServiceCommandArgs = {
|
|
734
765
|
type: Command.Service;
|
package/dist/index.js
CHANGED
|
@@ -17252,6 +17252,8 @@ var IOS_ICON_SPECS = [
|
|
|
17252
17252
|
{ width: 1024, height: 1024, name: "app-store" }
|
|
17253
17253
|
];
|
|
17254
17254
|
var pngToIco = require("png-to-ico").default;
|
|
17255
|
+
var APP_ICON_VARIANT_KEY_PATTERN = /^[a-z0-9]+$/;
|
|
17256
|
+
var DATA_URL_PATTERN = /^data:([^;,]+);base64,([a-z0-9+/=]+)$/i;
|
|
17255
17257
|
function normalizeAppIcon(icon, cwd) {
|
|
17256
17258
|
if (typeof icon !== "string" || !icon.trim()) {
|
|
17257
17259
|
throw new Error("App icon must be a non-empty http(s) URL.");
|
|
@@ -17276,8 +17278,46 @@ function prepareAppPayload(payload, cwd) {
|
|
|
17276
17278
|
if (normalized.icon !== void 0) {
|
|
17277
17279
|
normalized.icon = normalizeAppIcon(normalized.icon, cwd);
|
|
17278
17280
|
}
|
|
17281
|
+
if (normalized.icons !== void 0) {
|
|
17282
|
+
normalized.icons = normalizeAppIconVariants(normalized.icons);
|
|
17283
|
+
}
|
|
17279
17284
|
return normalized;
|
|
17280
17285
|
}
|
|
17286
|
+
function normalizeAppIconVariants(input) {
|
|
17287
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
17288
|
+
throw new Error("App icons must be an object map of variant names to asset references.");
|
|
17289
|
+
}
|
|
17290
|
+
const entries = Object.entries(input);
|
|
17291
|
+
const normalized = Object.fromEntries(
|
|
17292
|
+
entries.map(([key, value]) => [validateAppIconVariantKey(key), normalizeAppIconVariantValue(value)])
|
|
17293
|
+
);
|
|
17294
|
+
return normalized;
|
|
17295
|
+
}
|
|
17296
|
+
function validateAppIconVariantKey(key) {
|
|
17297
|
+
const trimmed = key.trim();
|
|
17298
|
+
if (!trimmed) {
|
|
17299
|
+
throw new Error("App icon variant name is required.");
|
|
17300
|
+
}
|
|
17301
|
+
if (!APP_ICON_VARIANT_KEY_PATTERN.test(trimmed)) {
|
|
17302
|
+
throw new Error(
|
|
17303
|
+
`Invalid app icon variant name "${key}". Use lowercase letters and digits only, for example webp512x512.`
|
|
17304
|
+
);
|
|
17305
|
+
}
|
|
17306
|
+
return trimmed;
|
|
17307
|
+
}
|
|
17308
|
+
function normalizeAppIconVariantValue(value) {
|
|
17309
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
17310
|
+
throw new Error("App icon variant value must be a non-empty URL or image data URL.");
|
|
17311
|
+
}
|
|
17312
|
+
const trimmed = value.trim();
|
|
17313
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
17314
|
+
return trimmed;
|
|
17315
|
+
}
|
|
17316
|
+
if (isSupportedImageDataUrl(trimmed)) {
|
|
17317
|
+
return trimmed;
|
|
17318
|
+
}
|
|
17319
|
+
throw new Error("App icon variant value must be an http(s) URL or a supported image data URL.");
|
|
17320
|
+
}
|
|
17281
17321
|
function createAppIconExportPlans(input) {
|
|
17282
17322
|
const { namespace, objectId } = parseNamespacedRef(input.id, {
|
|
17283
17323
|
entityLabel: "app ref"
|
|
@@ -17324,6 +17364,30 @@ async function exportAppIcon(icon, plans) {
|
|
|
17324
17364
|
(0, import_node_fs15.writeFileSync)(plan.outputPath, bytes);
|
|
17325
17365
|
}
|
|
17326
17366
|
}
|
|
17367
|
+
async function renderAppIconVariant(input) {
|
|
17368
|
+
const svg = await resolveAppIconSvg(input.icon);
|
|
17369
|
+
const bytes = await renderAppIcon(svg, input.width, input.height, input.format);
|
|
17370
|
+
let outputPath;
|
|
17371
|
+
if (input.output) {
|
|
17372
|
+
outputPath = import_node_path20.default.resolve(input.cwd, input.output);
|
|
17373
|
+
(0, import_node_fs15.mkdirSync)(import_node_path20.default.dirname(outputPath), { recursive: true });
|
|
17374
|
+
(0, import_node_fs15.writeFileSync)(outputPath, bytes);
|
|
17375
|
+
}
|
|
17376
|
+
return {
|
|
17377
|
+
value: createImageDataUrl(bytes, input.format),
|
|
17378
|
+
...outputPath ? { outputPath } : {}
|
|
17379
|
+
};
|
|
17380
|
+
}
|
|
17381
|
+
function loadAppIconVariantFile(filePath, cwd) {
|
|
17382
|
+
const absolutePath = import_node_path20.default.resolve(cwd, filePath);
|
|
17383
|
+
const format = inferVariantFormatFromPath(absolutePath);
|
|
17384
|
+
const bytes = (0, import_node_fs15.readFileSync)(absolutePath);
|
|
17385
|
+
return {
|
|
17386
|
+
value: createImageDataUrl(bytes, format),
|
|
17387
|
+
format,
|
|
17388
|
+
absolutePath
|
|
17389
|
+
};
|
|
17390
|
+
}
|
|
17327
17391
|
async function resolveAppIconSvg(icon) {
|
|
17328
17392
|
const trimmed = icon.trim();
|
|
17329
17393
|
if (looksLikeSvgMarkup(trimmed)) {
|
|
@@ -17366,6 +17430,44 @@ async function renderAppIcon(svg, width, height, format) {
|
|
|
17366
17430
|
function looksLikeSvgMarkup(value) {
|
|
17367
17431
|
return /<svg[\s>]/i.test(value);
|
|
17368
17432
|
}
|
|
17433
|
+
function inferVariantFormatFromPath(filePath) {
|
|
17434
|
+
const ext = import_node_path20.default.extname(filePath).toLowerCase();
|
|
17435
|
+
switch (ext) {
|
|
17436
|
+
case ".png":
|
|
17437
|
+
return "png";
|
|
17438
|
+
case ".webp":
|
|
17439
|
+
return "webp";
|
|
17440
|
+
case ".svg":
|
|
17441
|
+
return "svg";
|
|
17442
|
+
case ".ico":
|
|
17443
|
+
return "ico";
|
|
17444
|
+
default:
|
|
17445
|
+
throw new Error(`Unsupported app icon variant file extension "${ext || "(none)"}". Use .png, .webp, .svg, or .ico.`);
|
|
17446
|
+
}
|
|
17447
|
+
}
|
|
17448
|
+
function createImageDataUrl(bytes, format) {
|
|
17449
|
+
return `data:${mimeTypeForIconFormat(format)};base64,${bytes.toString("base64")}`;
|
|
17450
|
+
}
|
|
17451
|
+
function mimeTypeForIconFormat(format) {
|
|
17452
|
+
switch (format) {
|
|
17453
|
+
case "png":
|
|
17454
|
+
return "image/png";
|
|
17455
|
+
case "webp":
|
|
17456
|
+
return "image/webp";
|
|
17457
|
+
case "svg":
|
|
17458
|
+
return "image/svg+xml";
|
|
17459
|
+
case "ico":
|
|
17460
|
+
return "image/x-icon";
|
|
17461
|
+
}
|
|
17462
|
+
}
|
|
17463
|
+
function isSupportedImageDataUrl(value) {
|
|
17464
|
+
const match = value.match(DATA_URL_PATTERN);
|
|
17465
|
+
if (!match) {
|
|
17466
|
+
return false;
|
|
17467
|
+
}
|
|
17468
|
+
const mimeType = match[1]?.toLowerCase();
|
|
17469
|
+
return mimeType === "image/png" || mimeType === "image/webp" || mimeType === "image/svg+xml" || mimeType === "image/x-icon";
|
|
17470
|
+
}
|
|
17369
17471
|
|
|
17370
17472
|
// src/commands/AppCommandHandler.ts
|
|
17371
17473
|
init_namespacedRef();
|
|
@@ -17399,7 +17501,11 @@ var AppCommandHandler = class {
|
|
|
17399
17501
|
"GET",
|
|
17400
17502
|
pathname
|
|
17401
17503
|
);
|
|
17402
|
-
|
|
17504
|
+
if (args.action === "view") {
|
|
17505
|
+
this.renderView(record);
|
|
17506
|
+
} else {
|
|
17507
|
+
this.renderJson(record, true);
|
|
17508
|
+
}
|
|
17403
17509
|
return;
|
|
17404
17510
|
}
|
|
17405
17511
|
case "create": {
|
|
@@ -17463,6 +17569,46 @@ var AppCommandHandler = class {
|
|
|
17463
17569
|
);
|
|
17464
17570
|
return;
|
|
17465
17571
|
}
|
|
17572
|
+
case "icon-add": {
|
|
17573
|
+
const pathname = this.buildAppPath(args.id);
|
|
17574
|
+
const record = await this.request(
|
|
17575
|
+
baseUrl,
|
|
17576
|
+
token,
|
|
17577
|
+
"GET",
|
|
17578
|
+
pathname
|
|
17579
|
+
);
|
|
17580
|
+
const name = validateAppIconVariantKey(args.name);
|
|
17581
|
+
const existingIcons = record.icons || {};
|
|
17582
|
+
if (existingIcons[name] && !args.force) {
|
|
17583
|
+
throw new Error(`App icon variant "${name}" already exists for ${args.id}. Re-run with --force to overwrite it.`);
|
|
17584
|
+
}
|
|
17585
|
+
const source = args.filePath ? loadAppIconVariantFile(args.filePath, process.cwd()) : await this.renderIconVariantFromApp(record, args);
|
|
17586
|
+
const updatedIcons = {
|
|
17587
|
+
...existingIcons,
|
|
17588
|
+
[name]: source.value
|
|
17589
|
+
};
|
|
17590
|
+
const updatedRecord = await this.request(
|
|
17591
|
+
baseUrl,
|
|
17592
|
+
token,
|
|
17593
|
+
"PUT",
|
|
17594
|
+
pathname,
|
|
17595
|
+
{
|
|
17596
|
+
icons: updatedIcons
|
|
17597
|
+
}
|
|
17598
|
+
);
|
|
17599
|
+
ui.success(`Updated icon variant ${name} for ${args.id}`);
|
|
17600
|
+
this.renderJson(
|
|
17601
|
+
{
|
|
17602
|
+
id: args.id,
|
|
17603
|
+
name,
|
|
17604
|
+
..."absolutePath" in source ? { filePath: source.absolutePath } : {},
|
|
17605
|
+
..."outputPath" in source && source.outputPath ? { outputPath: source.outputPath } : {},
|
|
17606
|
+
icons: updatedRecord.icons || updatedIcons
|
|
17607
|
+
},
|
|
17608
|
+
args.json
|
|
17609
|
+
);
|
|
17610
|
+
return;
|
|
17611
|
+
}
|
|
17466
17612
|
case "delete": {
|
|
17467
17613
|
const pathname = this.buildAppPath(args.id);
|
|
17468
17614
|
const record = await this.request(
|
|
@@ -17593,12 +17739,53 @@ var AppCommandHandler = class {
|
|
|
17593
17739
|
}
|
|
17594
17740
|
ui.plain(JSON.stringify(value, null, 2));
|
|
17595
17741
|
}
|
|
17742
|
+
renderView(record) {
|
|
17743
|
+
const appId = formatNamespacedDisplayId(record.namespace, record.id);
|
|
17744
|
+
ui.plain(`App: ${appId}`);
|
|
17745
|
+
ui.plain(`Name: ${record.name}`);
|
|
17746
|
+
ui.plain(`Status: ${record.status}`);
|
|
17747
|
+
if (record.icon) {
|
|
17748
|
+
ui.plain(`Icon: ${record.icon}`);
|
|
17749
|
+
}
|
|
17750
|
+
if (record.icons && Object.keys(record.icons).length > 0) {
|
|
17751
|
+
ui.plain("Icons:");
|
|
17752
|
+
for (const [name, value] of Object.entries(record.icons).sort(
|
|
17753
|
+
([left], [right]) => left.localeCompare(right)
|
|
17754
|
+
)) {
|
|
17755
|
+
ui.plain(` ${name}: ${value}`);
|
|
17756
|
+
}
|
|
17757
|
+
}
|
|
17758
|
+
if (record.deploys && Object.keys(record.deploys).length > 0) {
|
|
17759
|
+
ui.plain("Deploys:");
|
|
17760
|
+
for (const [platform, serviceRef] of Object.entries(record.deploys)) {
|
|
17761
|
+
if (serviceRef) {
|
|
17762
|
+
ui.plain(` ${platform}: ${serviceRef}`);
|
|
17763
|
+
}
|
|
17764
|
+
}
|
|
17765
|
+
}
|
|
17766
|
+
}
|
|
17596
17767
|
buildAppPath(appId) {
|
|
17597
17768
|
const { namespace, objectId } = parseNamespacedRef(appId, {
|
|
17598
17769
|
entityLabel: "app ref"
|
|
17599
17770
|
});
|
|
17600
17771
|
return `/apps/${encodeURIComponent(namespace)}/${encodeURIComponent(objectId)}`;
|
|
17601
17772
|
}
|
|
17773
|
+
async renderIconVariantFromApp(record, args) {
|
|
17774
|
+
if (!record.icon) {
|
|
17775
|
+
throw new Error(`App icon is missing for ${args.id}`);
|
|
17776
|
+
}
|
|
17777
|
+
if (!args.width || !args.height) {
|
|
17778
|
+
throw new Error("App icon add export requires an explicit size.");
|
|
17779
|
+
}
|
|
17780
|
+
return renderAppIconVariant({
|
|
17781
|
+
icon: record.icon,
|
|
17782
|
+
width: args.width,
|
|
17783
|
+
height: args.height,
|
|
17784
|
+
format: args.format || "png",
|
|
17785
|
+
output: args.output,
|
|
17786
|
+
cwd: process.cwd()
|
|
17787
|
+
});
|
|
17788
|
+
}
|
|
17602
17789
|
};
|
|
17603
17790
|
function readNamespaceFromPayload(payload) {
|
|
17604
17791
|
if (!payload || typeof payload !== "object") {
|
|
@@ -19221,6 +19408,28 @@ var AccountCommandHandler = class {
|
|
|
19221
19408
|
async handle(args) {
|
|
19222
19409
|
const token = this.readToken();
|
|
19223
19410
|
switch (args.action) {
|
|
19411
|
+
case "list": {
|
|
19412
|
+
const baseUrl = this.resolveAuthBaseUrl(args.baseUrl);
|
|
19413
|
+
const result = await this.request(
|
|
19414
|
+
baseUrl,
|
|
19415
|
+
token,
|
|
19416
|
+
"GET",
|
|
19417
|
+
`/accounts?${this.buildAccountListQuery(args)}`
|
|
19418
|
+
);
|
|
19419
|
+
this.renderAccountList(result, args.json);
|
|
19420
|
+
return;
|
|
19421
|
+
}
|
|
19422
|
+
case "app-users": {
|
|
19423
|
+
const baseUrl = this.resolveAuthBaseUrl(args.baseUrl);
|
|
19424
|
+
const result = await this.request(
|
|
19425
|
+
baseUrl,
|
|
19426
|
+
token,
|
|
19427
|
+
"GET",
|
|
19428
|
+
`/accounts/app-users/${encodeURIComponent(args.app)}?${this.buildPagedQuery(args)}`
|
|
19429
|
+
);
|
|
19430
|
+
this.renderAccountAppUsers(result, args.json);
|
|
19431
|
+
return;
|
|
19432
|
+
}
|
|
19224
19433
|
case "view": {
|
|
19225
19434
|
const baseUrl = this.resolveAuthBaseUrl(args.baseUrl);
|
|
19226
19435
|
const result = await this.request(
|
|
@@ -19362,6 +19571,20 @@ var AccountCommandHandler = class {
|
|
|
19362
19571
|
if (args.nickName) params.set("nickName", args.nickName);
|
|
19363
19572
|
return params.toString();
|
|
19364
19573
|
}
|
|
19574
|
+
buildAccountListQuery(args) {
|
|
19575
|
+
const params = new URLSearchParams();
|
|
19576
|
+
if (args.page) params.set("page", String(args.page));
|
|
19577
|
+
if (args.pageSize) params.set("pageSize", String(args.pageSize));
|
|
19578
|
+
if (args.mobile) params.set("mobile", args.mobile);
|
|
19579
|
+
if (args.nickName) params.set("nickName", args.nickName);
|
|
19580
|
+
return params.toString();
|
|
19581
|
+
}
|
|
19582
|
+
buildPagedQuery(args) {
|
|
19583
|
+
const params = new URLSearchParams();
|
|
19584
|
+
if (args.page) params.set("page", String(args.page));
|
|
19585
|
+
if (args.pageSize) params.set("pageSize", String(args.pageSize));
|
|
19586
|
+
return params.toString();
|
|
19587
|
+
}
|
|
19365
19588
|
buildRoleBindingsQuery(args) {
|
|
19366
19589
|
const params = new URLSearchParams();
|
|
19367
19590
|
params.set("account", args.account);
|
|
@@ -19440,6 +19663,44 @@ var AccountCommandHandler = class {
|
|
|
19440
19663
|
});
|
|
19441
19664
|
}
|
|
19442
19665
|
}
|
|
19666
|
+
renderAccountList(result, asJson) {
|
|
19667
|
+
if (asJson) {
|
|
19668
|
+
ui.plain(JSON.stringify(result, null, 2));
|
|
19669
|
+
return;
|
|
19670
|
+
}
|
|
19671
|
+
this.renderAccountView(result.items, false);
|
|
19672
|
+
if (result.items.length > 0) {
|
|
19673
|
+
ui.info(`page ${result.page}`, {
|
|
19674
|
+
pageSize: result.pageSize,
|
|
19675
|
+
totalPages: result.totalPages,
|
|
19676
|
+
hasNext: result.hasNext
|
|
19677
|
+
});
|
|
19678
|
+
}
|
|
19679
|
+
}
|
|
19680
|
+
renderAccountAppUsers(result, asJson) {
|
|
19681
|
+
if (asJson) {
|
|
19682
|
+
ui.plain(JSON.stringify(result, null, 2));
|
|
19683
|
+
return;
|
|
19684
|
+
}
|
|
19685
|
+
if (result.items.length === 0) {
|
|
19686
|
+
ui.warn("No app users found.");
|
|
19687
|
+
return;
|
|
19688
|
+
}
|
|
19689
|
+
for (const item of result.items) {
|
|
19690
|
+
ui.info(item.account.id, {
|
|
19691
|
+
mobile: item.account.mobile,
|
|
19692
|
+
nickNames: item.nickNames,
|
|
19693
|
+
roles: item.roles.map((role) => `${role.namespace}/${role.role}`),
|
|
19694
|
+
sources: item.sources
|
|
19695
|
+
});
|
|
19696
|
+
}
|
|
19697
|
+
ui.info(`page ${result.page}`, {
|
|
19698
|
+
pageSize: result.pageSize,
|
|
19699
|
+
total: result.total,
|
|
19700
|
+
totalPages: result.totalPages,
|
|
19701
|
+
hasNext: result.hasNext
|
|
19702
|
+
});
|
|
19703
|
+
}
|
|
19443
19704
|
renderJson(value, asJson) {
|
|
19444
19705
|
if (!asJson) {
|
|
19445
19706
|
return;
|
|
@@ -20625,6 +20886,97 @@ function parseAppArgs(tokens) {
|
|
|
20625
20886
|
return { type: "app" /* App */, action, id, baseUrl, json };
|
|
20626
20887
|
}
|
|
20627
20888
|
if (action === "icon") {
|
|
20889
|
+
const nextToken = rest[0];
|
|
20890
|
+
if (nextToken === "add") {
|
|
20891
|
+
rest.shift();
|
|
20892
|
+
const rawRef2 = rest.shift();
|
|
20893
|
+
const name = rest.shift();
|
|
20894
|
+
if (!rawRef2 || rawRef2.startsWith("-") || !name || name.startsWith("-")) {
|
|
20895
|
+
throw new Error(
|
|
20896
|
+
"Usage: app icon add <ns:objectId> <name> (--file <path> | (--size <w>x<h>|--<w>x<h>) [--format <png|webp|svg|ico>] [--output <path>]) [--force] [--base-url <url>] [--json]"
|
|
20897
|
+
);
|
|
20898
|
+
}
|
|
20899
|
+
const id2 = parseNamespacedRef(rawRef2, {
|
|
20900
|
+
entityLabel: "app ref"
|
|
20901
|
+
}).fullId;
|
|
20902
|
+
let width2;
|
|
20903
|
+
let height2;
|
|
20904
|
+
let format2;
|
|
20905
|
+
let output2;
|
|
20906
|
+
let filePath;
|
|
20907
|
+
let force = false;
|
|
20908
|
+
while (rest.length > 0) {
|
|
20909
|
+
const token = rest.shift();
|
|
20910
|
+
const inlineSize = parseInlineSizeToken(token);
|
|
20911
|
+
if (inlineSize) {
|
|
20912
|
+
if (filePath || width2 || height2) {
|
|
20913
|
+
throw new Error("App icon add source already set. Use either --file or one explicit size.");
|
|
20914
|
+
}
|
|
20915
|
+
width2 = inlineSize.width;
|
|
20916
|
+
height2 = inlineSize.height;
|
|
20917
|
+
continue;
|
|
20918
|
+
}
|
|
20919
|
+
switch (token) {
|
|
20920
|
+
case "--file":
|
|
20921
|
+
if (filePath || width2 || height2) {
|
|
20922
|
+
throw new Error("App icon add source already set. Use either --file or one explicit size.");
|
|
20923
|
+
}
|
|
20924
|
+
filePath = requireValue5(rest, token);
|
|
20925
|
+
break;
|
|
20926
|
+
case "--size": {
|
|
20927
|
+
if (filePath || width2 || height2) {
|
|
20928
|
+
throw new Error("App icon add source already set. Use either --file or one explicit size.");
|
|
20929
|
+
}
|
|
20930
|
+
const size = parseSizeValue(requireValue5(rest, token));
|
|
20931
|
+
width2 = size.width;
|
|
20932
|
+
height2 = size.height;
|
|
20933
|
+
break;
|
|
20934
|
+
}
|
|
20935
|
+
case "--format": {
|
|
20936
|
+
const value = requireValue5(rest, token);
|
|
20937
|
+
if (value !== "png" && value !== "webp" && value !== "svg" && value !== "ico") {
|
|
20938
|
+
throw new Error(`Invalid app icon format "${value}". Use png, webp, svg, or ico.`);
|
|
20939
|
+
}
|
|
20940
|
+
format2 = value;
|
|
20941
|
+
break;
|
|
20942
|
+
}
|
|
20943
|
+
case "--output":
|
|
20944
|
+
output2 = requireValue5(rest, token);
|
|
20945
|
+
break;
|
|
20946
|
+
case "--force":
|
|
20947
|
+
force = true;
|
|
20948
|
+
break;
|
|
20949
|
+
case "--base-url":
|
|
20950
|
+
baseUrl = requireValue5(rest, token);
|
|
20951
|
+
break;
|
|
20952
|
+
case "--json":
|
|
20953
|
+
json = true;
|
|
20954
|
+
break;
|
|
20955
|
+
default:
|
|
20956
|
+
throw new Error(`Unknown app icon add option: ${token}`);
|
|
20957
|
+
}
|
|
20958
|
+
}
|
|
20959
|
+
if (!filePath && (!width2 || !height2)) {
|
|
20960
|
+
throw new Error("Missing app icon add source. Use --file <path>, --size <w>x<h>, or --<w>x<h>.");
|
|
20961
|
+
}
|
|
20962
|
+
if (filePath && format2) {
|
|
20963
|
+
throw new Error("App icon add with --file infers format from the file extension. Remove --format.");
|
|
20964
|
+
}
|
|
20965
|
+
return {
|
|
20966
|
+
type: "app" /* App */,
|
|
20967
|
+
action: "icon-add",
|
|
20968
|
+
id: id2,
|
|
20969
|
+
name,
|
|
20970
|
+
filePath,
|
|
20971
|
+
width: width2,
|
|
20972
|
+
height: height2,
|
|
20973
|
+
format: format2,
|
|
20974
|
+
output: output2,
|
|
20975
|
+
force,
|
|
20976
|
+
baseUrl,
|
|
20977
|
+
json
|
|
20978
|
+
};
|
|
20979
|
+
}
|
|
20628
20980
|
const rawRef = rest.shift();
|
|
20629
20981
|
if (!rawRef || rawRef.startsWith("-")) {
|
|
20630
20982
|
throw new Error(
|
|
@@ -20715,6 +21067,7 @@ function parseAppArgs(tokens) {
|
|
|
20715
21067
|
return {
|
|
20716
21068
|
type: "app" /* App */,
|
|
20717
21069
|
action,
|
|
21070
|
+
subAction: "export",
|
|
20718
21071
|
id,
|
|
20719
21072
|
preset,
|
|
20720
21073
|
width,
|
|
@@ -21514,7 +21867,93 @@ function parseAccountArgs(tokens) {
|
|
|
21514
21867
|
const rest = [...tokens];
|
|
21515
21868
|
const action = rest.shift();
|
|
21516
21869
|
if (!action) {
|
|
21517
|
-
throw new Error("Missing account action. Use: account view|role");
|
|
21870
|
+
throw new Error("Missing account action. Use: account list|view|app-users|role");
|
|
21871
|
+
}
|
|
21872
|
+
if (action === "list") {
|
|
21873
|
+
let mobile;
|
|
21874
|
+
let nickName;
|
|
21875
|
+
let page;
|
|
21876
|
+
let pageSize;
|
|
21877
|
+
let baseUrl2;
|
|
21878
|
+
let json2 = false;
|
|
21879
|
+
while (rest.length > 0) {
|
|
21880
|
+
const token = rest.shift();
|
|
21881
|
+
switch (token) {
|
|
21882
|
+
case "--mobile":
|
|
21883
|
+
mobile = requireValue8(rest, token);
|
|
21884
|
+
break;
|
|
21885
|
+
case "--nickname":
|
|
21886
|
+
case "--nickName":
|
|
21887
|
+
nickName = requireValue8(rest, token);
|
|
21888
|
+
break;
|
|
21889
|
+
case "--page":
|
|
21890
|
+
page = parsePositiveInt(requireValue8(rest, token), token);
|
|
21891
|
+
break;
|
|
21892
|
+
case "--page-size":
|
|
21893
|
+
pageSize = parsePositiveInt(requireValue8(rest, token), token);
|
|
21894
|
+
break;
|
|
21895
|
+
case "--base-url":
|
|
21896
|
+
baseUrl2 = requireValue8(rest, token);
|
|
21897
|
+
break;
|
|
21898
|
+
case "--json":
|
|
21899
|
+
json2 = true;
|
|
21900
|
+
break;
|
|
21901
|
+
default:
|
|
21902
|
+
throw new Error(`Unknown account list option: ${token}`);
|
|
21903
|
+
}
|
|
21904
|
+
}
|
|
21905
|
+
if (mobile && nickName) {
|
|
21906
|
+
throw new Error(
|
|
21907
|
+
"Usage: account list [--page <n>] [--page-size <n>] [--mobile <mobile> | --nickname <nickname>] [--base-url <url>] [--json]"
|
|
21908
|
+
);
|
|
21909
|
+
}
|
|
21910
|
+
return {
|
|
21911
|
+
type: "account" /* Account */,
|
|
21912
|
+
action: "list",
|
|
21913
|
+
page,
|
|
21914
|
+
pageSize,
|
|
21915
|
+
mobile,
|
|
21916
|
+
nickName,
|
|
21917
|
+
baseUrl: baseUrl2,
|
|
21918
|
+
json: json2
|
|
21919
|
+
};
|
|
21920
|
+
}
|
|
21921
|
+
if (action === "app-users") {
|
|
21922
|
+
const app = parseNamespacedRef(requireValue8(rest, "app-users"), {
|
|
21923
|
+
entityLabel: "app ref"
|
|
21924
|
+
}).fullId;
|
|
21925
|
+
let page;
|
|
21926
|
+
let pageSize;
|
|
21927
|
+
let baseUrl2;
|
|
21928
|
+
let json2 = false;
|
|
21929
|
+
while (rest.length > 0) {
|
|
21930
|
+
const token = rest.shift();
|
|
21931
|
+
switch (token) {
|
|
21932
|
+
case "--page":
|
|
21933
|
+
page = parsePositiveInt(requireValue8(rest, token), token);
|
|
21934
|
+
break;
|
|
21935
|
+
case "--page-size":
|
|
21936
|
+
pageSize = parsePositiveInt(requireValue8(rest, token), token);
|
|
21937
|
+
break;
|
|
21938
|
+
case "--base-url":
|
|
21939
|
+
baseUrl2 = requireValue8(rest, token);
|
|
21940
|
+
break;
|
|
21941
|
+
case "--json":
|
|
21942
|
+
json2 = true;
|
|
21943
|
+
break;
|
|
21944
|
+
default:
|
|
21945
|
+
throw new Error(`Unknown account app-users option: ${token}`);
|
|
21946
|
+
}
|
|
21947
|
+
}
|
|
21948
|
+
return {
|
|
21949
|
+
type: "account" /* Account */,
|
|
21950
|
+
action: "app-users",
|
|
21951
|
+
app,
|
|
21952
|
+
page,
|
|
21953
|
+
pageSize,
|
|
21954
|
+
baseUrl: baseUrl2,
|
|
21955
|
+
json: json2
|
|
21956
|
+
};
|
|
21518
21957
|
}
|
|
21519
21958
|
if (action === "view") {
|
|
21520
21959
|
let account2;
|
|
@@ -21737,6 +22176,13 @@ function requireValue8(tokens, optionName) {
|
|
|
21737
22176
|
}
|
|
21738
22177
|
return value;
|
|
21739
22178
|
}
|
|
22179
|
+
function parsePositiveInt(value, optionName) {
|
|
22180
|
+
const parsed = Number(value);
|
|
22181
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
22182
|
+
throw new Error(`${optionName} must be a positive integer`);
|
|
22183
|
+
}
|
|
22184
|
+
return parsed;
|
|
22185
|
+
}
|
|
21740
22186
|
|
|
21741
22187
|
// src/orgCommandParser.ts
|
|
21742
22188
|
init_namespacedRef();
|
|
@@ -22265,7 +22711,9 @@ var HELP_TEXT = [
|
|
|
22265
22711
|
` ${import_chalk4.default.gray(" definition create <role> [--display-name <name>] [--description <text>] [--base-url <url>] [--json]")}`,
|
|
22266
22712
|
` ${import_chalk4.default.gray(" default base URL: https://auth-api-v2.pmate.chat")}`,
|
|
22267
22713
|
` ${import_chalk4.default.cyan("account")} View accounts and manage account role bindings`,
|
|
22714
|
+
` ${import_chalk4.default.gray(" list [--page <n>] [--page-size <n>] [--mobile <mobile> | --nickname <nickname>] [--base-url <url>] [--json]")}`,
|
|
22268
22715
|
` ${import_chalk4.default.gray(" view (--account <id> | --mobile <mobile> | --nickname <nickname>) [--base-url <url>] [--json]")}`,
|
|
22716
|
+
` ${import_chalk4.default.gray(" app-users <ns:app> [--page <n>] [--page-size <n>] [--base-url <url>] [--json]")}`,
|
|
22269
22717
|
` ${import_chalk4.default.gray(" role list --account <id> [--namespace <ns>] [--base-url <url>] [--json]")}`,
|
|
22270
22718
|
` ${import_chalk4.default.gray(" role add --account <id> --namespace <ns> --role <role> [--base-url <url>] [--json]")}`,
|
|
22271
22719
|
` ${import_chalk4.default.gray(" role remove --account <id> --namespace <ns> --role <role> [--base-url <url>] [--json]")}`,
|
|
@@ -22306,6 +22754,8 @@ var HELP_TEXT = [
|
|
|
22306
22754
|
` ${import_chalk4.default.gray(" icon <ns:objectId> --android --out-dir <path> [--base-url <url>] [--json]")}`,
|
|
22307
22755
|
` ${import_chalk4.default.gray(" icon <ns:objectId> --ios --out-dir <path> [--base-url <url>] [--json]")}`,
|
|
22308
22756
|
` ${import_chalk4.default.gray(" icon <ns:objectId> (--size <w>x<h>|--<w>x<h>) --output <path> [--format <png|webp|svg|ico>] [--base-url <url>] [--json]")}`,
|
|
22757
|
+
` ${import_chalk4.default.gray(" icon add <ns:objectId> <name> --file <path> [--force] [--base-url <url>] [--json]")}`,
|
|
22758
|
+
` ${import_chalk4.default.gray(" icon add <ns:objectId> <name> (--size <w>x<h>|--<w>x<h>) [--format <png|webp|svg|ico>] [--output <path>] [--force] [--base-url <url>] [--json]")}`,
|
|
22309
22759
|
` ${import_chalk4.default.gray(" delete <ns:objectId> [--base-url <url>] [--json]")}`,
|
|
22310
22760
|
` ${import_chalk4.default.gray(" default base URL: https://apps-api.pmate.chat")}`,
|
|
22311
22761
|
` ${import_chalk4.default.cyan("service")} Manage service registry entries via apps-api`,
|
|
@@ -23913,7 +24363,7 @@ function parseRandomArgs(tokens) {
|
|
|
23913
24363
|
mode = "easy";
|
|
23914
24364
|
break;
|
|
23915
24365
|
case "--length":
|
|
23916
|
-
length =
|
|
24366
|
+
length = parsePositiveInt2(requireValue12(rest, token), token);
|
|
23917
24367
|
seenLength = true;
|
|
23918
24368
|
break;
|
|
23919
24369
|
case "--charset": {
|
|
@@ -23928,10 +24378,10 @@ function parseRandomArgs(tokens) {
|
|
|
23928
24378
|
break;
|
|
23929
24379
|
}
|
|
23930
24380
|
case "--count":
|
|
23931
|
-
count =
|
|
24381
|
+
count = parsePositiveInt2(requireValue12(rest, token), token);
|
|
23932
24382
|
break;
|
|
23933
24383
|
case "--words":
|
|
23934
|
-
words =
|
|
24384
|
+
words = parsePositiveInt2(requireValue12(rest, token), token);
|
|
23935
24385
|
seenWords = true;
|
|
23936
24386
|
break;
|
|
23937
24387
|
case "--digits":
|
|
@@ -23980,7 +24430,7 @@ function requireValue12(tokens, optionName) {
|
|
|
23980
24430
|
function decodeEscapedNewlines(value) {
|
|
23981
24431
|
return value.replace(/(?<!\\)\\r\\n/g, "\n").replace(/(?<!\\)\\n/g, "\n").replace(/(?<!\\)\\r/g, "\n");
|
|
23982
24432
|
}
|
|
23983
|
-
function
|
|
24433
|
+
function parsePositiveInt2(value, optionName) {
|
|
23984
24434
|
const parsed = Number.parseInt(value, 10);
|
|
23985
24435
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
23986
24436
|
throw new Error(`Invalid ${optionName} value: ${value}`);
|