Skip to content

Commit

Permalink
perf(spec-parser): update plugin.json name/description (#11200)
Browse files Browse the repository at this point in the history
* perf(spec-parser): update plugin.json name/description

* perf: remove env for name_for_human

---------

Co-authored-by: turenlong <rentu@microsoft.com>
  • Loading branch information
SLdragon and SLdragon authored Mar 27, 2024
1 parent 5335b13 commit 33585d6
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 107 deletions.
22 changes: 20 additions & 2 deletions packages/spec-parser/src/manifestUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,17 @@ export class ManifestUpdater {
},
];

const appName = this.removeEnvs(manifest.name.short);

ManifestUpdater.updateManifestDescription(manifest, spec);

const specRelativePath = ManifestUpdater.getRelativePath(manifestPath, outputSpecPath);
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(spec, specRelativePath, options);
const apiPlugin = ManifestUpdater.generatePluginManifestSchema(
spec,
specRelativePath,
appName,
options
);

return [manifest, apiPlugin];
}
Expand Down Expand Up @@ -80,6 +87,7 @@ export class ManifestUpdater {
static generatePluginManifestSchema(
spec: OpenAPIV3.Document,
specRelativePath: string,
appName: string,
options: ParseOptions
): PluginManifestSchema {
const functions: FunctionObject[] = [];
Expand Down Expand Up @@ -174,7 +182,7 @@ export class ManifestUpdater {

const apiPlugin: PluginManifestSchema = {
schema_version: "v2",
name_for_human: spec.info.title,
name_for_human: appName,
description_for_human: spec.info.description ?? "<Please add description of the plugin>",
functions: functions,
runtimes: [
Expand Down Expand Up @@ -317,4 +325,14 @@ export class ManifestUpdater {
const relativePath = path.relative(path.dirname(from), to);
return path.normalize(relativePath).replace(/\\/g, "/");
}

static removeEnvs(str: string): string {
const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
const matches = placeHolderReg.exec(str);
let newStr = str;
if (matches != null) {
newStr = newStr.replace(matches[0], "");
}
return newStr;
}
}
2 changes: 1 addition & 1 deletion packages/spec-parser/src/specParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export class SpecParser {
);
}

apiResult.server = Utils.resolveServerUrl(serverUrl.url);
apiResult.server = Utils.resolveEnv(serverUrl.url);

let operationId = operation.operationId;
if (!operationId) {
Expand Down
14 changes: 7 additions & 7 deletions packages/spec-parser/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,29 +446,29 @@ export class Utils {
}
}

static resolveServerUrl(url: string): string {
static resolveEnv(str: string): string {
const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
let matches = placeHolderReg.exec(url);
let newUrl = url;
let matches = placeHolderReg.exec(str);
let newStr = str;
while (matches != null) {
const envVar = matches[1];
const envVal = process.env[envVar];
if (!envVal) {
throw new Error(Utils.format(ConstantString.ResolveServerUrlFailed, envVar));
} else {
newUrl = newUrl.replace(matches[0], envVal);
newStr = newStr.replace(matches[0], envVal);
}
matches = placeHolderReg.exec(url);
matches = placeHolderReg.exec(str);
}
return newUrl;
return newStr;
}

static checkServerUrl(servers: OpenAPIV3.ServerObject[]): ErrorResult[] {
const errors: ErrorResult[] = [];

let serverUrl;
try {
serverUrl = Utils.resolveServerUrl(servers[0].url);
serverUrl = Utils.resolveEnv(servers[0].url);
} catch (err) {
errors.push({
type: ErrorType.ResolveServerUrlFailed,
Expand Down
184 changes: 91 additions & 93 deletions packages/spec-parser/test/manifestUpdater.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ describe("updateManifestWithAiPlugin", () => {

const expectedPlugins: PluginManifestSchema = {
schema_version: "v2",
name_for_human: "My API",
name_for_human: "Original Name",
description_for_human: "My API description",
functions: [
{
Expand Down Expand Up @@ -153,7 +153,7 @@ describe("updateManifestWithAiPlugin", () => {
expect(apiPlugin).to.deep.equal(expectedPlugins);
});

it("should update the manifest with the correct manifest and apiPlugin files with optional parameters", async () => {
it("should update the plugin json correctly when contains env in name and description", async () => {
const spec: any = {
openapi: "3.0.2",
info: {
Expand All @@ -180,12 +180,6 @@ describe("updateManifestWithAiPlugin", () => {
type: "integer",
},
},
{
name: "id",
schema: {
type: "string",
},
},
],
},
post: {
Expand Down Expand Up @@ -218,11 +212,14 @@ describe("updateManifestWithAiPlugin", () => {

sinon.stub(fs, "pathExists").resolves(true);
const originalManifest = {
name: { short: "Original Name", full: "Original Full Name" },
description: { short: "Original Short Description", full: "Original Full Description" },
name: { short: "Original Name${{TestEnv}}", full: "Original Full Name" },
description: {
short: "Original Short Description",
full: "Original Full Description${{TestEnv}}",
},
};
const expectedManifest = {
name: { short: "Original Name", full: "Original Full Name" },
name: { short: "Original Name${{TestEnv}}", full: "Original Full Name" },
description: { short: "My API", full: "My API description" },
plugins: [
{
Expand All @@ -233,7 +230,7 @@ describe("updateManifestWithAiPlugin", () => {

const expectedPlugins: PluginManifestSchema = {
schema_version: "v2",
name_for_human: "My API",
name_for_human: "Original Name",
description_for_human: "My API description",
functions: [
{
Expand All @@ -246,10 +243,6 @@ describe("updateManifestWithAiPlugin", () => {
type: "integer",
description: "Maximum number of pets to return",
},
id: {
type: "string",
description: "",
},
},
required: ["limit"],
},
Expand Down Expand Up @@ -283,7 +276,6 @@ describe("updateManifestWithAiPlugin", () => {
],
};
sinon.stub(fs, "readJSON").resolves(originalManifest);

const options: ParseOptions = {
allowMethods: ["get", "post"],
};
Expand All @@ -299,7 +291,7 @@ describe("updateManifestWithAiPlugin", () => {
expect(apiPlugin).to.deep.equal(expectedPlugins);
});

it("should generate default ai plugin file if no api", async () => {
it("should update the manifest with the correct manifest and apiPlugin files with optional parameters", async () => {
const spec: any = {
openapi: "3.0.2",
info: {
Expand All @@ -311,74 +303,6 @@ describe("updateManifestWithAiPlugin", () => {
url: "/v3",
},
],
paths: {},
};
const manifestPath = "/path/to/your/manifest.json";
const outputSpecPath = "/path/to/your/spec/outputSpec.yaml";
const pluginFilePath = "/path/to/your/ai-plugin.json";

sinon.stub(fs, "pathExists").resolves(true);
const originalManifest = {
name: { short: "Original Name", full: "Original Full Name" },
description: { short: "Original Short Description", full: "Original Full Description" },
};
const expectedManifest = {
name: { short: "Original Name", full: "Original Full Name" },
description: { short: "My API", full: "My API description" },
plugins: [
{
pluginFile: "ai-plugin.json",
},
],
};

const expectedPlugins: PluginManifestSchema = {
schema_version: "v2",
name_for_human: "My API",
description_for_human: "My API description",
functions: [],
runtimes: [
{
type: "OpenApi",
auth: {
type: "none",
},
spec: {
url: "spec/outputSpec.yaml",
},
run_for_functions: [],
},
],
};
sinon.stub(fs, "readJSON").resolves(originalManifest);
const options: ParseOptions = {
allowMethods: ["get", "post"],
};
const [manifest, apiPlugin] = await ManifestUpdater.updateManifestWithAiPlugin(
manifestPath,
outputSpecPath,
pluginFilePath,
spec,
options
);

expect(manifest).to.deep.equal(expectedManifest);
expect(apiPlugin).to.deep.equal(expectedPlugins);
});

it("should truncate if title is long", async () => {
const spec: any = {
openapi: "3.0.2",
info: {
title:
"long title long title long title long title long title long title long title long title long title long title long title long title",
description: "This is the description",
},
servers: [
{
url: "/v3",
},
],
paths: {
"/pets": {
get: {
Expand All @@ -394,6 +318,12 @@ describe("updateManifestWithAiPlugin", () => {
type: "integer",
},
},
{
name: "id",
schema: {
type: "string",
},
},
],
},
post: {
Expand Down Expand Up @@ -431,10 +361,7 @@ describe("updateManifestWithAiPlugin", () => {
};
const expectedManifest = {
name: { short: "Original Name", full: "Original Full Name" },
description: {
short: "long title long title long title long title long title long title long title lon",
full: "This is the description",
},
description: { short: "My API", full: "My API description" },
plugins: [
{
pluginFile: "ai-plugin.json",
Expand All @@ -444,9 +371,8 @@ describe("updateManifestWithAiPlugin", () => {

const expectedPlugins: PluginManifestSchema = {
schema_version: "v2",
name_for_human:
"long title long title long title long title long title long title long title long title long title long title long title long title",
description_for_human: "This is the description",
name_for_human: "Original Name",
description_for_human: "My API description",
functions: [
{
name: "getPets",
Expand All @@ -458,6 +384,10 @@ describe("updateManifestWithAiPlugin", () => {
type: "integer",
description: "Maximum number of pets to return",
},
id: {
type: "string",
description: "",
},
},
required: ["limit"],
},
Expand Down Expand Up @@ -491,6 +421,74 @@ describe("updateManifestWithAiPlugin", () => {
],
};
sinon.stub(fs, "readJSON").resolves(originalManifest);

const options: ParseOptions = {
allowMethods: ["get", "post"],
};
const [manifest, apiPlugin] = await ManifestUpdater.updateManifestWithAiPlugin(
manifestPath,
outputSpecPath,
pluginFilePath,
spec,
options
);

expect(manifest).to.deep.equal(expectedManifest);
expect(apiPlugin).to.deep.equal(expectedPlugins);
});

it("should generate default ai plugin file if no api", async () => {
const spec: any = {
openapi: "3.0.2",
info: {
title: "My API",
description: "My API description",
},
servers: [
{
url: "/v3",
},
],
paths: {},
};
const manifestPath = "/path/to/your/manifest.json";
const outputSpecPath = "/path/to/your/spec/outputSpec.yaml";
const pluginFilePath = "/path/to/your/ai-plugin.json";

sinon.stub(fs, "pathExists").resolves(true);
const originalManifest = {
name: { short: "Original Name", full: "Original Full Name" },
description: { short: "Original Short Description", full: "Original Full Description" },
};
const expectedManifest = {
name: { short: "Original Name", full: "Original Full Name" },
description: { short: "My API", full: "My API description" },
plugins: [
{
pluginFile: "ai-plugin.json",
},
],
};

const expectedPlugins: PluginManifestSchema = {
schema_version: "v2",
name_for_human: "Original Name",
description_for_human: "My API description",
functions: [],
runtimes: [
{
type: "OpenApi",
auth: {
type: "none",
},
spec: {
url: "spec/outputSpec.yaml",
},
run_for_functions: [],
},
],
};
sinon.stub(fs, "readJSON").resolves(originalManifest);
const options: ParseOptions = {
allowMethods: ["get", "post"],
};
Expand Down
Loading

0 comments on commit 33585d6

Please sign in to comment.