@docyrus/docyrus 0.0.14 → 0.0.16
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/main.js +348 -58
- package/main.js.map +3 -3
- package/package.json +1 -1
package/main.js
CHANGED
|
@@ -124678,7 +124678,7 @@ function buildInputSchema(args, env2, options2) {
|
|
|
124678
124678
|
// package.json
|
|
124679
124679
|
var package_default = {
|
|
124680
124680
|
name: "@docyrus/docyrus",
|
|
124681
|
-
version: "0.0.
|
|
124681
|
+
version: "0.0.16",
|
|
124682
124682
|
private: false,
|
|
124683
124683
|
description: "Docyrus API CLI",
|
|
124684
124684
|
main: "./main.js",
|
|
@@ -125009,6 +125009,54 @@ function createAiCli(dependencies) {
|
|
|
125009
125009
|
}
|
|
125010
125010
|
|
|
125011
125011
|
// src/commands/appsCommands.ts
|
|
125012
|
+
function normalizeOptional(value) {
|
|
125013
|
+
const trimmed = value?.trim();
|
|
125014
|
+
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
125015
|
+
}
|
|
125016
|
+
function extractAppRecords(payload) {
|
|
125017
|
+
if (Array.isArray(payload)) {
|
|
125018
|
+
return payload.filter((item) => typeof item === "object" && item !== null);
|
|
125019
|
+
}
|
|
125020
|
+
if (typeof payload === "object" && payload !== null && Array.isArray(payload.data)) {
|
|
125021
|
+
return payload.data.filter((item) => typeof item === "object" && item !== null);
|
|
125022
|
+
}
|
|
125023
|
+
return [];
|
|
125024
|
+
}
|
|
125025
|
+
function extractString(record2, key) {
|
|
125026
|
+
const value = record2[key];
|
|
125027
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
125028
|
+
}
|
|
125029
|
+
async function resolveAppId(params) {
|
|
125030
|
+
const appId = normalizeOptional(params.appId);
|
|
125031
|
+
const appSlug = normalizeOptional(params.appSlug);
|
|
125032
|
+
if (appId && appSlug) {
|
|
125033
|
+
throw new UserInputError("Provide either --appId or --appSlug, not both.");
|
|
125034
|
+
}
|
|
125035
|
+
if (!appId && !appSlug) {
|
|
125036
|
+
throw new UserInputError("Provide --appId or --appSlug.");
|
|
125037
|
+
}
|
|
125038
|
+
if (appId) {
|
|
125039
|
+
return appId;
|
|
125040
|
+
}
|
|
125041
|
+
const response = await params.apiClient.request({
|
|
125042
|
+
method: "GET",
|
|
125043
|
+
path: "/apps"
|
|
125044
|
+
});
|
|
125045
|
+
const apps = extractAppRecords(response.data);
|
|
125046
|
+
const matches = apps.filter((item) => extractString(item, "slug") === appSlug);
|
|
125047
|
+
if (matches.length === 0) {
|
|
125048
|
+
throw new UserInputError(`App slug '${appSlug}' was not found.`);
|
|
125049
|
+
}
|
|
125050
|
+
if (matches.length > 1) {
|
|
125051
|
+
const matchingIds = matches.map((item) => extractString(item, "id")).filter((value) => Boolean(value));
|
|
125052
|
+
throw new UserInputError(`App slug '${appSlug}' is ambiguous. Matching IDs: ${matchingIds.join(", ")}`);
|
|
125053
|
+
}
|
|
125054
|
+
const resolvedId = extractString(matches[0], "id");
|
|
125055
|
+
if (!resolvedId) {
|
|
125056
|
+
throw new UserInputError(`App slug '${appSlug}' resolved to an invalid item without id.`);
|
|
125057
|
+
}
|
|
125058
|
+
return resolvedId;
|
|
125059
|
+
}
|
|
125012
125060
|
function createAppsCli(dependencies) {
|
|
125013
125061
|
const appsCli = Cli_exports.create("apps", {
|
|
125014
125062
|
description: "App commands",
|
|
@@ -125036,6 +125084,81 @@ function createAppsCli(dependencies) {
|
|
|
125036
125084
|
});
|
|
125037
125085
|
}
|
|
125038
125086
|
});
|
|
125087
|
+
appsCli.command("delete", {
|
|
125088
|
+
description: "Archive an app",
|
|
125089
|
+
options: external_exports.object({
|
|
125090
|
+
appId: external_exports.string().optional().describe("App ID"),
|
|
125091
|
+
appSlug: external_exports.string().optional().describe("App slug")
|
|
125092
|
+
}),
|
|
125093
|
+
run: async (context) => {
|
|
125094
|
+
const apiBaseUrl = await dependencies.environmentConfigService.getActiveApiBaseUrl();
|
|
125095
|
+
const apiClient = dependencies.createApiClient(apiBaseUrl);
|
|
125096
|
+
const appId = await resolveAppId({
|
|
125097
|
+
apiClient,
|
|
125098
|
+
appId: context.options.appId,
|
|
125099
|
+
appSlug: context.options.appSlug
|
|
125100
|
+
});
|
|
125101
|
+
const response = await apiClient.request({
|
|
125102
|
+
method: "DELETE",
|
|
125103
|
+
path: `/dev/apps/${appId}`
|
|
125104
|
+
});
|
|
125105
|
+
return await injectContext({
|
|
125106
|
+
apiBaseUrl,
|
|
125107
|
+
authStore: dependencies.authStore,
|
|
125108
|
+
payload: response.data
|
|
125109
|
+
});
|
|
125110
|
+
}
|
|
125111
|
+
});
|
|
125112
|
+
appsCli.command("restore", {
|
|
125113
|
+
description: "Restore an archived app",
|
|
125114
|
+
options: external_exports.object({
|
|
125115
|
+
appId: external_exports.string().optional().describe("App ID"),
|
|
125116
|
+
appSlug: external_exports.string().optional().describe("App slug")
|
|
125117
|
+
}),
|
|
125118
|
+
run: async (context) => {
|
|
125119
|
+
const apiBaseUrl = await dependencies.environmentConfigService.getActiveApiBaseUrl();
|
|
125120
|
+
const apiClient = dependencies.createApiClient(apiBaseUrl);
|
|
125121
|
+
const appId = await resolveAppId({
|
|
125122
|
+
apiClient,
|
|
125123
|
+
appId: context.options.appId,
|
|
125124
|
+
appSlug: context.options.appSlug
|
|
125125
|
+
});
|
|
125126
|
+
const response = await apiClient.request({
|
|
125127
|
+
method: "POST",
|
|
125128
|
+
path: `/dev/apps/${appId}/restore`
|
|
125129
|
+
});
|
|
125130
|
+
return await injectContext({
|
|
125131
|
+
apiBaseUrl,
|
|
125132
|
+
authStore: dependencies.authStore,
|
|
125133
|
+
payload: response.data
|
|
125134
|
+
});
|
|
125135
|
+
}
|
|
125136
|
+
});
|
|
125137
|
+
appsCli.command("permanent-delete", {
|
|
125138
|
+
description: "Permanently delete an app",
|
|
125139
|
+
options: external_exports.object({
|
|
125140
|
+
appId: external_exports.string().optional().describe("App ID"),
|
|
125141
|
+
appSlug: external_exports.string().optional().describe("App slug")
|
|
125142
|
+
}),
|
|
125143
|
+
run: async (context) => {
|
|
125144
|
+
const apiBaseUrl = await dependencies.environmentConfigService.getActiveApiBaseUrl();
|
|
125145
|
+
const apiClient = dependencies.createApiClient(apiBaseUrl);
|
|
125146
|
+
const appId = await resolveAppId({
|
|
125147
|
+
apiClient,
|
|
125148
|
+
appId: context.options.appId,
|
|
125149
|
+
appSlug: context.options.appSlug
|
|
125150
|
+
});
|
|
125151
|
+
const response = await apiClient.request({
|
|
125152
|
+
method: "DELETE",
|
|
125153
|
+
path: `/dev/apps/${appId}/permanent`
|
|
125154
|
+
});
|
|
125155
|
+
return await injectContext({
|
|
125156
|
+
apiBaseUrl,
|
|
125157
|
+
authStore: dependencies.authStore,
|
|
125158
|
+
payload: response.data
|
|
125159
|
+
});
|
|
125160
|
+
}
|
|
125161
|
+
});
|
|
125039
125162
|
return appsCli;
|
|
125040
125163
|
}
|
|
125041
125164
|
|
|
@@ -126104,7 +126227,7 @@ function parseOpenApiDocument(raw) {
|
|
|
126104
126227
|
}
|
|
126105
126228
|
return parsed;
|
|
126106
126229
|
}
|
|
126107
|
-
async function loadOpenApiSpec(dependencies, tenantId) {
|
|
126230
|
+
async function loadOpenApiSpec(dependencies, tenantId, options2) {
|
|
126108
126231
|
let filePath = dependencies.tenantOpenApiService.getTenantOpenApiFilePath(tenantId);
|
|
126109
126232
|
let downloaded = false;
|
|
126110
126233
|
let sourceUrl;
|
|
@@ -126118,7 +126241,7 @@ async function loadOpenApiSpec(dependencies, tenantId) {
|
|
|
126118
126241
|
cause: error48
|
|
126119
126242
|
});
|
|
126120
126243
|
}
|
|
126121
|
-
const downloadResult = await dependencies.tenantOpenApiService.downloadTenantOpenApi(tenantId);
|
|
126244
|
+
const downloadResult = await dependencies.tenantOpenApiService.downloadTenantOpenApi(tenantId, options2);
|
|
126122
126245
|
downloaded = true;
|
|
126123
126246
|
sourceUrl = downloadResult.sourceUrl;
|
|
126124
126247
|
filePath = downloadResult.filePath;
|
|
@@ -126137,11 +126260,15 @@ async function withActiveTenantSpec(dependencies) {
|
|
|
126137
126260
|
if (!activeProfile) {
|
|
126138
126261
|
throw new AuthSessionError("No active session found. Run 'docyrus auth login'.");
|
|
126139
126262
|
}
|
|
126140
|
-
const
|
|
126263
|
+
const authSessionService = dependencies.createAuthSessionService(apiBaseUrl);
|
|
126264
|
+
const authToken = await authSessionService.getValidAccessToken();
|
|
126141
126265
|
return {
|
|
126142
126266
|
apiBaseUrl,
|
|
126143
126267
|
activeProfile,
|
|
126144
|
-
spec
|
|
126268
|
+
spec: await loadOpenApiSpec(dependencies, activeProfile.tenantId, {
|
|
126269
|
+
apiBaseUrl,
|
|
126270
|
+
authToken
|
|
126271
|
+
})
|
|
126145
126272
|
};
|
|
126146
126273
|
}
|
|
126147
126274
|
function createDiscoverCli(dependencies) {
|
|
@@ -126157,7 +126284,12 @@ function createDiscoverCli(dependencies) {
|
|
|
126157
126284
|
if (!activeProfile) {
|
|
126158
126285
|
throw new AuthSessionError("No active session found. Run 'docyrus auth login'.");
|
|
126159
126286
|
}
|
|
126160
|
-
const
|
|
126287
|
+
const authSessionService = dependencies.createAuthSessionService(apiBaseUrl);
|
|
126288
|
+
const authToken = await authSessionService.getValidAccessToken();
|
|
126289
|
+
const downloaded = await dependencies.tenantOpenApiService.downloadTenantOpenApi(activeProfile.tenantId, {
|
|
126290
|
+
apiBaseUrl,
|
|
126291
|
+
authToken
|
|
126292
|
+
});
|
|
126161
126293
|
return await injectContext({
|
|
126162
126294
|
apiBaseUrl,
|
|
126163
126295
|
authStore: dependencies.authStore,
|
|
@@ -126454,7 +126586,7 @@ function normalizeBatchPayload(payload, key) {
|
|
|
126454
126586
|
function isRecord4(value) {
|
|
126455
126587
|
return typeof value === "object" && value !== null;
|
|
126456
126588
|
}
|
|
126457
|
-
function
|
|
126589
|
+
function extractString2(record2, key) {
|
|
126458
126590
|
const value = record2[key];
|
|
126459
126591
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
126460
126592
|
}
|
|
@@ -126475,20 +126607,20 @@ function ensureExclusiveSelector(label, idValue, slugValue) {
|
|
|
126475
126607
|
throw new UserInputError(`Provide --${label}Id or --${label}Slug.`);
|
|
126476
126608
|
}
|
|
126477
126609
|
}
|
|
126478
|
-
function
|
|
126610
|
+
function normalizeOptional2(value) {
|
|
126479
126611
|
const trimmed = value?.trim();
|
|
126480
126612
|
return trimmed && trimmed.length > 0 ? trimmed : void 0;
|
|
126481
126613
|
}
|
|
126482
126614
|
function resolveBySlug(label, items, slug) {
|
|
126483
|
-
const matches = items.filter((item) =>
|
|
126615
|
+
const matches = items.filter((item) => extractString2(item, "slug") === slug);
|
|
126484
126616
|
if (matches.length === 0) {
|
|
126485
126617
|
throw new UserInputError(`${label} slug '${slug}' was not found.`);
|
|
126486
126618
|
}
|
|
126487
126619
|
if (matches.length > 1) {
|
|
126488
|
-
const matchingIds = matches.map((item) =>
|
|
126620
|
+
const matchingIds = matches.map((item) => extractString2(item, "id")).filter((id) => Boolean(id));
|
|
126489
126621
|
throw new UserInputError(`${label} slug '${slug}' is ambiguous. Matching IDs: ${matchingIds.join(", ")}`);
|
|
126490
126622
|
}
|
|
126491
|
-
const matchId =
|
|
126623
|
+
const matchId = extractString2(matches[0], "id");
|
|
126492
126624
|
if (!matchId) {
|
|
126493
126625
|
throw new UserInputError(`${label} slug '${slug}' resolved to an invalid item without id.`);
|
|
126494
126626
|
}
|
|
@@ -126502,8 +126634,8 @@ var StudioResolver = class {
|
|
|
126502
126634
|
#dataSourcesByAppId = /* @__PURE__ */ new Map();
|
|
126503
126635
|
#fieldsByAppAndDataSource = /* @__PURE__ */ new Map();
|
|
126504
126636
|
async resolveAppId(options2) {
|
|
126505
|
-
const appId =
|
|
126506
|
-
const appSlug =
|
|
126637
|
+
const appId = normalizeOptional2(options2.appId);
|
|
126638
|
+
const appSlug = normalizeOptional2(options2.appSlug);
|
|
126507
126639
|
ensureExclusiveSelector("app", appId, appSlug);
|
|
126508
126640
|
if (appId) {
|
|
126509
126641
|
return appId;
|
|
@@ -126512,8 +126644,8 @@ var StudioResolver = class {
|
|
|
126512
126644
|
return resolveBySlug("App", apps, appSlug);
|
|
126513
126645
|
}
|
|
126514
126646
|
async resolveDataSourceId(options2) {
|
|
126515
|
-
const dataSourceId =
|
|
126516
|
-
const dataSourceSlug =
|
|
126647
|
+
const dataSourceId = normalizeOptional2(options2.dataSourceId);
|
|
126648
|
+
const dataSourceSlug = normalizeOptional2(options2.dataSourceSlug);
|
|
126517
126649
|
ensureExclusiveSelector("dataSource", dataSourceId, dataSourceSlug);
|
|
126518
126650
|
if (dataSourceId) {
|
|
126519
126651
|
return dataSourceId;
|
|
@@ -126522,8 +126654,8 @@ var StudioResolver = class {
|
|
|
126522
126654
|
return resolveBySlug("Data source", dataSources, dataSourceSlug);
|
|
126523
126655
|
}
|
|
126524
126656
|
async resolveFieldId(options2) {
|
|
126525
|
-
const fieldId =
|
|
126526
|
-
const fieldSlug =
|
|
126657
|
+
const fieldId = normalizeOptional2(options2.fieldId);
|
|
126658
|
+
const fieldSlug = normalizeOptional2(options2.fieldSlug);
|
|
126527
126659
|
ensureExclusiveSelector("field", fieldId, fieldSlug);
|
|
126528
126660
|
if (fieldId) {
|
|
126529
126661
|
return fieldId;
|
|
@@ -126630,6 +126762,65 @@ function requireNonEmptyObject(payload, label) {
|
|
|
126630
126762
|
throw new UserInputError(`${label} payload is empty. Provide flags, --data, or --from-file.`);
|
|
126631
126763
|
}
|
|
126632
126764
|
}
|
|
126765
|
+
function isRecord5(value) {
|
|
126766
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
126767
|
+
}
|
|
126768
|
+
function normalizeBatchUpdateFieldItem(item) {
|
|
126769
|
+
if (!isRecord5(item)) {
|
|
126770
|
+
return item;
|
|
126771
|
+
}
|
|
126772
|
+
const normalized = {
|
|
126773
|
+
...item
|
|
126774
|
+
};
|
|
126775
|
+
if (!("fieldId" in normalized) && typeof normalized.id === "string") {
|
|
126776
|
+
normalized.fieldId = normalized.id;
|
|
126777
|
+
}
|
|
126778
|
+
if (!("readOnly" in normalized) && "read_only" in normalized) {
|
|
126779
|
+
normalized.readOnly = normalized.read_only;
|
|
126780
|
+
}
|
|
126781
|
+
if (!("defaultValue" in normalized) && "default_value" in normalized) {
|
|
126782
|
+
normalized.defaultValue = normalized.default_value;
|
|
126783
|
+
}
|
|
126784
|
+
if (!("relationDataSourceId" in normalized) && "relation_data_source_id" in normalized) {
|
|
126785
|
+
normalized.relationDataSourceId = normalized.relation_data_source_id;
|
|
126786
|
+
}
|
|
126787
|
+
if (!("editorOptions" in normalized) && "options" in normalized) {
|
|
126788
|
+
normalized.editorOptions = normalized.options;
|
|
126789
|
+
}
|
|
126790
|
+
return normalized;
|
|
126791
|
+
}
|
|
126792
|
+
function normalizeBatchUpdateFieldsPayload(payload) {
|
|
126793
|
+
const fields = payload.fields;
|
|
126794
|
+
if (!Array.isArray(fields)) {
|
|
126795
|
+
return payload;
|
|
126796
|
+
}
|
|
126797
|
+
return {
|
|
126798
|
+
...payload,
|
|
126799
|
+
fields: fields.map((item) => normalizeBatchUpdateFieldItem(item))
|
|
126800
|
+
};
|
|
126801
|
+
}
|
|
126802
|
+
function normalizeUpdateEnumItem(item) {
|
|
126803
|
+
if (!isRecord5(item)) {
|
|
126804
|
+
return item;
|
|
126805
|
+
}
|
|
126806
|
+
if (!("enumId" in item) && typeof item.id === "string") {
|
|
126807
|
+
return {
|
|
126808
|
+
...item,
|
|
126809
|
+
enumId: item.id
|
|
126810
|
+
};
|
|
126811
|
+
}
|
|
126812
|
+
return item;
|
|
126813
|
+
}
|
|
126814
|
+
function normalizeUpdateEnumsPayload(payload) {
|
|
126815
|
+
const enums = payload.enums;
|
|
126816
|
+
if (!Array.isArray(enums)) {
|
|
126817
|
+
return payload;
|
|
126818
|
+
}
|
|
126819
|
+
return {
|
|
126820
|
+
...payload,
|
|
126821
|
+
enums: enums.map((item) => normalizeUpdateEnumItem(item))
|
|
126822
|
+
};
|
|
126823
|
+
}
|
|
126633
126824
|
function createStudioCli(dependencies) {
|
|
126634
126825
|
const studioCli = Cli_exports.create("studio", {
|
|
126635
126826
|
description: "Studio (dev app data source CRUD) commands",
|
|
@@ -126768,7 +126959,7 @@ function createStudioCli(dependencies) {
|
|
|
126768
126959
|
}
|
|
126769
126960
|
});
|
|
126770
126961
|
studioCli.command("delete-data-source", {
|
|
126771
|
-
description: "
|
|
126962
|
+
description: "Archive a data source",
|
|
126772
126963
|
options: external_exports.object({
|
|
126773
126964
|
appId: external_exports.string().optional().describe("App ID"),
|
|
126774
126965
|
appSlug: external_exports.string().optional().describe("App slug"),
|
|
@@ -126793,6 +126984,46 @@ function createStudioCli(dependencies) {
|
|
|
126793
126984
|
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
126794
126985
|
}
|
|
126795
126986
|
});
|
|
126987
|
+
studioCli.command("restore-data-source", {
|
|
126988
|
+
description: "Restore an archived data source",
|
|
126989
|
+
options: external_exports.object({
|
|
126990
|
+
appId: external_exports.string().optional().describe("App ID"),
|
|
126991
|
+
appSlug: external_exports.string().optional().describe("App slug"),
|
|
126992
|
+
dataSourceId: external_exports.string().min(1).describe("Data source ID")
|
|
126993
|
+
}),
|
|
126994
|
+
run: async (context) => {
|
|
126995
|
+
const studio = await getStudioRunContext(dependencies);
|
|
126996
|
+
const appId = await studio.resolver.resolveAppId({
|
|
126997
|
+
appId: context.options.appId,
|
|
126998
|
+
appSlug: context.options.appSlug
|
|
126999
|
+
});
|
|
127000
|
+
const response = await studio.apiClient.request({
|
|
127001
|
+
method: "POST",
|
|
127002
|
+
path: `/dev/apps/${appId}/data-sources/${context.options.dataSourceId}/restore`
|
|
127003
|
+
});
|
|
127004
|
+
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
127005
|
+
}
|
|
127006
|
+
});
|
|
127007
|
+
studioCli.command("permanent-delete-data-source", {
|
|
127008
|
+
description: "Permanently delete a data source",
|
|
127009
|
+
options: external_exports.object({
|
|
127010
|
+
appId: external_exports.string().optional().describe("App ID"),
|
|
127011
|
+
appSlug: external_exports.string().optional().describe("App slug"),
|
|
127012
|
+
dataSourceId: external_exports.string().min(1).describe("Data source ID")
|
|
127013
|
+
}),
|
|
127014
|
+
run: async (context) => {
|
|
127015
|
+
const studio = await getStudioRunContext(dependencies);
|
|
127016
|
+
const appId = await studio.resolver.resolveAppId({
|
|
127017
|
+
appId: context.options.appId,
|
|
127018
|
+
appSlug: context.options.appSlug
|
|
127019
|
+
});
|
|
127020
|
+
const response = await studio.apiClient.request({
|
|
127021
|
+
method: "DELETE",
|
|
127022
|
+
path: `/dev/apps/${appId}/data-sources/${context.options.dataSourceId}/permanent`
|
|
127023
|
+
});
|
|
127024
|
+
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
127025
|
+
}
|
|
127026
|
+
});
|
|
126796
127027
|
studioCli.command("bulk-create-data-sources", {
|
|
126797
127028
|
description: "Bulk create data sources",
|
|
126798
127029
|
options: external_exports.object({
|
|
@@ -127086,10 +127317,11 @@ function createStudioCli(dependencies) {
|
|
|
127086
127317
|
}),
|
|
127087
127318
|
"fields"
|
|
127088
127319
|
);
|
|
127320
|
+
const normalizedPayload = normalizeBatchUpdateFieldsPayload(payload);
|
|
127089
127321
|
const response = await studio.apiClient.request({
|
|
127090
127322
|
method: "PATCH",
|
|
127091
127323
|
path: `/dev/apps/${appId}/data-sources/${dataSourceId}/fields/batch`,
|
|
127092
|
-
body:
|
|
127324
|
+
body: normalizedPayload
|
|
127093
127325
|
});
|
|
127094
127326
|
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
127095
127327
|
}
|
|
@@ -127250,10 +127482,11 @@ function createStudioCli(dependencies) {
|
|
|
127250
127482
|
}),
|
|
127251
127483
|
"enums"
|
|
127252
127484
|
);
|
|
127485
|
+
const normalizedPayload = normalizeUpdateEnumsPayload(payload);
|
|
127253
127486
|
const response = await studio.apiClient.request({
|
|
127254
127487
|
method: "PATCH",
|
|
127255
127488
|
path: `/dev/apps/${appId}/data-sources/${dataSourceId}/fields/${fieldId}/enums`,
|
|
127256
|
-
body:
|
|
127489
|
+
body: normalizedPayload
|
|
127257
127490
|
});
|
|
127258
127491
|
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
127259
127492
|
}
|
|
@@ -127587,7 +127820,7 @@ var ApiClient = class {
|
|
|
127587
127820
|
|
|
127588
127821
|
// src/services/authSession.ts
|
|
127589
127822
|
var DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS = 3600;
|
|
127590
|
-
function
|
|
127823
|
+
function isRecord6(value) {
|
|
127591
127824
|
return typeof value === "object" && value !== null;
|
|
127592
127825
|
}
|
|
127593
127826
|
function extractRecordValue(record2, keys) {
|
|
@@ -127598,7 +127831,7 @@ function extractRecordValue(record2, keys) {
|
|
|
127598
127831
|
}
|
|
127599
127832
|
return void 0;
|
|
127600
127833
|
}
|
|
127601
|
-
function
|
|
127834
|
+
function extractString3(record2, keys) {
|
|
127602
127835
|
const value = extractRecordValue(record2, keys);
|
|
127603
127836
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
127604
127837
|
}
|
|
@@ -127900,15 +128133,15 @@ var AuthSessionService = class {
|
|
|
127900
128133
|
fetchFn: this.params.fetchFn
|
|
127901
128134
|
});
|
|
127902
128135
|
const payload = response.data;
|
|
127903
|
-
const dataCandidate =
|
|
127904
|
-
if (!
|
|
128136
|
+
const dataCandidate = isRecord6(payload) && isRecord6(payload.data) ? payload.data : payload;
|
|
128137
|
+
if (!isRecord6(dataCandidate)) {
|
|
127905
128138
|
throw new AuthSessionError("Unable to parse /users/me response.");
|
|
127906
128139
|
}
|
|
127907
|
-
const tenantCandidate =
|
|
127908
|
-
const userId =
|
|
127909
|
-
const email3 =
|
|
127910
|
-
const tenantId = tenantCandidate ?
|
|
127911
|
-
const tenantName = tenantCandidate ?
|
|
128140
|
+
const tenantCandidate = isRecord6(dataCandidate.tenant) ? dataCandidate.tenant : void 0;
|
|
128141
|
+
const userId = extractString3(dataCandidate, ["id", "user_id"]);
|
|
128142
|
+
const email3 = extractString3(dataCandidate, ["email"]);
|
|
128143
|
+
const tenantId = tenantCandidate ? extractString3(tenantCandidate, ["id"]) : extractString3(dataCandidate, ["tenant_id", "tenantId"]);
|
|
128144
|
+
const tenantName = tenantCandidate ? extractString3(tenantCandidate, ["name"]) : extractString3(dataCandidate, ["tenant_name", "tenantName"]);
|
|
127912
128145
|
const tenantNo = tenantCandidate ? extractNumber(tenantCandidate, ["no", "tenant_no"]) : extractNumber(dataCandidate, ["tenant_no", "tenantNo"]);
|
|
127913
128146
|
if (!userId || !email3 || !tenantId || !tenantName || !tenantNo) {
|
|
127914
128147
|
throw new AuthSessionError("Incomplete identity data returned from /users/me.");
|
|
@@ -127930,17 +128163,17 @@ var AuthSessionService = class {
|
|
|
127930
128163
|
fetchFn: this.params.fetchFn
|
|
127931
128164
|
});
|
|
127932
128165
|
const payload = response.data;
|
|
127933
|
-
const listCandidate = Array.isArray(payload) ? payload :
|
|
128166
|
+
const listCandidate = Array.isArray(payload) ? payload : isRecord6(payload) && Array.isArray(payload.data) ? payload.data : null;
|
|
127934
128167
|
if (!listCandidate) {
|
|
127935
128168
|
throw new AuthSessionError("Unable to parse tenant catalog response.");
|
|
127936
128169
|
}
|
|
127937
128170
|
const mapped = [];
|
|
127938
128171
|
for (const item of listCandidate) {
|
|
127939
|
-
if (!
|
|
128172
|
+
if (!isRecord6(item)) {
|
|
127940
128173
|
continue;
|
|
127941
128174
|
}
|
|
127942
|
-
const tenantId =
|
|
127943
|
-
const tenantName =
|
|
128175
|
+
const tenantId = extractString3(item, ["id", "tenant_id"]);
|
|
128176
|
+
const tenantName = extractString3(item, ["name"]);
|
|
127944
128177
|
const tenantNo = extractNumber(item, ["tenant_no", "tenantNo", "no"]);
|
|
127945
128178
|
const logoValue = extractRecordValue(item, ["logo"]);
|
|
127946
128179
|
const logo = typeof logoValue === "string" || logoValue === null ? logoValue : void 0;
|
|
@@ -128618,10 +128851,66 @@ var import_node_path9 = require("node:path");
|
|
|
128618
128851
|
function resolveSourceUrl(tenantId, template) {
|
|
128619
128852
|
return template.replace("{tenantId}", encodeURIComponent(tenantId));
|
|
128620
128853
|
}
|
|
128854
|
+
async function parseOpenApiJsonResponse(response, params) {
|
|
128855
|
+
const content = await response.text();
|
|
128856
|
+
let parsedContent;
|
|
128857
|
+
try {
|
|
128858
|
+
parsedContent = JSON.parse(content);
|
|
128859
|
+
} catch (error48) {
|
|
128860
|
+
throw new AuthSessionError("Downloaded tenant OpenAPI spec is invalid JSON.", {
|
|
128861
|
+
tenantId: params.tenantId,
|
|
128862
|
+
sourceUrl: params.sourceUrl,
|
|
128863
|
+
cause: error48
|
|
128864
|
+
});
|
|
128865
|
+
}
|
|
128866
|
+
return parsedContent;
|
|
128867
|
+
}
|
|
128621
128868
|
var TenantOpenApiService = class {
|
|
128622
128869
|
constructor(params) {
|
|
128623
128870
|
this.params = params;
|
|
128624
128871
|
}
|
|
128872
|
+
async #writeOpenApiFile(tenantId, parsedContent) {
|
|
128873
|
+
const filePath = this.getTenantOpenApiFilePath(tenantId);
|
|
128874
|
+
await (0, import_promises7.mkdir)((0, import_node_path9.dirname)(filePath), {
|
|
128875
|
+
recursive: true,
|
|
128876
|
+
mode: 448
|
|
128877
|
+
});
|
|
128878
|
+
await (0, import_promises7.writeFile)(filePath, `${JSON.stringify(parsedContent, null, 2)}
|
|
128879
|
+
`, {
|
|
128880
|
+
encoding: "utf8",
|
|
128881
|
+
mode: 384
|
|
128882
|
+
});
|
|
128883
|
+
await (0, import_promises7.chmod)(filePath, 384);
|
|
128884
|
+
return filePath;
|
|
128885
|
+
}
|
|
128886
|
+
async #generateTenantOpenApiViaAuthenticatedEndpoint(tenantId, options2) {
|
|
128887
|
+
if (!options2.apiBaseUrl || !options2.authToken) {
|
|
128888
|
+
throw new AuthSessionError("Failed to download tenant OpenAPI spec.", {
|
|
128889
|
+
tenantId,
|
|
128890
|
+
reason: "OpenAPI file is missing and no authenticated fallback request could be made."
|
|
128891
|
+
});
|
|
128892
|
+
}
|
|
128893
|
+
const apiUrl = `${normalizeApiBaseUrl(options2.apiBaseUrl)}/api/openapi.json`;
|
|
128894
|
+
const response = await (this.params?.fetchFn || fetch)(apiUrl, {
|
|
128895
|
+
method: "GET",
|
|
128896
|
+
headers: {
|
|
128897
|
+
Accept: "application/json",
|
|
128898
|
+
Authorization: `Bearer ${options2.authToken}`
|
|
128899
|
+
}
|
|
128900
|
+
});
|
|
128901
|
+
if (!response.ok) {
|
|
128902
|
+
throw new AuthSessionError("Failed to generate tenant OpenAPI spec via authenticated endpoint.", {
|
|
128903
|
+
tenantId,
|
|
128904
|
+
sourceUrl: apiUrl,
|
|
128905
|
+
status: response.status,
|
|
128906
|
+
statusText: response.statusText
|
|
128907
|
+
});
|
|
128908
|
+
}
|
|
128909
|
+
return await parseOpenApiJsonResponse(response, {
|
|
128910
|
+
tenantId,
|
|
128911
|
+
sourceUrl: apiUrl
|
|
128912
|
+
});
|
|
128913
|
+
}
|
|
128625
128914
|
getTenantOpenApiFilePath(tenantId) {
|
|
128626
128915
|
const normalizedTenantId = tenantId.trim();
|
|
128627
128916
|
if (!normalizedTenantId) {
|
|
@@ -128630,7 +128919,7 @@ var TenantOpenApiService = class {
|
|
|
128630
128919
|
const rootPath = this.params?.rootPath || TENANT_OPENAPI_ROOT_PATH;
|
|
128631
128920
|
return (0, import_node_path9.join)(rootPath, normalizedTenantId, "openapi.json");
|
|
128632
128921
|
}
|
|
128633
|
-
async downloadTenantOpenApi(tenantId) {
|
|
128922
|
+
async downloadTenantOpenApi(tenantId, options2 = {}) {
|
|
128634
128923
|
const normalizedTenantId = tenantId.trim();
|
|
128635
128924
|
if (!normalizedTenantId) {
|
|
128636
128925
|
throw new AuthSessionError("Tenant ID is required to download OpenAPI spec.");
|
|
@@ -128643,35 +128932,34 @@ var TenantOpenApiService = class {
|
|
|
128643
128932
|
method: "GET"
|
|
128644
128933
|
});
|
|
128645
128934
|
if (!response.ok) {
|
|
128646
|
-
|
|
128647
|
-
|
|
128648
|
-
|
|
128649
|
-
|
|
128650
|
-
|
|
128935
|
+
if (response.status !== 404) {
|
|
128936
|
+
throw new AuthSessionError("Failed to download tenant OpenAPI spec.", {
|
|
128937
|
+
tenantId: normalizedTenantId,
|
|
128938
|
+
sourceUrl,
|
|
128939
|
+
status: response.status,
|
|
128940
|
+
statusText: response.statusText
|
|
128941
|
+
});
|
|
128942
|
+
}
|
|
128943
|
+
const generatedSpec = await this.#generateTenantOpenApiViaAuthenticatedEndpoint(normalizedTenantId, options2);
|
|
128944
|
+
const retryResponse = await (this.params?.fetchFn || fetch)(sourceUrl, {
|
|
128945
|
+
method: "GET"
|
|
128651
128946
|
});
|
|
128652
|
-
|
|
128653
|
-
|
|
128654
|
-
|
|
128655
|
-
|
|
128656
|
-
|
|
128657
|
-
|
|
128658
|
-
throw new AuthSessionError("Downloaded tenant OpenAPI spec is invalid JSON.", {
|
|
128947
|
+
const parsedContent2 = retryResponse.ok ? await parseOpenApiJsonResponse(retryResponse, {
|
|
128948
|
+
tenantId: normalizedTenantId,
|
|
128949
|
+
sourceUrl
|
|
128950
|
+
}) : generatedSpec;
|
|
128951
|
+
const filePath2 = await this.#writeOpenApiFile(normalizedTenantId, parsedContent2);
|
|
128952
|
+
return {
|
|
128659
128953
|
tenantId: normalizedTenantId,
|
|
128660
128954
|
sourceUrl,
|
|
128661
|
-
|
|
128662
|
-
}
|
|
128955
|
+
filePath: filePath2
|
|
128956
|
+
};
|
|
128663
128957
|
}
|
|
128664
|
-
const
|
|
128665
|
-
|
|
128666
|
-
|
|
128667
|
-
mode: 448
|
|
128668
|
-
});
|
|
128669
|
-
await (0, import_promises7.writeFile)(filePath, `${JSON.stringify(parsedContent, null, 2)}
|
|
128670
|
-
`, {
|
|
128671
|
-
encoding: "utf8",
|
|
128672
|
-
mode: 384
|
|
128958
|
+
const parsedContent = await parseOpenApiJsonResponse(response, {
|
|
128959
|
+
tenantId: normalizedTenantId,
|
|
128960
|
+
sourceUrl
|
|
128673
128961
|
});
|
|
128674
|
-
await (
|
|
128962
|
+
const filePath = await this.#writeOpenApiFile(normalizedTenantId, parsedContent);
|
|
128675
128963
|
return {
|
|
128676
128964
|
tenantId: normalizedTenantId,
|
|
128677
128965
|
sourceUrl,
|
|
@@ -128698,6 +128986,7 @@ var ROOT_HELP_COMMANDS = [
|
|
|
128698
128986
|
{ command: "discover search <terms>", description: "Search in endpoint paths and entity names" },
|
|
128699
128987
|
{ command: "ds list <appSlug> <dataSourceSlug>", description: "List data source items" },
|
|
128700
128988
|
{ command: "apps list", description: "List apps" },
|
|
128989
|
+
{ command: "apps delete --appId <id>", description: "Archive an app" },
|
|
128701
128990
|
{ command: "studio list-data-sources --appSlug <slug>", description: "List studio data sources" },
|
|
128702
128991
|
{ command: "tui", description: "Launch terminal UI (OpenTUI, requires Bun)" },
|
|
128703
128992
|
{ command: "curl <path>", description: "Send arbitrary API requests" }
|
|
@@ -128773,6 +129062,7 @@ function createDocyrusCli(params) {
|
|
|
128773
129062
|
}));
|
|
128774
129063
|
cli2.command(createDiscoverCli({
|
|
128775
129064
|
environmentConfigService,
|
|
129065
|
+
createAuthSessionService,
|
|
128776
129066
|
authStore,
|
|
128777
129067
|
tenantOpenApiService
|
|
128778
129068
|
}));
|