@docyrus/docyrus 0.0.15 → 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 +165 -39
- 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",
|
|
@@ -126227,7 +126227,7 @@ function parseOpenApiDocument(raw) {
|
|
|
126227
126227
|
}
|
|
126228
126228
|
return parsed;
|
|
126229
126229
|
}
|
|
126230
|
-
async function loadOpenApiSpec(dependencies, tenantId) {
|
|
126230
|
+
async function loadOpenApiSpec(dependencies, tenantId, options2) {
|
|
126231
126231
|
let filePath = dependencies.tenantOpenApiService.getTenantOpenApiFilePath(tenantId);
|
|
126232
126232
|
let downloaded = false;
|
|
126233
126233
|
let sourceUrl;
|
|
@@ -126241,7 +126241,7 @@ async function loadOpenApiSpec(dependencies, tenantId) {
|
|
|
126241
126241
|
cause: error48
|
|
126242
126242
|
});
|
|
126243
126243
|
}
|
|
126244
|
-
const downloadResult = await dependencies.tenantOpenApiService.downloadTenantOpenApi(tenantId);
|
|
126244
|
+
const downloadResult = await dependencies.tenantOpenApiService.downloadTenantOpenApi(tenantId, options2);
|
|
126245
126245
|
downloaded = true;
|
|
126246
126246
|
sourceUrl = downloadResult.sourceUrl;
|
|
126247
126247
|
filePath = downloadResult.filePath;
|
|
@@ -126260,11 +126260,15 @@ async function withActiveTenantSpec(dependencies) {
|
|
|
126260
126260
|
if (!activeProfile) {
|
|
126261
126261
|
throw new AuthSessionError("No active session found. Run 'docyrus auth login'.");
|
|
126262
126262
|
}
|
|
126263
|
-
const
|
|
126263
|
+
const authSessionService = dependencies.createAuthSessionService(apiBaseUrl);
|
|
126264
|
+
const authToken = await authSessionService.getValidAccessToken();
|
|
126264
126265
|
return {
|
|
126265
126266
|
apiBaseUrl,
|
|
126266
126267
|
activeProfile,
|
|
126267
|
-
spec
|
|
126268
|
+
spec: await loadOpenApiSpec(dependencies, activeProfile.tenantId, {
|
|
126269
|
+
apiBaseUrl,
|
|
126270
|
+
authToken
|
|
126271
|
+
})
|
|
126268
126272
|
};
|
|
126269
126273
|
}
|
|
126270
126274
|
function createDiscoverCli(dependencies) {
|
|
@@ -126280,7 +126284,12 @@ function createDiscoverCli(dependencies) {
|
|
|
126280
126284
|
if (!activeProfile) {
|
|
126281
126285
|
throw new AuthSessionError("No active session found. Run 'docyrus auth login'.");
|
|
126282
126286
|
}
|
|
126283
|
-
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
|
+
});
|
|
126284
126293
|
return await injectContext({
|
|
126285
126294
|
apiBaseUrl,
|
|
126286
126295
|
authStore: dependencies.authStore,
|
|
@@ -126753,6 +126762,65 @@ function requireNonEmptyObject(payload, label) {
|
|
|
126753
126762
|
throw new UserInputError(`${label} payload is empty. Provide flags, --data, or --from-file.`);
|
|
126754
126763
|
}
|
|
126755
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
|
+
}
|
|
126756
126824
|
function createStudioCli(dependencies) {
|
|
126757
126825
|
const studioCli = Cli_exports.create("studio", {
|
|
126758
126826
|
description: "Studio (dev app data source CRUD) commands",
|
|
@@ -127249,10 +127317,11 @@ function createStudioCli(dependencies) {
|
|
|
127249
127317
|
}),
|
|
127250
127318
|
"fields"
|
|
127251
127319
|
);
|
|
127320
|
+
const normalizedPayload = normalizeBatchUpdateFieldsPayload(payload);
|
|
127252
127321
|
const response = await studio.apiClient.request({
|
|
127253
127322
|
method: "PATCH",
|
|
127254
127323
|
path: `/dev/apps/${appId}/data-sources/${dataSourceId}/fields/batch`,
|
|
127255
|
-
body:
|
|
127324
|
+
body: normalizedPayload
|
|
127256
127325
|
});
|
|
127257
127326
|
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
127258
127327
|
}
|
|
@@ -127413,10 +127482,11 @@ function createStudioCli(dependencies) {
|
|
|
127413
127482
|
}),
|
|
127414
127483
|
"enums"
|
|
127415
127484
|
);
|
|
127485
|
+
const normalizedPayload = normalizeUpdateEnumsPayload(payload);
|
|
127416
127486
|
const response = await studio.apiClient.request({
|
|
127417
127487
|
method: "PATCH",
|
|
127418
127488
|
path: `/dev/apps/${appId}/data-sources/${dataSourceId}/fields/${fieldId}/enums`,
|
|
127419
|
-
body:
|
|
127489
|
+
body: normalizedPayload
|
|
127420
127490
|
});
|
|
127421
127491
|
return await wrapStudioPayload(studio.apiBaseUrl, dependencies, response.data);
|
|
127422
127492
|
}
|
|
@@ -127750,7 +127820,7 @@ var ApiClient = class {
|
|
|
127750
127820
|
|
|
127751
127821
|
// src/services/authSession.ts
|
|
127752
127822
|
var DEFAULT_MANUAL_ACCESS_TOKEN_EXPIRY_SECONDS = 3600;
|
|
127753
|
-
function
|
|
127823
|
+
function isRecord6(value) {
|
|
127754
127824
|
return typeof value === "object" && value !== null;
|
|
127755
127825
|
}
|
|
127756
127826
|
function extractRecordValue(record2, keys) {
|
|
@@ -128063,11 +128133,11 @@ var AuthSessionService = class {
|
|
|
128063
128133
|
fetchFn: this.params.fetchFn
|
|
128064
128134
|
});
|
|
128065
128135
|
const payload = response.data;
|
|
128066
|
-
const dataCandidate =
|
|
128067
|
-
if (!
|
|
128136
|
+
const dataCandidate = isRecord6(payload) && isRecord6(payload.data) ? payload.data : payload;
|
|
128137
|
+
if (!isRecord6(dataCandidate)) {
|
|
128068
128138
|
throw new AuthSessionError("Unable to parse /users/me response.");
|
|
128069
128139
|
}
|
|
128070
|
-
const tenantCandidate =
|
|
128140
|
+
const tenantCandidate = isRecord6(dataCandidate.tenant) ? dataCandidate.tenant : void 0;
|
|
128071
128141
|
const userId = extractString3(dataCandidate, ["id", "user_id"]);
|
|
128072
128142
|
const email3 = extractString3(dataCandidate, ["email"]);
|
|
128073
128143
|
const tenantId = tenantCandidate ? extractString3(tenantCandidate, ["id"]) : extractString3(dataCandidate, ["tenant_id", "tenantId"]);
|
|
@@ -128093,13 +128163,13 @@ var AuthSessionService = class {
|
|
|
128093
128163
|
fetchFn: this.params.fetchFn
|
|
128094
128164
|
});
|
|
128095
128165
|
const payload = response.data;
|
|
128096
|
-
const listCandidate = Array.isArray(payload) ? payload :
|
|
128166
|
+
const listCandidate = Array.isArray(payload) ? payload : isRecord6(payload) && Array.isArray(payload.data) ? payload.data : null;
|
|
128097
128167
|
if (!listCandidate) {
|
|
128098
128168
|
throw new AuthSessionError("Unable to parse tenant catalog response.");
|
|
128099
128169
|
}
|
|
128100
128170
|
const mapped = [];
|
|
128101
128171
|
for (const item of listCandidate) {
|
|
128102
|
-
if (!
|
|
128172
|
+
if (!isRecord6(item)) {
|
|
128103
128173
|
continue;
|
|
128104
128174
|
}
|
|
128105
128175
|
const tenantId = extractString3(item, ["id", "tenant_id"]);
|
|
@@ -128781,10 +128851,66 @@ var import_node_path9 = require("node:path");
|
|
|
128781
128851
|
function resolveSourceUrl(tenantId, template) {
|
|
128782
128852
|
return template.replace("{tenantId}", encodeURIComponent(tenantId));
|
|
128783
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
|
+
}
|
|
128784
128868
|
var TenantOpenApiService = class {
|
|
128785
128869
|
constructor(params) {
|
|
128786
128870
|
this.params = params;
|
|
128787
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
|
+
}
|
|
128788
128914
|
getTenantOpenApiFilePath(tenantId) {
|
|
128789
128915
|
const normalizedTenantId = tenantId.trim();
|
|
128790
128916
|
if (!normalizedTenantId) {
|
|
@@ -128793,7 +128919,7 @@ var TenantOpenApiService = class {
|
|
|
128793
128919
|
const rootPath = this.params?.rootPath || TENANT_OPENAPI_ROOT_PATH;
|
|
128794
128920
|
return (0, import_node_path9.join)(rootPath, normalizedTenantId, "openapi.json");
|
|
128795
128921
|
}
|
|
128796
|
-
async downloadTenantOpenApi(tenantId) {
|
|
128922
|
+
async downloadTenantOpenApi(tenantId, options2 = {}) {
|
|
128797
128923
|
const normalizedTenantId = tenantId.trim();
|
|
128798
128924
|
if (!normalizedTenantId) {
|
|
128799
128925
|
throw new AuthSessionError("Tenant ID is required to download OpenAPI spec.");
|
|
@@ -128806,35 +128932,34 @@ var TenantOpenApiService = class {
|
|
|
128806
128932
|
method: "GET"
|
|
128807
128933
|
});
|
|
128808
128934
|
if (!response.ok) {
|
|
128809
|
-
|
|
128810
|
-
|
|
128811
|
-
|
|
128812
|
-
|
|
128813
|
-
|
|
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"
|
|
128814
128946
|
});
|
|
128815
|
-
|
|
128816
|
-
|
|
128817
|
-
|
|
128818
|
-
|
|
128819
|
-
|
|
128820
|
-
|
|
128821
|
-
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 {
|
|
128822
128953
|
tenantId: normalizedTenantId,
|
|
128823
128954
|
sourceUrl,
|
|
128824
|
-
|
|
128825
|
-
}
|
|
128955
|
+
filePath: filePath2
|
|
128956
|
+
};
|
|
128826
128957
|
}
|
|
128827
|
-
const
|
|
128828
|
-
|
|
128829
|
-
|
|
128830
|
-
mode: 448
|
|
128831
|
-
});
|
|
128832
|
-
await (0, import_promises7.writeFile)(filePath, `${JSON.stringify(parsedContent, null, 2)}
|
|
128833
|
-
`, {
|
|
128834
|
-
encoding: "utf8",
|
|
128835
|
-
mode: 384
|
|
128958
|
+
const parsedContent = await parseOpenApiJsonResponse(response, {
|
|
128959
|
+
tenantId: normalizedTenantId,
|
|
128960
|
+
sourceUrl
|
|
128836
128961
|
});
|
|
128837
|
-
await (
|
|
128962
|
+
const filePath = await this.#writeOpenApiFile(normalizedTenantId, parsedContent);
|
|
128838
128963
|
return {
|
|
128839
128964
|
tenantId: normalizedTenantId,
|
|
128840
128965
|
sourceUrl,
|
|
@@ -128937,6 +129062,7 @@ function createDocyrusCli(params) {
|
|
|
128937
129062
|
}));
|
|
128938
129063
|
cli2.command(createDiscoverCli({
|
|
128939
129064
|
environmentConfigService,
|
|
129065
|
+
createAuthSessionService,
|
|
128940
129066
|
authStore,
|
|
128941
129067
|
tenantOpenApiService
|
|
128942
129068
|
}));
|