@zuplo/cli 1.88.0 → 1.90.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 +1 -0
- package/dist/cmds/project/import-openapi.js +41 -0
- package/dist/cmds/project/index.js +4 -3
- package/dist/common/validators/file-system-validator.js +3 -3
- package/dist/project/import-openapi/handler.js +86 -0
- package/dist/project/import-openapi/interfaces.js +8 -0
- package/dist/project/import-openapi/utils.js +223 -0
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a7cdf682-723c-53b1-b20c-0a26e9a504db")}catch(e){}}();
|
|
3
|
+
import { captureEvent } from "../../common/analytics/lib.js";
|
|
4
|
+
import setBlocking from "../../common/output.js";
|
|
5
|
+
import { ZuploProjectValidator } from "../../common/validators/file-system-validator.js";
|
|
6
|
+
import { YargsChecker } from "../../common/validators/lib.js";
|
|
7
|
+
import { importOpenApi, } from "../../project/import-openapi/handler.js";
|
|
8
|
+
export default {
|
|
9
|
+
desc: "Import an OpenAPI file into your Zuplo project",
|
|
10
|
+
command: "import-openapi",
|
|
11
|
+
builder: (yargs) => {
|
|
12
|
+
return yargs
|
|
13
|
+
.option("dir", {
|
|
14
|
+
type: "string",
|
|
15
|
+
describe: "The directory containing your config/routes.json",
|
|
16
|
+
default: ".",
|
|
17
|
+
normalize: true,
|
|
18
|
+
hidden: true,
|
|
19
|
+
})
|
|
20
|
+
.option("prompt", {
|
|
21
|
+
type: "boolean",
|
|
22
|
+
describe: "Prompt for confirmation before importing",
|
|
23
|
+
default: true,
|
|
24
|
+
})
|
|
25
|
+
.option("source", {
|
|
26
|
+
type: "string",
|
|
27
|
+
describe: "The OpenAPI file to import",
|
|
28
|
+
})
|
|
29
|
+
.demandOption(["source"])
|
|
30
|
+
.middleware([setBlocking])
|
|
31
|
+
.check(async (argv) => {
|
|
32
|
+
return await new YargsChecker(new ZuploProjectValidator()).check(argv);
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
handler: async (argv) => {
|
|
36
|
+
await captureEvent({ argv, event: "zup project import-open-api" });
|
|
37
|
+
await importOpenApi(argv);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=import-openapi.js.map
|
|
41
|
+
//# debugId=a7cdf682-723c-53b1-b20c-0a26e9a504db
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e46201b0-8148-5c25-a7c1-7ae7cdc49cbb")}catch(e){}}();
|
|
3
3
|
import { groupHandler } from "../../common/handler.js";
|
|
4
|
+
import importOpenApi from "./import-openapi.js";
|
|
4
5
|
import update from "./update.js";
|
|
5
6
|
const commands = {
|
|
6
7
|
describe: "Project commands",
|
|
7
8
|
command: "project",
|
|
8
9
|
builder: (yargs) => {
|
|
9
|
-
return yargs.command(update).help();
|
|
10
|
+
return yargs.command(update).command(importOpenApi).help();
|
|
10
11
|
},
|
|
11
12
|
handler: groupHandler,
|
|
12
13
|
};
|
|
13
14
|
export default commands;
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
|
15
|
-
//# debugId=
|
|
16
|
+
//# debugId=e46201b0-8148-5c25-a7c1-7ae7cdc49cbb
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5d2da21c-788d-547b-b136-8738ace98ad7")}catch(e){}}();
|
|
3
3
|
import fg from "fast-glob";
|
|
4
4
|
import { existsSync, readdirSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
@@ -16,7 +16,7 @@ export class NotAGitRepoError extends Error {
|
|
|
16
16
|
}
|
|
17
17
|
export class NotAZuploProject extends Error {
|
|
18
18
|
constructor() {
|
|
19
|
-
super("Invalid directory: The current directory is not a Zuplo project.");
|
|
19
|
+
super("Invalid directory: The current directory is not the root of a Zuplo project.");
|
|
20
20
|
Object.setPrototypeOf(this, NotAZuploProject.prototype);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -163,4 +163,4 @@ export const validDeployDirectoryValidator = new CompositeValidator(new ZuploPro
|
|
|
163
163
|
export const validTestDirectoryValidator = new CompositeValidator(new ZuploProjectValidator(), new ZuploProjectHasTestsValidator());
|
|
164
164
|
export const validLinkDirectoryValidator = new CompositeValidator(new ZuploProjectValidator(), new UserIsLoggedInValidator());
|
|
165
165
|
//# sourceMappingURL=file-system-validator.js.map
|
|
166
|
-
//# debugId=
|
|
166
|
+
//# debugId=5d2da21c-788d-547b-b136-8738ace98ad7
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7a8f9c9d-06a4-50e2-963a-5a23166de5eb")}catch(e){}}();
|
|
3
|
+
import { confirm } from "@inquirer/prompts";
|
|
4
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { basename, extname, join, relative } from "node:path";
|
|
7
|
+
import prettier from "prettier";
|
|
8
|
+
import { printCriticalFailureToConsoleAndExit, printDiagnosticsToConsole, printResultToConsoleAndExitGracefully, } from "../../common/output.js";
|
|
9
|
+
import { addOperationIdsAsNecessary, generateMergeChangeset, parseOpenApiFile, } from "./utils.js";
|
|
10
|
+
const BASE_TEMPLATE = `
|
|
11
|
+
{
|
|
12
|
+
"openapi": "3.1.0",
|
|
13
|
+
"info": {
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"title": "My Zuplo API"
|
|
16
|
+
},
|
|
17
|
+
"paths": {}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
`;
|
|
21
|
+
export async function importOpenApi(argv) {
|
|
22
|
+
const filePath = argv.source;
|
|
23
|
+
const normalizedFilePath = join(relative(process.cwd(), filePath));
|
|
24
|
+
if (!existsSync(normalizedFilePath)) {
|
|
25
|
+
printCriticalFailureToConsoleAndExit(`The file ${normalizedFilePath} to import does not exist.`);
|
|
26
|
+
}
|
|
27
|
+
const rawOpenApiSpec = await readFile(normalizedFilePath);
|
|
28
|
+
const extName = extname(normalizedFilePath);
|
|
29
|
+
const basePath = basename(normalizedFilePath, extName);
|
|
30
|
+
const fileContent = rawOpenApiSpec.toString();
|
|
31
|
+
const parsedOpenApiSpec = await parseOpenApiFile(extName, fileContent);
|
|
32
|
+
const destinationFilePath = join(process.cwd(), "config", `${basePath.replace("oas", "")}.oas.json`);
|
|
33
|
+
let originalDocument;
|
|
34
|
+
if (!existsSync(destinationFilePath)) {
|
|
35
|
+
originalDocument = (await parseOpenApiFile(".json", BASE_TEMPLATE));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const existingOpenApiSpec = await readFile(destinationFilePath);
|
|
39
|
+
const existingFileContent = existingOpenApiSpec.toString();
|
|
40
|
+
originalDocument = (await parseOpenApiFile(extName, existingFileContent));
|
|
41
|
+
}
|
|
42
|
+
const { created, merged, retained } = generateMergeChangeset(originalDocument, parsedOpenApiSpec);
|
|
43
|
+
printDiagnosticsToConsole("This import will...");
|
|
44
|
+
printDiagnosticsToConsole("");
|
|
45
|
+
if (created.size > 0) {
|
|
46
|
+
printDiagnosticsToConsole(`Create ${created.size} new ${created.size > 1 ? "operations" : "operation"}`);
|
|
47
|
+
printDiagnosticsToConsole("");
|
|
48
|
+
created.forEach((operation) => {
|
|
49
|
+
printDiagnosticsToConsole(operation);
|
|
50
|
+
});
|
|
51
|
+
printDiagnosticsToConsole("");
|
|
52
|
+
}
|
|
53
|
+
if (merged.size > 0) {
|
|
54
|
+
printDiagnosticsToConsole(`Merge ${merged.size} new ${merged.size > 1 ? "operations" : "operation"}`);
|
|
55
|
+
printDiagnosticsToConsole("");
|
|
56
|
+
merged.forEach((operation) => {
|
|
57
|
+
printDiagnosticsToConsole(operation);
|
|
58
|
+
});
|
|
59
|
+
printDiagnosticsToConsole("");
|
|
60
|
+
}
|
|
61
|
+
if (retained.size > 0) {
|
|
62
|
+
printDiagnosticsToConsole(`Retain ${retained.size} new ${retained.size > 1 ? "operations" : "operation"}`);
|
|
63
|
+
printDiagnosticsToConsole("");
|
|
64
|
+
retained.forEach((operation) => {
|
|
65
|
+
printDiagnosticsToConsole(operation);
|
|
66
|
+
});
|
|
67
|
+
printDiagnosticsToConsole("");
|
|
68
|
+
}
|
|
69
|
+
if (argv.prompt) {
|
|
70
|
+
printDiagnosticsToConsole("");
|
|
71
|
+
const answer = await confirm({ message: "Proceed?", default: true });
|
|
72
|
+
if (!answer) {
|
|
73
|
+
printResultToConsoleAndExitGracefully("Import cancelled.");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
addOperationIdsAsNecessary(parsedOpenApiSpec);
|
|
77
|
+
const formattedOpenApi = prettier.format(JSON.stringify(parsedOpenApiSpec), {
|
|
78
|
+
parser: "json-stringify",
|
|
79
|
+
});
|
|
80
|
+
writeFileSync(destinationFilePath, formattedOpenApi, {
|
|
81
|
+
flag: "w",
|
|
82
|
+
});
|
|
83
|
+
printResultToConsoleAndExitGracefully(`Import successful. File written to ${destinationFilePath}`);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=handler.js.map
|
|
86
|
+
//# debugId=7a8f9c9d-06a4-50e2-963a-5a23166de5eb
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b14028c7-4667-5a33-8f2d-e6c8216e26eb")}catch(e){}}();
|
|
3
|
+
export const ZUPLO_OPEN_API_VENDOR_PREFIX = "x-zuplo";
|
|
4
|
+
export const OPEN_API_INTERNAL_PROPERTY_VENDOR_TAG = "x-internal";
|
|
5
|
+
export const ZUPLO_OPEN_API_PATH_KEY = `${ZUPLO_OPEN_API_VENDOR_PREFIX}-path`;
|
|
6
|
+
export const ZUPLO_OPEN_API_ROUTE_KEY = `${ZUPLO_OPEN_API_VENDOR_PREFIX}-route`;
|
|
7
|
+
//# sourceMappingURL=interfaces.js.map
|
|
8
|
+
//# debugId=b14028c7-4667-5a33-8f2d-e6c8216e26eb
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c089ea78-2efe-51c0-aa97-d386b8b87324")}catch(e){}}();
|
|
3
|
+
import yaml from "js-yaml";
|
|
4
|
+
import { v4 } from "uuid";
|
|
5
|
+
import { ZUPLO_OPEN_API_PATH_KEY, ZUPLO_OPEN_API_ROUTE_KEY, } from "./interfaces.js";
|
|
6
|
+
export const OPERATION_PATH_MERGE_DELIMITER = ">";
|
|
7
|
+
export const OPEN_API_FILE_TYPES = [".json", ".yml", ".yaml"];
|
|
8
|
+
export const parseOpenApiFile = async (extName, fileText) => {
|
|
9
|
+
if (!OPEN_API_FILE_TYPES.includes(extName)) {
|
|
10
|
+
throw new Error(`Invalid file type. Supported file types are: ${OPEN_API_FILE_TYPES.join(", ")}`);
|
|
11
|
+
}
|
|
12
|
+
if (extName.includes("json")) {
|
|
13
|
+
return JSON.parse(fileText);
|
|
14
|
+
}
|
|
15
|
+
return yaml.load(fileText);
|
|
16
|
+
};
|
|
17
|
+
export const addOperationIdsAsNecessary = (openApi) => {
|
|
18
|
+
const paths = openApi.paths;
|
|
19
|
+
if (!paths) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
for (const path of Object.keys(paths)) {
|
|
23
|
+
const pathItem = paths[path];
|
|
24
|
+
if (!pathItem) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const methods = [
|
|
28
|
+
"get",
|
|
29
|
+
"put",
|
|
30
|
+
"post",
|
|
31
|
+
"delete",
|
|
32
|
+
"options",
|
|
33
|
+
"head",
|
|
34
|
+
"patch",
|
|
35
|
+
"trace",
|
|
36
|
+
];
|
|
37
|
+
for (const method of methods) {
|
|
38
|
+
const operation = pathItem[method];
|
|
39
|
+
if (operation && !operation.operationId) {
|
|
40
|
+
operation.operationId = v4();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export const mergeOpenApiDocuments = (originalDocument, newDocument) => {
|
|
46
|
+
return mergeOpenApiDocumentOnPathMethod(originalDocument, newDocument);
|
|
47
|
+
};
|
|
48
|
+
const mergeOpenApiDocumentOnPathMethod = (originalDocument, newDocument) => {
|
|
49
|
+
let paths = originalDocument.paths;
|
|
50
|
+
if (newDocument.paths) {
|
|
51
|
+
paths = Object.entries(newDocument.paths).reduce((mergedPaths, [path, pathObject]) => {
|
|
52
|
+
const existingEntry = mergedPaths[path];
|
|
53
|
+
if (!existingEntry) {
|
|
54
|
+
mergedPaths[path] = pathObject;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
mergedPaths[path] = mergePathItems(existingEntry, pathObject);
|
|
58
|
+
}
|
|
59
|
+
return mergedPaths;
|
|
60
|
+
}, originalDocument.paths ?? {});
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
info: newDocument.info,
|
|
64
|
+
openapi: mergeOpenApiVersion(originalDocument.openapi, newDocument.openapi),
|
|
65
|
+
components: mergeComponents(originalDocument.components, newDocument.components),
|
|
66
|
+
jsonSchemaDialect: newDocument.jsonSchemaDialect ?? originalDocument.jsonSchemaDialect,
|
|
67
|
+
servers: newDocument.servers ?? originalDocument.servers,
|
|
68
|
+
security: newDocument.security ?? originalDocument.security,
|
|
69
|
+
tags: newDocument.tags ?? originalDocument.tags,
|
|
70
|
+
externalDocs: newDocument.externalDocs ?? originalDocument.externalDocs,
|
|
71
|
+
paths,
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const mergeComponents = (originalComponents, newComponents) => {
|
|
75
|
+
if (!originalComponents) {
|
|
76
|
+
return newComponents;
|
|
77
|
+
}
|
|
78
|
+
if (!newComponents) {
|
|
79
|
+
return originalComponents;
|
|
80
|
+
}
|
|
81
|
+
const { schemas, responses, parameters, examples, requestBodies, headers, securitySchemes, links, callbacks, pathItems, } = originalComponents;
|
|
82
|
+
const { schemas: newSchemas, responses: newResponses, parameters: newParameters, examples: newExamples, requestBodies: newRequestBodies, headers: newHeaders, securitySchemes: newSecuritySchemes, links: newLinks, callbacks: newCallbacks, pathItems: newPathItems, } = newComponents;
|
|
83
|
+
return {
|
|
84
|
+
schemas: schemas ? { ...schemas, ...newSchemas } : newSchemas,
|
|
85
|
+
responses: responses ? { ...responses, ...newResponses } : newResponses,
|
|
86
|
+
parameters: parameters
|
|
87
|
+
? { ...parameters, ...newParameters }
|
|
88
|
+
: newParameters,
|
|
89
|
+
examples: examples ? { ...examples, ...newExamples } : newExamples,
|
|
90
|
+
requestBodies: requestBodies
|
|
91
|
+
? { ...requestBodies, ...newRequestBodies }
|
|
92
|
+
: newRequestBodies,
|
|
93
|
+
headers: headers ? { ...headers, ...newHeaders } : newHeaders,
|
|
94
|
+
securitySchemes: securitySchemes
|
|
95
|
+
? { ...securitySchemes, ...newSecuritySchemes }
|
|
96
|
+
: newSecuritySchemes,
|
|
97
|
+
links: links ? { ...links, ...newLinks } : newLinks,
|
|
98
|
+
callbacks: callbacks ? { ...callbacks, ...newCallbacks } : newCallbacks,
|
|
99
|
+
pathItems: pathItems ? { ...pathItems, ...newPathItems } : newPathItems,
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
const mergeOpenApiVersion = (originalVersion, newDocumentVersion) => {
|
|
103
|
+
if (originalVersion === "3.1.0") {
|
|
104
|
+
return originalVersion;
|
|
105
|
+
}
|
|
106
|
+
if (newDocumentVersion === "3.1.0") {
|
|
107
|
+
return newDocumentVersion;
|
|
108
|
+
}
|
|
109
|
+
return originalVersion;
|
|
110
|
+
};
|
|
111
|
+
const mergePathItems = (originalPathItem, newPathItem) => {
|
|
112
|
+
const { summary, description, get, put, post, delete: deleteOperation, options, head, patch, trace, servers, parameters, } = originalPathItem;
|
|
113
|
+
const zuploPathProperties = originalPathItem[ZUPLO_OPEN_API_PATH_KEY];
|
|
114
|
+
const newZuploPathProperty = typeof newPathItem === "object" &&
|
|
115
|
+
newPathItem !== null &&
|
|
116
|
+
ZUPLO_OPEN_API_PATH_KEY in newPathItem
|
|
117
|
+
? newPathItem[ZUPLO_OPEN_API_PATH_KEY]
|
|
118
|
+
: undefined;
|
|
119
|
+
const { summary: newSummary, description: newDescription, get: newGetOperation, put: newPutOperation, post: newPostOperation, delete: newDeleteOperation, options: newOptionsOperation, head: newHeadOperation, patch: newPatchOperation, trace: newTraceOperation, servers: newServers, parameters: newParameters, } = newPathItem;
|
|
120
|
+
return {
|
|
121
|
+
summary: newSummary ?? summary,
|
|
122
|
+
description: newDescription ?? description,
|
|
123
|
+
[ZUPLO_OPEN_API_PATH_KEY]: newZuploPathProperty ?? zuploPathProperties,
|
|
124
|
+
servers: newServers ?? servers,
|
|
125
|
+
parameters: newParameters ?? parameters,
|
|
126
|
+
get: mergeOperationObjects(get, newGetOperation),
|
|
127
|
+
put: mergeOperationObjects(put, newPutOperation),
|
|
128
|
+
post: mergeOperationObjects(post, newPostOperation),
|
|
129
|
+
delete: mergeOperationObjects(deleteOperation, newDeleteOperation),
|
|
130
|
+
options: mergeOperationObjects(options, newOptionsOperation),
|
|
131
|
+
head: mergeOperationObjects(head, newHeadOperation),
|
|
132
|
+
patch: mergeOperationObjects(patch, newPatchOperation),
|
|
133
|
+
trace: mergeOperationObjects(trace, newTraceOperation),
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
const mergeOperationObjects = (originalOperationObject, newOperationObject) => {
|
|
137
|
+
if (!newOperationObject) {
|
|
138
|
+
return originalOperationObject;
|
|
139
|
+
}
|
|
140
|
+
const originalZuploProperties = originalOperationObject?.[ZUPLO_OPEN_API_ROUTE_KEY];
|
|
141
|
+
return {
|
|
142
|
+
operationId: v4(),
|
|
143
|
+
[ZUPLO_OPEN_API_ROUTE_KEY]: originalZuploProperties,
|
|
144
|
+
...newOperationObject,
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
export const generateMergeChangeset = (originalDocument, newDocument) => {
|
|
148
|
+
return generatePathMethodMergeChangeset(originalDocument, newDocument);
|
|
149
|
+
};
|
|
150
|
+
const generatePathMethodMergeChangeset = (originalDocument, newDocument) => {
|
|
151
|
+
let created = new Set();
|
|
152
|
+
const merged = new Set();
|
|
153
|
+
let retained = new Set();
|
|
154
|
+
const originalPaths = originalDocument.paths;
|
|
155
|
+
const newPaths = newDocument.paths;
|
|
156
|
+
if (!originalPaths && !newPaths) {
|
|
157
|
+
return { created, merged, retained };
|
|
158
|
+
}
|
|
159
|
+
if (!originalPaths && newPaths) {
|
|
160
|
+
created = new Set(getAllOperationKeys(newPaths));
|
|
161
|
+
return { created, merged, retained };
|
|
162
|
+
}
|
|
163
|
+
if (!newPaths && originalPaths) {
|
|
164
|
+
retained = new Set(getAllOperationKeys(originalPaths));
|
|
165
|
+
return { created, merged, retained };
|
|
166
|
+
}
|
|
167
|
+
if (newPaths && originalPaths) {
|
|
168
|
+
const oldOperationKeys = getAllOperationKeys(originalPaths);
|
|
169
|
+
const newOperationKeys = getAllOperationKeys(newPaths);
|
|
170
|
+
const oldOperationKeysSet = new Set(oldOperationKeys);
|
|
171
|
+
const newOperationKeysSet = new Set(newOperationKeys);
|
|
172
|
+
newOperationKeys.forEach((operationKey) => {
|
|
173
|
+
if (oldOperationKeysSet.has(operationKey)) {
|
|
174
|
+
merged.add(operationKey);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
created.add(operationKey);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
oldOperationKeys.forEach((operationKey) => {
|
|
181
|
+
if (!newOperationKeysSet.has(operationKey)) {
|
|
182
|
+
retained.add(operationKey);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return { created, merged, retained };
|
|
187
|
+
};
|
|
188
|
+
const getAllOperationKeys = (pathsObject) => {
|
|
189
|
+
return Object.entries(pathsObject)
|
|
190
|
+
.map(([path, pathObject]) => {
|
|
191
|
+
const pathItemObject = pathObject;
|
|
192
|
+
const { get, put, post, delete: deleteOperation, options, head, patch, trace, } = pathItemObject;
|
|
193
|
+
const operations = [];
|
|
194
|
+
if (get) {
|
|
195
|
+
operations.push("get");
|
|
196
|
+
}
|
|
197
|
+
if (put) {
|
|
198
|
+
operations.push("put");
|
|
199
|
+
}
|
|
200
|
+
if (post) {
|
|
201
|
+
operations.push("post");
|
|
202
|
+
}
|
|
203
|
+
if (deleteOperation) {
|
|
204
|
+
operations.push("delete");
|
|
205
|
+
}
|
|
206
|
+
if (options) {
|
|
207
|
+
operations.push("options");
|
|
208
|
+
}
|
|
209
|
+
if (head) {
|
|
210
|
+
operations.push("head");
|
|
211
|
+
}
|
|
212
|
+
if (patch) {
|
|
213
|
+
operations.push("patch");
|
|
214
|
+
}
|
|
215
|
+
if (trace) {
|
|
216
|
+
operations.push("trace");
|
|
217
|
+
}
|
|
218
|
+
return operations.map((operation) => `${operation}${OPERATION_PATH_MERGE_DELIMITER}${path}`);
|
|
219
|
+
})
|
|
220
|
+
.flat();
|
|
221
|
+
};
|
|
222
|
+
//# sourceMappingURL=utils.js.map
|
|
223
|
+
//# debugId=c089ea78-2efe-51c0-aa97-d386b8b87324
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuplo/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.90.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": "https://github.com/zuplo/cli",
|
|
6
6
|
"description": "The command-line interface for Zuplo",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@sentry/cli": "^2.20.7",
|
|
32
32
|
"@types/chai": "^4.3.4",
|
|
33
|
+
"@types/js-yaml": "^4.0.8",
|
|
33
34
|
"@types/mocha": "^10.0.1",
|
|
34
35
|
"@types/node": "^18.15.11",
|
|
35
36
|
"@types/prettier": "^2.7.2",
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
"@types/semver": "^7.3.13",
|
|
38
39
|
"@types/tar": "^6.1.4",
|
|
39
40
|
"@types/temp": "^0.9.1",
|
|
41
|
+
"@types/uuid": "^9.0.6",
|
|
40
42
|
"@types/yargs": "^17.0.24",
|
|
41
43
|
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
|
42
44
|
"@typescript-eslint/parser": "^5.57.1",
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"husky": "^8.0.3",
|
|
50
52
|
"lint-staged": "^13.2.0",
|
|
51
53
|
"mocha": "^10.2.0",
|
|
54
|
+
"openapi-types": "^12.1.3",
|
|
52
55
|
"prettier-plugin-organize-imports": "^3.2.2",
|
|
53
56
|
"typescript": "^5.2.2"
|
|
54
57
|
},
|
|
@@ -58,9 +61,9 @@
|
|
|
58
61
|
"@inquirer/prompts": "^3.0.4",
|
|
59
62
|
"@sentry/node": "7.69.0",
|
|
60
63
|
"@swc/core": "1.3.78",
|
|
61
|
-
"@zuplo/core": "5.
|
|
64
|
+
"@zuplo/core": "5.1450.0",
|
|
62
65
|
"@zuplo/pino-pretty-configurations": "^1.5.0",
|
|
63
|
-
"@zuplo/runtime": "5.
|
|
66
|
+
"@zuplo/runtime": "5.1450.0",
|
|
64
67
|
"chalk": "^5.1.2",
|
|
65
68
|
"chokidar": "^3.5.3",
|
|
66
69
|
"deno-bin": "1.37.1",
|
|
@@ -73,6 +76,7 @@
|
|
|
73
76
|
"fastify-sse-v2": "^3.1.2",
|
|
74
77
|
"ignore": "^5.2.4",
|
|
75
78
|
"jose": "^4.14.4",
|
|
79
|
+
"js-yaml": "^4.1.0",
|
|
76
80
|
"jsonc-parser": "^3.2.0",
|
|
77
81
|
"open": "^9.1.0",
|
|
78
82
|
"pino": "^8.11.0",
|
|
@@ -85,6 +89,7 @@
|
|
|
85
89
|
"simple-git": "^3.17.0",
|
|
86
90
|
"tar": "^6.1.13",
|
|
87
91
|
"temp": "^0.9.4",
|
|
92
|
+
"uuid": "^9.0.1",
|
|
88
93
|
"yargs": "^17.7.1"
|
|
89
94
|
}
|
|
90
95
|
}
|