-
Notifications
You must be signed in to change notification settings - Fork 149
Expand file tree
/
Copy pathexecuteEventGridFunction.ts
More file actions
156 lines (139 loc) · 6.29 KB
/
executeEventGridFunction.ts
File metadata and controls
156 lines (139 loc) · 6.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { type IActionContext, type IAzureQuickPickItem } from '@microsoft/vscode-azext-utils';
import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import * as vscode from 'vscode';
import { localize } from '../../localize';
import { type FunctionTreeItemBase } from '../../tree/FunctionTreeItemBase';
import { feedUtils } from '../../utils/feedUtils';
import { type IFunction } from '../../workspace/LocalFunction';
import { supportedEventGridSourceLabels, supportedEventGridSources, type EventGridSource } from './eventGridSources';
import { executeFunctionWithInput } from './executeFunction';
type FileMetadata = {
name: string;
path: string;
sha: string;
size: number;
url: string;
html_url: string;
git_url: string;
download_url: string;
type: string;
_links: {
self: string;
git: string;
html: string;
};
};
const sampleFilesUrl =
'https://api.github.com/repos/Azure/azure-rest-api-specs/contents/specification/eventgrid/data-plane/' +
'{eventSource}' +
'/stable/2018-01-01/examples/cloud-events-schema/';
export async function executeEventGridFunction(context: IActionContext, node: FunctionTreeItemBase | IFunction): Promise<void> {
// Prompt for event source
const eventGridSourcePicks: IAzureQuickPickItem<EventGridSource | undefined>[] = supportedEventGridSources.map((source: EventGridSource) => {
return {
label: supportedEventGridSourceLabels.get(source) || source,
data: source,
};
});
const eventSource: EventGridSource =
(
await context.ui.showQuickPick(eventGridSourcePicks, {
placeHolder: localize('selectEventSource', 'Select the event source'),
stepName: 'eventGridSource',
})
).data ?? 'Microsoft.Storage';
// Get sample files for event source
const samplesUrl = sampleFilesUrl.replace('{eventSource}', eventSource);
const sampleFiles: FileMetadata[] = await feedUtils.getJsonFeed(context, samplesUrl);
const fileNames: string[] = sampleFiles.map((fileMetadata) => fileMetadata.name);
// Prompt for event type
const eventTypePicks: IAzureQuickPickItem<string | undefined>[] = fileNames.map((name: string) => ({
data: name,
// give human-readable name for event type from file name
label: name
.replace(/\.json$/, '')
.split('_')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' '),
}));
const selectedFileName: string =
(
await context.ui.showQuickPick(eventTypePicks, {
placeHolder: localize('selectEventType', 'Select the event type'),
stepName: 'eventType',
})
).data ?? 'blob_created.json';
// Get selected contents of sample request
const selectedFileUrl = sampleFiles.find((fileMetadata) => fileMetadata.name === selectedFileName)?.download_url || sampleFiles[0].download_url;
const selectedFileContents: {} = await feedUtils.getJsonFeed(context, selectedFileUrl);
// Prompt for whether to send or modify the sample request
const shouldModify: boolean =
(
await context.ui.showQuickPick(
[
{
label: localize('sendSample', 'Send sample request'),
data: false,
},
{
label: localize('modifySample', 'Modify sample request'),
data: true,
},
],
{
placeHolder: 'Would you like to send the sample request or modify it first?',
stepName: 'modifyOrSendSample',
},
)
).data || false;
// Execute function with sample data directly if user chooses not to modify
if (!shouldModify) {
return executeFunctionWithInput(context, selectedFileContents, node);
}
// Create a temp file with the sample request & open in new window
const tempFilePath: string = await createTempSampleFile(eventSource, selectedFileName, selectedFileContents);
const document: vscode.TextDocument = await vscode.workspace.openTextDocument(tempFilePath);
await vscode.window.showTextDocument(document, {
preview: false,
});
// Request will be sent when the user clicks on the button or on the codelens link
// Set a listener to delete the temp file after it's closed
await new Promise<void>((resolve, reject) => {
const disposable = vscode.workspace.onDidCloseTextDocument(async (closedDocument) => {
if (closedDocument.fileName === document.fileName) {
try {
await fs.unlink(tempFilePath);
resolve();
} catch (error) {
reject(error);
} finally {
disposable.dispose();
}
}
});
});
}
async function createTempSampleFile(eventSource: string, fileName: string, contents: {}): Promise<string> {
const samplesDirPath = await createSamplesDirIfNotExists(eventSource);
const sampleFileName = fileName.replace(/\.json$/, '.eventgrid.json');
const filePath: string = path.join(samplesDirPath, sampleFileName);
await fs.writeFile(filePath, JSON.stringify(contents, undefined, 2));
return filePath;
}
async function createSamplesDirIfNotExists(eventSource: string): Promise<string> {
const baseDir: string = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath || path.join(os.tmpdir(), 'vscode', 'azureFunctions');
// Create the path to the directory
const dirPath = path.join(baseDir, '.vscode', 'eventGridSamples', eventSource);
// Create the directory if it doesn't already exist
if (!(await fs.pathExists(dirPath))) {
await fs.mkdirp(dirPath);
}
// Return the path to the directory
return dirPath;
}