Skip to content

Commit b9e97b7

Browse files
amitjoshi438Amit Joshi
andauthored
Add server logic debug command and welcome notification (#1394)
* Add debug command for Server Logic in navigation group * Refactor debug configuration resolution to handle server logic files more clearly * Show welcome notification for server logic files in active editor --------- Co-authored-by: Amit Joshi <[email protected]>
1 parent 71e8a2e commit b9e97b7

File tree

6 files changed

+140
-48
lines changed

6 files changed

+140
-48
lines changed

l10n/bundle.l10n.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,23 @@
3232
"Failed to fetch some files.": "Failed to fetch some files.",
3333
"Failed to get file ready for edit: {0}": "Failed to get file ready for edit: {0}",
3434
"Saving your file ...": "Saving your file ...",
35+
"Debug Power Pages Server Logic": "Debug Power Pages Server Logic",
36+
"Debug Current Server Logic": "Debug Current Server Logic",
37+
"Run Server Logic": "Run Server Logic",
38+
"Cannot debug: Please open a server logic file (.js) from the server-logics folder.": "Cannot debug: Please open a server logic file (.js) from the server-logics folder.",
39+
"Server Logic debugging requires an open workspace.": "Server Logic debugging requires an open workspace.",
40+
"Failed to initialize Server Logic debugger: {0}": "Failed to initialize Server Logic debugger: {0}",
41+
"No active editor found.": "No active editor found.",
42+
"Please open a server logic file (.js) from the server-logics folder.": "Please open a server logic file (.js) from the server-logics folder.",
43+
"No active editor. Please open a server logic file.": "No active editor. Please open a server logic file.",
44+
"Power Pages Server Logic detected! You can now debug your server logic files with breakpoints and IntelliSense.": "Power Pages Server Logic detected! You can now debug your server logic files with breakpoints and IntelliSense.",
45+
"Debug Current File": "Debug Current File",
46+
"Learn More": "Learn More",
47+
"Don't Show Again": "Don't Show Again",
48+
"Debug": "Debug",
49+
"Debug this server logic file": "Debug this server logic file",
50+
"Run": "Run",
51+
"Run this server logic file without debugging": "Run this server logic file without debugging",
3552
"Enter Organization ID": "Enter Organization ID",
3653
"Power Pages Copilot is now connected to the environment: {0} : {1}/{0} represents the environment name": {
3754
"message": "Power Pages Copilot is now connected to the environment: {0} : {1}",

loc/translations-export/vscode-powerplatform.xlf

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@
134134
<trans-unit id="++CODE++19766ed6ccb2f4a32778eed80d1928d2c87a18d7c275ccb163ec6709d3eb2e27">
135135
<source xml:lang="en">Cancel</source>
136136
</trans-unit>
137+
<trans-unit id="++CODE++2007ab2650ce558e97a30b2aa70e1c881773cf3db7fbd8a430db221b06364579">
138+
<source xml:lang="en">Cannot debug: Please open a server logic file (.js) from the server-logics folder.</source>
139+
</trans-unit>
137140
<trans-unit id="++CODE++75106b7b8e0c597d51e042edbde3498f813c9cd7bd59759f4dde848abc054e85">
138141
<source xml:lang="en">Cannot install Power Pages generator. Please install npm and try again.</source>
139142
<note>Do not translate 'npm'</note>
@@ -338,6 +341,21 @@ Check the CodeQL extension panel for available queries.</source>
338341
<trans-unit id="++CODE++f88d5f387c99b46f054799a5bc6bac06d5b9f5dfd9eaf95627b5f34b137c7cb2">
339342
<source xml:lang="en">Database location: {0}</source>
340343
</trans-unit>
344+
<trans-unit id="++CODE++1a03bd2fd107c453f3183e30b9716f82200671e8270fbbefbe602f5a48705527">
345+
<source xml:lang="en">Debug</source>
346+
</trans-unit>
347+
<trans-unit id="++CODE++c290c1e52a812e64e79be343e932a767838b3045abdc429dad559882f68f999d">
348+
<source xml:lang="en">Debug Current File</source>
349+
</trans-unit>
350+
<trans-unit id="++CODE++187bba1fb2a0c6f665f35430ac7e2d820aab5b73b2921b99e26096a92cdf98e4">
351+
<source xml:lang="en">Debug Current Server Logic</source>
352+
</trans-unit>
353+
<trans-unit id="++CODE++136d1125a6f04a9c7c631e9be49bc4fca530e921f2af0fe5e2a9b1d95e0aa6ca">
354+
<source xml:lang="en">Debug Power Pages Server Logic</source>
355+
</trans-unit>
356+
<trans-unit id="++CODE++ff0a1f27b622e2032d9c0df2db5943ac6504497bf01e48c77335b6591f134522">
357+
<source xml:lang="en">Debug this server logic file</source>
358+
</trans-unit>
341359
<trans-unit id="++CODE++5bd78fcb75f98d65ab8f89a8f0b6681c25c13308fa8643c44ab459b7783c06c9">
342360
<source xml:lang="en">Default Environment: {0}</source>
343361
<note>The {0} represents profile's resource/environment URL</note>
@@ -371,6 +389,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
371389
<trans-unit id="++CODE++183c7081100618aebb39219dd011d8d9961649aad278be8fe49c0d1a8874684f">
372390
<source xml:lang="en">Do not show again</source>
373391
</trans-unit>
392+
<trans-unit id="++CODE++1d60d0cdcb5408b8e39ed364f675c9cad8a2f6174a413324d1e34437bd41269b">
393+
<source xml:lang="en">Don't Show Again</source>
394+
</trans-unit>
374395
<trans-unit id="++CODE++668c177d38e6f62ffe2ca64e3915151cfcd566204fd4e4b499e7fe237ad63fb1">
375396
<source xml:lang="en">Download Power Pages Site</source>
376397
</trans-unit>
@@ -519,6 +540,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
519540
<source xml:lang="en">Failed to import comparison: {0}</source>
520541
<note>Error message when import fails. {0} is the error message.</note>
521542
</trans-unit>
543+
<trans-unit id="++CODE++7df498affc70b3844ab77806857554f50899316597e96d91097dcefd8e225024">
544+
<source xml:lang="en">Failed to initialize Server Logic debugger: {0}</source>
545+
</trans-unit>
522546
<trans-unit id="++CODE++9696573fbb3df8812e2d0b83aa3d9077681bf992c9f9514fbbb81fcc7787560d">
523547
<source xml:lang="en">Failed to install SARIF viewer extension. Opening results as text file.</source>
524548
</trans-unit>
@@ -663,6 +687,9 @@ Return to this chat and @powerpages can help you write and edit your website cod
663687
<trans-unit id="++CODE++8e79146ac2ac83ff880a2a3860077ea6cfed5cdcea1ea169fed12fdd03b5360d">
664688
<source xml:lang="en">Invalid file format. The file does not contain valid metadata diff data.</source>
665689
</trans-unit>
690+
<trans-unit id="++CODE++8d8cd546b58d91c300d3149ef40b8d98d3061dc38f15ea937d2ed785a3f25771">
691+
<source xml:lang="en">Learn More</source>
692+
</trans-unit>
666693
<trans-unit id="++CODE++c59fe0045151cddc10b8384a437337e86eab905877883c18b53e068a3d36121d">
667694
<source xml:lang="en">Learn more about Copilot</source>
668695
</trans-unit>
@@ -764,6 +791,12 @@ The {3} represents Dataverse Environment's Organization ID (GUID)</note>
764791
<trans-unit id="++CODE++b1061a7adf836619e40617bbbbe42d04a9c167b5756a2b4926c02d88e780a7f9">
765792
<source xml:lang="en">No Website Data Found in Current Directory. Please switch to a directory that contains the PAC downloaded website data to continue.</source>
766793
</trans-unit>
794+
<trans-unit id="++CODE++4e0d6304be5d5157d4b4b95a0bbffe07b9c2a84f6849b3bb0d591e79b864f33c">
795+
<source xml:lang="en">No active editor found.</source>
796+
</trans-unit>
797+
<trans-unit id="++CODE++5fa52f38613f411a293ae2794bdd18faa33ed13bc586c60a8bd774832069c82e">
798+
<source xml:lang="en">No active editor. Please open a server logic file.</source>
799+
</trans-unit>
767800
<trans-unit id="++CODE++1b03558147265e7c9bd70e6a4abe031ef65dbca05e01d94953e58b86ec82c859">
768801
<source xml:lang="en">No analysis results found.</source>
769802
</trans-unit>
@@ -892,6 +925,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID)</note>
892925
<trans-unit id="++CODE++6355962eca901310bd24d2142605263344a3f09fb4fc30fc0f9dcf4cd56bf534">
893926
<source xml:lang="en">Please login to preview the site.</source>
894927
</trans-unit>
928+
<trans-unit id="++CODE++2e56799726107b8b44bdcad31ef1ce0515cfacc9372b34946a4257af3bcf2919">
929+
<source xml:lang="en">Please open a server logic file (.js) from the server-logics folder.</source>
930+
</trans-unit>
895931
<trans-unit id="++CODE++f413d35f48356c6c13c6c9d8947f011221acb3bea7d0ce74eb2f5ed217f26bad">
896932
<source xml:lang="en">Please select the folder that contains your compiled output to upload your site.</source>
897933
</trans-unit>
@@ -902,6 +938,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID)</note>
902938
<source xml:lang="en">Power Pages Copilot is now connected to the environment: {0} : {1}</source>
903939
<note>{0} represents the environment name</note>
904940
</trans-unit>
941+
<trans-unit id="++CODE++f519c6aeba20c1a712f6043bf6eb52bf3bb8834f5f1a6c9ea60244dbbb30453c">
942+
<source xml:lang="en">Power Pages Server Logic detected! You can now debug your server logic files with breakpoints and IntelliSense.</source>
943+
</trans-unit>
905944
<trans-unit id="++CODE++db40be71cd139d96719d08f10c843b8bf1c2a0d3d2da06902109a758a98bc9f9">
906945
<source xml:lang="en">Power Pages Site Comparison Results</source>
907946
</trans-unit>
@@ -962,6 +1001,15 @@ The {3} represents Dataverse Environment's Organization ID (GUID)</note>
9621001
<trans-unit id="++CODE++b87504a6b179044cf99d39cf641f47aa5e76c4c5b949413ec33953ec35c10ac4">
9631002
<source xml:lang="en">Results opened in SARIF viewer successfully.</source>
9641003
</trans-unit>
1004+
<trans-unit id="++CODE++00d60e31a4e6b8344d4201f25a6a7dee770713107f6d097abb01559d32b17f26">
1005+
<source xml:lang="en">Run</source>
1006+
</trans-unit>
1007+
<trans-unit id="++CODE++ea703d2310b31c503c3e81398804a049aa6e65f78dbe7014f8f52dae263dadfb">
1008+
<source xml:lang="en">Run Server Logic</source>
1009+
</trans-unit>
1010+
<trans-unit id="++CODE++80b0001b823cb916650c75c5c08b3bdf9be4951036ec14ee4086b487125d05c8">
1011+
<source xml:lang="en">Run this server logic file without debugging</source>
1012+
</trans-unit>
9651013
<trans-unit id="++CODE++9eb3810da0fd0dbacf4b6f4d7ad58e6e631ab807c0dd404dcb9f03066da8443b">
9661014
<source xml:lang="en">Running CodeQL analysis...</source>
9671015
</trans-unit>
@@ -1020,6 +1068,9 @@ The {3} represents Dataverse Environment's Organization ID (GUID)</note>
10201068
<trans-unit id="++CODE++d4e969ee5e3ea8fe5e7f9195be448fd5fd5d2cb6f487929c3e495cbbe7e8f1e8">
10211069
<source xml:lang="en">Selection is too large. Try making a shorter selection.</source>
10221070
</trans-unit>
1071+
<trans-unit id="++CODE++f460c321b3d56be39d9fae8946e759608e6b8f34c0378aaa91e2996b2bd8f2b5">
1072+
<source xml:lang="en">Server Logic debugging requires an open workspace.</source>
1073+
</trans-unit>
10231074
<trans-unit id="++CODE++142027a259879fdd2b6410360a9cd3798f433c2fc5668bb685dd4ff513072e16">
10241075
<source xml:lang="en">Session Details</source>
10251076
</trans-unit>

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,11 @@
958958
"command": "powerPlatform.previewCurrentActiveUsers",
959959
"group": "navigation",
960960
"when": "isWeb && virtualWorkspace"
961+
},
962+
{
963+
"command": "microsoft.powerplatform.pages.debugServerLogic",
964+
"group": "navigation",
965+
"when": "resourcePath =~ /server-logics?[/\\\\]/ && resourceExtname == .js"
961966
}
962967
],
963968
"commandPalette": [

src/debugger/server-logic/ServerLogicDebugProvider.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,17 @@ export class ServerLogicDebugProvider implements vscode.DebugConfigurationProvid
4848
_: vscode.CancellationToken
4949
): Promise<vscode.DebugConfiguration | undefined> {
5050

51+
const editor = vscode.window.activeTextEditor;
52+
53+
// Only handle server logic files
54+
if (!editor || !isServerLogicFile(editor.document.uri.fsPath)) {
55+
// Not a server logic file, let other providers handle it
56+
return config;
57+
}
58+
59+
// If empty config (F5 with no launch.json), create one for the current file
5160
if (!config.type && !config.request && !config.name) {
52-
const editor = vscode.window.activeTextEditor;
53-
if (editor && isServerLogicFile(editor.document.uri.fsPath)) {
54-
config = createServerLogicDebugConfig(editor.document.uri.fsPath);
55-
} else {
56-
vscode.window.showErrorMessage(SERVER_LOGIC_STRINGS.ERROR_OPEN_SERVER_LOGIC_FILE);
57-
return undefined;
58-
}
61+
config = createServerLogicDebugConfig(editor.document.uri.fsPath);
5962
}
6063

6164
if (!folder) {

src/debugger/server-logic/ServerLogicDebugger.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,19 @@ export function activateServerLogicDebugger(context: vscode.ExtensionContext): v
201201
)
202202
);
203203

