specli 0.0.26 → 0.0.28
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/cli/main.js +1 -1
- package/dist/cli/model/naming.js +83 -4
- package/package.json +1 -1
package/dist/cli/main.js
CHANGED
|
@@ -179,7 +179,7 @@ export async function main(argv, options = {}) {
|
|
|
179
179
|
const args = op.pathArgs.length
|
|
180
180
|
? ` ${op.pathArgs.map((a) => `<${a}>`).join(" ")}`
|
|
181
181
|
: "";
|
|
182
|
-
process.stdout.write(`-
|
|
182
|
+
process.stdout.write(`- ${program.name()} ${op.resource} ${op.action}${args}\n`);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
});
|
package/dist/cli/model/naming.js
CHANGED
|
@@ -86,6 +86,88 @@ function inferResource(op) {
|
|
|
86
86
|
const cleaned = first.replace(/^\{.+\}$/, "");
|
|
87
87
|
return pluralize(kebabCase(cleaned || "api"));
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Extracts a meaningful disambiguator from an operationId by removing
|
|
91
|
+
* redundant parts that are already represented in the command name.
|
|
92
|
+
*
|
|
93
|
+
* Examples:
|
|
94
|
+
* - "createDeployment" with action "create" and resource "deployments" -> null (no extra info)
|
|
95
|
+
* - "uploadDeploymentFiles" with action "create" and resource "deployments" -> "upload-files"
|
|
96
|
+
* - "getDeploymentEvents" with action "get" and resource "deployments" -> "events"
|
|
97
|
+
*/
|
|
98
|
+
function extractDisambiguator(operationId, action, resource) {
|
|
99
|
+
// Convert to kebab for consistent comparison
|
|
100
|
+
let name = kebabCase(operationId);
|
|
101
|
+
// Remove action prefix if it matches the command's action or its synonyms
|
|
102
|
+
// This avoids redundancy like "get-get-deployment" or "get-list-files"
|
|
103
|
+
const actionSynonyms = {
|
|
104
|
+
get: ["get", "retrieve", "read", "list", "search"],
|
|
105
|
+
list: ["list", "search", "get"],
|
|
106
|
+
create: ["create", "post"],
|
|
107
|
+
update: ["update", "patch", "put"],
|
|
108
|
+
delete: ["delete", "remove"],
|
|
109
|
+
};
|
|
110
|
+
const synonyms = actionSynonyms[action] ?? [action];
|
|
111
|
+
for (const synonym of synonyms) {
|
|
112
|
+
if (name.startsWith(`${synonym}-`)) {
|
|
113
|
+
name = name.slice(synonym.length + 1);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Remove resource name (singular and plural forms) from anywhere in the string
|
|
118
|
+
const singularResource = resource.replace(/s$/, "");
|
|
119
|
+
const resourcePatterns = [resource, singularResource];
|
|
120
|
+
for (const pattern of resourcePatterns) {
|
|
121
|
+
// Remove from start: "deployment-events" -> "events"
|
|
122
|
+
if (name.startsWith(`${pattern}-`)) {
|
|
123
|
+
name = name.slice(pattern.length + 1);
|
|
124
|
+
}
|
|
125
|
+
// Remove from middle: "upload-deployment-files" -> "upload-files"
|
|
126
|
+
else if (name.includes(`-${pattern}-`)) {
|
|
127
|
+
name = name.replace(`-${pattern}-`, "-");
|
|
128
|
+
}
|
|
129
|
+
// Remove from end: "upload-deployment" -> "upload"
|
|
130
|
+
else if (name.endsWith(`-${pattern}`)) {
|
|
131
|
+
name = name.slice(0, -(pattern.length + 1));
|
|
132
|
+
}
|
|
133
|
+
// Exact match means no extra info
|
|
134
|
+
if (name === pattern) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// If nothing meaningful remains, return null
|
|
139
|
+
if (!name || name === action)
|
|
140
|
+
return null;
|
|
141
|
+
return name;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Derives a disambiguated action name for colliding operations.
|
|
145
|
+
* Tries to create meaningful names like "get-events" instead of "get-get-deployment-events-1".
|
|
146
|
+
*/
|
|
147
|
+
function deriveDisambiguatedAction(op, idx) {
|
|
148
|
+
if (op.operationId) {
|
|
149
|
+
const disambiguator = extractDisambiguator(op.operationId, op.action, op.resource);
|
|
150
|
+
if (disambiguator) {
|
|
151
|
+
// Use the disambiguator directly as action: "upload-files", "get-events"
|
|
152
|
+
return `${op.action}-${disambiguator}`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Fallback: try to extract something from the path
|
|
156
|
+
const segments = getPathSegments(op.path);
|
|
157
|
+
// Look for the last non-parameter segment that isn't the resource
|
|
158
|
+
const singularResource = op.resource.replace(/s$/, "");
|
|
159
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
160
|
+
const seg = segments[i];
|
|
161
|
+
if (!seg || seg.startsWith("{"))
|
|
162
|
+
continue;
|
|
163
|
+
const kebabSeg = kebabCase(seg);
|
|
164
|
+
if (kebabSeg !== op.resource && kebabSeg !== singularResource) {
|
|
165
|
+
return `${op.action}-${kebabSeg}`;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Last resort: append numeric suffix
|
|
169
|
+
return `${op.action}-${idx}`;
|
|
170
|
+
}
|
|
89
171
|
function canonicalizeAction(action) {
|
|
90
172
|
const a = kebabCase(action);
|
|
91
173
|
// Common RPC verbs -> REST canonical verbs
|
|
@@ -178,10 +260,7 @@ export function planOperations(ops) {
|
|
|
178
260
|
return op;
|
|
179
261
|
const idx = (seen.get(key) ?? 0) + 1;
|
|
180
262
|
seen.set(key, idx);
|
|
181
|
-
const
|
|
182
|
-
? kebabCase(op.operationId)
|
|
183
|
-
: kebabCase(`${op.method}-${op.path}`);
|
|
184
|
-
const disambiguatedAction = `${op.action}-${suffix}-${idx}`;
|
|
263
|
+
const disambiguatedAction = deriveDisambiguatedAction(op, idx);
|
|
185
264
|
return {
|
|
186
265
|
...op,
|
|
187
266
|
action: disambiguatedAction,
|