204-
const workspaceFolders = vscode.workspace.workspaceFolders;
205-
if (workspaceFolders && workspaceFolders.length > 0) {
206-
const serverLogicsPath = path.join(workspaceFolders[0].uri.fsPath, SERVER_LOGIC_FILES.SERVER_LOGICS_FOLDER);
207-
if (fs.existsSync(serverLogicsPath)) {
208-
showServerLogicWelcomeNotification();
209-
}
204+
// Show welcome notification when a server logic file is opened
205+
context.subscriptions.push(
206+
vscode.window.onDidChangeActiveTextEditor(editor => {
207+
if (editor && isServerLogicFile(editor.document.uri.fsPath)) {
208+
showServerLogicWelcomeNotification();
209+
}
210+
})
211+
);
212+
213+
// Check if active editor already has a server logic file
214+
const activeEditor = vscode.window.activeTextEditor;
215+
if (activeEditor && isServerLogicFile(activeEditor.document.uri.fsPath)) {
216+
showServerLogicWelcomeNotification();
210217
}
211218
}
212219

src/debugger/test/integration/ServerLogicDebugger.test.ts

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -101,102 +101,111 @@ describe('ServerLogicDebugger', () => {
101101
showErrorMessageStub = sandbox.stub(vscode.window, 'showErrorMessage');
102102
});
103103

104-
it('should return undefined and show error when no folder provided', async () => {
104+
it('should pass through config when no active editor', async () => {
105+
const folder: vscode.WorkspaceFolder = {
106+
uri: vscode.Uri.file('some/path'),
107+
index: 0,
108+
name: 'Workspace',
109+
};
105110
const config: vscode.DebugConfiguration = {
106111
type: 'node',
107112
request: 'launch',
108113
name: 'Test'
109114
};
110115

116+
sandbox.stub(vscode.window, 'activeTextEditor').value(undefined);
117+
111118
const result = await provider.resolveDebugConfiguration(
112-
undefined,
119+
folder,
113120
config,
114121
{} as vscode.CancellationToken
115122
);
116123

117-
expect(result).to.be.undefined;
118-
expect(showErrorMessageStub.calledOnce).to.be.true;
124+
expect(result).to.deep.equal(config);
125+
expect(showErrorMessageStub.called).to.be.false;
119126
});
120127

121-
it('should show error when empty config and no server logic file open', async () => {
128+
it('should pass through config when file is not in server-logics folder', async () => {
122129
const folder: vscode.WorkspaceFolder = {
123130
uri: vscode.Uri.file('some/path'),
124131
index: 0,
125132
name: 'Workspace',
126133
};
127-
const emptyConfig: vscode.DebugConfiguration = {
128-
type: '',
129-
request: '',
130-
name: ''
134+
const config: vscode.DebugConfiguration = {
135+
type: 'node',
136+
request: 'launch',
137+
name: 'Test'
131138
};
132139

133-
sandbox.stub(vscode.window, 'activeTextEditor').value(undefined);
140+
const mockEditor = {
141+
document: {
142+
uri: {
143+
fsPath: '/some/path/regular-folder/test.js'
144+
}
145+
}
146+
};
147+
sandbox.stub(vscode.window, 'activeTextEditor').value(mockEditor);
134148

135149
const result = await provider.resolveDebugConfiguration(
136150
folder,
137-
emptyConfig,
151+
config,
138152
{} as vscode.CancellationToken
139153
);
140154

141-
expect(result).to.be.undefined;
142-
expect(showErrorMessageStub.calledOnce).to.be.true;
155+
expect(result).to.deep.equal(config);
156+
expect(showErrorMessageStub.called).to.be.false;
143157
});
144158

145-
it('should show error when file is not in server-logics folder', async () => {
159+
it('should pass through config when file is .ts instead of .js', async () => {
146160
const folder: vscode.WorkspaceFolder = {
147161
uri: vscode.Uri.file('some/path'),
148162
index: 0,
149163
name: 'Workspace',
150164
};
151-
const emptyConfig: vscode.DebugConfiguration = {
152-
type: '',
153-
request: '',
154-
name: ''
165+
const config: vscode.DebugConfiguration = {
166+
type: 'node',
167+
request: 'launch',
168+
name: 'Test'
155169
};
156170

157171
const mockEditor = {
158172
document: {
159173
uri: {
160-
fsPath: '/some/path/regular-folder/test.js'
174+
fsPath: '/project/server-logics/handler.ts'
161175
}
162176
}
163177
};
164178
sandbox.stub(vscode.window, 'activeTextEditor').value(mockEditor);
165179

166180
const result = await provider.resolveDebugConfiguration(
167181
folder,
168-
emptyConfig,
182+
config,
169183
{} as vscode.CancellationToken
170184
);
171185

172-
expect(result).to.be.undefined;
173-
expect(showErrorMessageStub.calledOnce).to.be.true;
186+
expect(result).to.deep.equal(config);
187+
expect(showErrorMessageStub.called).to.be.false;
174188
});
175189

176-
it('should show error when file is .ts instead of .js', async () => {
177-
const folder: vscode.WorkspaceFolder = {
178-
uri: vscode.Uri.file('some/path'),
179-
index: 0,
180-
name: 'Workspace',
181-
};
182-
const emptyConfig: vscode.DebugConfiguration = {
183-
type: '',
184-
request: '',
185-
name: ''
190+
it('should show error when server logic file but no folder provided', async () => {
191+
const config: vscode.DebugConfiguration = {
192+
type: 'node',
193+
request: 'launch',
194+
name: 'Test'
186195
};
187196

188197
const mockEditor = {
189198
document: {
190199
uri: {
191-
fsPath: '/project/server-logics/handler.ts'
200+
fsPath: '/project/server-logics/handler.js'
192201
}
193202
}
194203
};
195204
sandbox.stub(vscode.window, 'activeTextEditor').value(mockEditor);
196205

197206
const result = await provider.resolveDebugConfiguration(
198-
folder,
199-
emptyConfig,
207+
undefined,
208+
config,
200209
{} as vscode.CancellationToken
201210
);
202211

0 commit comments

Comments
 (0)