diff --git a/loc/translations-import/vscode-powerplatform.cs.xlf b/loc/translations-import/vscode-powerplatform.cs.xlf
index 9d7a5b3d..9f93e9e6 100644
--- a/loc/translations-import/vscode-powerplatform.cs.xlf
+++ b/loc/translations-import/vscode-powerplatform.cs.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
Vytváří se {0}...
+
+
+ The {0} represents profile's resource/environment URL
+ Výchozí prostředí: {0}
+
-
- Failed to get file ready for edit.
- Soubor se nepodařilo připravit k úpravám.
+
+ Failed to get file ready for edit: {0}
+ Soubor se nepodařilo připravit k úpravám: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ Kód organizace: {3}
The {0} represents the profile type (Admin vs Dataverse)
Druh profilu: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Prostředek: {0}
+
+ Response data is empty
+ Data odpovědi jsou prázdná.
Saving your file ...
@@ -375,9 +379,9 @@ Kód organizace: {3}
The {0} represents auth profile's user name (email address))
Uživatel: {0}
-
- We encountered an error preparing the file for edit.
- Při přípravě souboru k úpravám došlo k chybě.
+
+ We encountered an error preparing the files for edit.
+ Při přípravě souborů k úpravám došlo k chybě.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.de.xlf b/loc/translations-import/vscode-powerplatform.de.xlf
index 36e89770..c932f947 100644
--- a/loc/translations-import/vscode-powerplatform.de.xlf
+++ b/loc/translations-import/vscode-powerplatform.de.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
"{0}" wird erstellt...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Standardumgebung: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -108,6 +113,7 @@ Typ: {3}
Do not show again
+ Nicht mehr anzeigen
Edit the site
@@ -146,9 +152,9 @@ Typ: {3}
Failed to fetch some files.
Fehler beim Abrufen einiger Dateien
-
- Failed to get file ready for edit.
- Fehler beim Vorbereiten der Datei für die Bearbeitung.
+
+ Failed to get file ready for edit: {0}
+ Fehler beim Vorbereiten der Datei für die Bearbeitung: {0}
Fetching your file ...
@@ -170,9 +176,11 @@ Typ: {3}
Learn more about Copilot
+ Weitere Informationen zu Copilot
Let Copilot help you code
+ Von Copilot beim Codieren helfen lassen
Managed
@@ -301,10 +309,9 @@ Organisations-ID: {3}
The {0} represents the profile type (Admin vs Dataverse)
Profil-Variante: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Ressource: {0}
+
+ Response data is empty
+ Antwortdaten sind leer
Saving your file ...
@@ -321,6 +328,7 @@ Organisations-ID: {3}
Selection is empty.
+ Auswahl ist leer.
The Power Pages generator is ready for use in your VS Code extension!
@@ -348,6 +356,7 @@ Organisations-ID: {3}
Try Copilot for Power Pages
+ Copilot für Power Pages testen
Try again
@@ -370,9 +379,9 @@ Organisations-ID: {3}
The {0} represents auth profile's user name (email address))
Benutzer: {0}
-
- We encountered an error preparing the file for edit.
- Beim Vorbereiten der Datei zur Bearbeitung ist ein Fehler aufgetreten.
+
+ We encountered an error preparing the files for edit.
+ Beim Vorbereiten der Dateien für die Bearbeitung ist ein Fehler aufgetreten.
Web files
@@ -384,6 +393,7 @@ Organisations-ID: {3}
Whether it’s HTML, CSS, JS, or Liquid code, just describe what you need and let AI build it for you.
+ Ob es sich um HTML-, CSS-, JS- oder Liquid-Code handelt, beschreiben Sie einfach, was Sie benötigen, und lassen Sie es von KI für Sie erstellen.
You are editing a live, public site
diff --git a/loc/translations-import/vscode-powerplatform.es.xlf b/loc/translations-import/vscode-powerplatform.es.xlf
index 494b7919..78dec27b 100644
--- a/loc/translations-import/vscode-powerplatform.es.xlf
+++ b/loc/translations-import/vscode-powerplatform.es.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
Creando {0}...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Entorno predeterminado: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ Tipo: {3}
Failed to fetch some files.
No se pudieron capturar algunos archivos.
-
- Failed to get file ready for edit.
- No se pudo preparar el archivo para su edición.
+
+ Failed to get file ready for edit: {0}
+ No se pudo preparar el archivo para su edición: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ Id. de organización: {3}
The {0} represents the profile type (Admin vs Dataverse)
Tipo de perfil: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Recurso: {0}
+
+ Response data is empty
+ Los datos de respuesta están vacíos
Saving your file ...
@@ -375,9 +379,9 @@ Id. de organización: {3}
The {0} represents auth profile's user name (email address))
Usuario: {0}
-
- We encountered an error preparing the file for edit.
- Se detectó un error al preparar el archivo para su edición.
+
+ We encountered an error preparing the files for edit.
+ Se detectó un error al preparar los archivos para su edición.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.fr.xlf b/loc/translations-import/vscode-powerplatform.fr.xlf
index fab25d91..c09dde59 100644
--- a/loc/translations-import/vscode-powerplatform.fr.xlf
+++ b/loc/translations-import/vscode-powerplatform.fr.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
Création de {0}...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Environnement par défaut : {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ Type : {3}
Failed to fetch some files.
Échec de récupération de certains fichiers.
-
- Failed to get file ready for edit.
- Impossible de préparer le fichier pour la modification.
+
+ Failed to get file ready for edit: {0}
+ Impossible de préparer le fichier pour la modification : {0}
Fetching your file ...
@@ -304,10 +309,9 @@ ID d’organisation : {3}
The {0} represents the profile type (Admin vs Dataverse)
Type de profil : {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Ressource : {0}
+
+ Response data is empty
+ Les données de la réponse sont vides
Saving your file ...
@@ -375,9 +379,9 @@ ID d’organisation : {3}
The {0} represents auth profile's user name (email address))
Utilisateur : {0}
-
- We encountered an error preparing the file for edit.
- Une erreur s’est produite lors de la préparation du fichier pour la modification.
+
+ We encountered an error preparing the files for edit.
+ Nous avons rencontré une erreur lors de la préparation des fichiers à modifier.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.it.xlf b/loc/translations-import/vscode-powerplatform.it.xlf
index b48ff89b..c7fc7846 100644
--- a/loc/translations-import/vscode-powerplatform.it.xlf
+++ b/loc/translations-import/vscode-powerplatform.it.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
Creazione di {0} in corso...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Ambiente predefinito: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ Tipo: {3}
Failed to fetch some files.
Impossibile recuperare alcuni file.
-
- Failed to get file ready for edit.
- Impossibile preparare il file per la modifica.
+
+ Failed to get file ready for edit: {0}
+ Impossibile preparare il file per la modifica: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ ID organizzazione: {3}
The {0} represents the profile type (Admin vs Dataverse)
Tipo di profilo: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Risorsa: {0}
+
+ Response data is empty
+ I dati della risposta sono vuoti
Saving your file ...
@@ -375,9 +379,9 @@ ID organizzazione: {3}
The {0} represents auth profile's user name (email address))
Utente: {0}
-
- We encountered an error preparing the file for edit.
- Si è verificato un errore durante la preparazione del file per la modifica.
+
+ We encountered an error preparing the files for edit.
+ Si è verificato un errore durante la preparazione dei file per la modifica.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.ja.xlf b/loc/translations-import/vscode-powerplatform.ja.xlf
index 3e642e0c..40c3c565 100644
--- a/loc/translations-import/vscode-powerplatform.ja.xlf
+++ b/loc/translations-import/vscode-powerplatform.ja.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
{0} を作成しています...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ 既定の環境: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
Failed to fetch some files.
一部のファイルを取得できませんでした。
-
- Failed to get file ready for edit.
- ファイルの編集準備に失敗しました。
+
+ Failed to get file ready for edit: {0}
+ ファイルの編集準備に失敗しました: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ URL: {1}
The {0} represents the profile type (Admin vs Dataverse)
プロファイルの種類: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- リソース: {0}
+
+ Response data is empty
+ 応答データが空です
Saving your file ...
@@ -375,9 +379,9 @@ URL: {1}
The {0} represents auth profile's user name (email address))
ユーザー: {0}
-
- We encountered an error preparing the file for edit.
- ファイルの編集準備中にエラーが発生しました。
+
+ We encountered an error preparing the files for edit.
+ ファイルの編集準備でエラーが発生しました。
Web files
diff --git a/loc/translations-import/vscode-powerplatform.ko.xlf b/loc/translations-import/vscode-powerplatform.ko.xlf
index bd0e4ff0..2444a39a 100644
--- a/loc/translations-import/vscode-powerplatform.ko.xlf
+++ b/loc/translations-import/vscode-powerplatform.ko.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
{0} 생성 중...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ 기본 환경: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
Failed to fetch some files.
일부 파일을 가져오지 못했습니다.
-
- Failed to get file ready for edit.
- 편집을 위해 파일 준비를 하지 못했습니다.
+
+ Failed to get file ready for edit: {0}
+ 다음을 편집할 파일을 준비하지 못했습니다. {0}
Fetching your file ...
@@ -304,10 +309,9 @@ URL: {1}
The {0} represents the profile type (Admin vs Dataverse)
프로필 종류: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- 리소스: {0}
+
+ Response data is empty
+ 응답 데이터가 비어 있음
Saving your file ...
@@ -375,9 +379,9 @@ URL: {1}
The {0} represents auth profile's user name (email address))
사용자: {0}
-
- We encountered an error preparing the file for edit.
- 파일 편집을 준비하는 동안 오류가 발생했습니다.
+
+ We encountered an error preparing the files for edit.
+ 편집할 파일을 준비하는 동안 오류가 발생했습니다.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.pt-BR.xlf b/loc/translations-import/vscode-powerplatform.pt-BR.xlf
index 870c76ed..9c035059 100644
--- a/loc/translations-import/vscode-powerplatform.pt-BR.xlf
+++ b/loc/translations-import/vscode-powerplatform.pt-BR.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
Criando {0}...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Ambiente Padrão: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ Tipo: {3}
Failed to fetch some files.
Falha ao buscar alguns arquivos.
-
- Failed to get file ready for edit.
- Falha ao preparar o arquivo para edição.
+
+ Failed to get file ready for edit: {0}
+ Falha ao preparar o arquivo para edição: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ ID da Organização: {3}
The {0} represents the profile type (Admin vs Dataverse)
Tipo de Perfil: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Recurso: {0}
+
+ Response data is empty
+ Os dados da resposta estão vazios
Saving your file ...
@@ -375,9 +379,9 @@ ID da Organização: {3}
The {0} represents auth profile's user name (email address))
Usuário: {0}
-
- We encountered an error preparing the file for edit.
- Encontramos um erro ao preparar o arquivo para edição.
+
+ We encountered an error preparing the files for edit.
+ Encontramos um erro ao preparar os arquivos para edição.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.ru.xlf b/loc/translations-import/vscode-powerplatform.ru.xlf
index d226621e..a9a40833 100644
--- a/loc/translations-import/vscode-powerplatform.ru.xlf
+++ b/loc/translations-import/vscode-powerplatform.ru.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
Создание {0}...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Среда по умолчанию: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
Failed to fetch some files.
Не удалось получить некоторые файлы.
-
- Failed to get file ready for edit.
- Не удалось получить файл для редактирования.
+
+ Failed to get file ready for edit: {0}
+ Не удалось получить файл для редактирования: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ URL-адрес: {1}
The {0} represents the profile type (Admin vs Dataverse)
Вид профиля: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Ресурс: {0}
+
+ Response data is empty
+ Данные ответа пусты
Saving your file ...
@@ -375,9 +379,9 @@ URL-адрес: {1}
The {0} represents auth profile's user name (email address))
Пользователь: {0}
-
- We encountered an error preparing the file for edit.
- Произошла ошибка при подготовке файла к редактированию.
+
+ We encountered an error preparing the files for edit.
+ Произошла ошибка при подготовке файлов к редактированию.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.tr.xlf b/loc/translations-import/vscode-powerplatform.tr.xlf
index 5040c1bc..2334fecf 100644
--- a/loc/translations-import/vscode-powerplatform.tr.xlf
+++ b/loc/translations-import/vscode-powerplatform.tr.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
{0} oluşturuluyor...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ Varsayılan Ortam: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ Tür: {3}
Failed to fetch some files.
Bazı dosyalar alınamadı.
-
- Failed to get file ready for edit.
- Dosya düzenlenmek üzere alınamadı.
+
+ Failed to get file ready for edit: {0}
+ Dosya düzenlenmek üzere alınamadı: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ Kuruluş Kimliği: {3}
The {0} represents the profile type (Admin vs Dataverse)
Profil Türü: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- Kaynak: {0}
+
+ Response data is empty
+ Yanıt verileri boş
Saving your file ...
@@ -375,9 +379,9 @@ Kuruluş Kimliği: {3}
The {0} represents auth profile's user name (email address))
Kullanıcı: {0}
-
- We encountered an error preparing the file for edit.
- Dosya düzenlemeye hazırlanırken bir hatayla karşılaştık.
+
+ We encountered an error preparing the files for edit.
+ Dosyalar düzenleme için hazırlanırken bir hatayla karşılaştık.
Web files
diff --git a/loc/translations-import/vscode-powerplatform.zh-CN.xlf b/loc/translations-import/vscode-powerplatform.zh-CN.xlf
index b12e879d..c22d9d80 100644
--- a/loc/translations-import/vscode-powerplatform.zh-CN.xlf
+++ b/loc/translations-import/vscode-powerplatform.zh-CN.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
正在创建 {0}...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ 默认环境: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
Failed to fetch some files.
无法获取部分文件。
-
- Failed to get file ready for edit.
- 无法获取可供编辑的文件。
+
+ Failed to get file ready for edit: {0}
+ 无法获取可供编辑的文件: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ URL: {1}
The {0} represents the profile type (Admin vs Dataverse)
配置文件种类: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- 资源: {0}
+
+ Response data is empty
+ 响应数据为空
Saving your file ...
@@ -375,9 +379,9 @@ URL: {1}
The {0} represents auth profile's user name (email address))
用户: {0}
-
- We encountered an error preparing the file for edit.
- 准备可供编辑的文件时出错。
+
+ We encountered an error preparing the files for edit.
+ 我们在准备编辑文件时遇到错误。
Web files
diff --git a/loc/translations-import/vscode-powerplatform.zh-TW.xlf b/loc/translations-import/vscode-powerplatform.zh-TW.xlf
index c6c81d40..b4bef113 100644
--- a/loc/translations-import/vscode-powerplatform.zh-TW.xlf
+++ b/loc/translations-import/vscode-powerplatform.zh-TW.xlf
@@ -91,6 +91,11 @@
{0} will be replaced by the entity type.
正在建立 {0}...
+
+ Default Environment: {0}
+ The {0} represents profile's resource/environment URL
+ 預設環境: {0}
+
Display Name: {0}
Unique Name: {1}
@@ -147,9 +152,9 @@ The {3} represents Solution's Type (Managed or Unmanaged), but that test is loca
Failed to fetch some files.
無法擷取部分檔案。
-
- Failed to get file ready for edit.
- 無法準備好文件進行編輯。
+
+ Failed to get file ready for edit: {0}
+ 無法準備好文件進行編輯: {0}
Fetching your file ...
@@ -304,10 +309,9 @@ URL: {1}
The {0} represents the profile type (Admin vs Dataverse)
設定檔種類: {0}
-
- Resource: {0}
- The {0} represents profile's resource/environment URL
- 資源: {0}
+
+ Response data is empty
+ 回覆資料是空的
Saving your file ...
@@ -375,9 +379,9 @@ URL: {1}
The {0} represents auth profile's user name (email address))
使用者: {0}
-
- We encountered an error preparing the file for edit.
- 準備要編輯的檔案時發生錯誤。
+
+ We encountered an error preparing the files for edit.
+ 我們在準備要編輯的檔案時發生錯誤。
Web files
diff --git a/package-lock.json b/package-lock.json
index 3e865fcd..c6a86fdb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"@microsoft/generator-powerpages": "1.21.19",
"@types/jwt-decode": "2.2.0",
"@types/node-fetch": "^2.6.2",
+ "@types/xmldom": "^0.1.34",
"@vscode/extension-telemetry": "^0.6.2",
"cockatiel": "^3.1.1",
"command-exists": "^1.2.9",
@@ -35,6 +36,7 @@
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"worker-loader": "^3.0.8",
+ "xmldom": "^0.6.0",
"yaml": "^2.2.2"
},
"devDependencies": {
@@ -102,6 +104,7 @@
"yargs": "^16.2.0"
},
"engines": {
+ "npm": ">=8.3.0",
"vscode": "^1.73.0"
},
"optionalDependencies": {
@@ -732,6 +735,76 @@
"fluid-framework": "^1.3.3"
}
},
+ "node_modules/@fluidframework/azure-client/node_modules/@fluidframework/server-services-client": {
+ "version": "0.1036.5001",
+ "resolved": "https://registry.npmjs.org/@fluidframework/server-services-client/-/server-services-client-0.1036.5001.tgz",
+ "integrity": "sha512-e+Zk2uPcds9yqlalAZ0PpfEAKPPUIpIoQb3YSm42ZVpAgQmLYIRqTpXrmTC7qdeQnSGFJUAliW4DfHBEwpSXlQ==",
+ "dependencies": {
+ "@fluidframework/common-utils": "^0.32.2",
+ "@fluidframework/gitresources": "^0.1036.5001",
+ "@fluidframework/protocol-base": "^0.1036.5001",
+ "@fluidframework/protocol-definitions": "^0.1028.2000",
+ "axios": "^0.26.0",
+ "crc-32": "1.2.0",
+ "debug": "^4.1.1",
+ "json-stringify-safe": "^5.0.1",
+ "jsrsasign": "^10.2.0",
+ "jwt-decode": "^3.0.0",
+ "querystring": "^0.2.0",
+ "sillyname": "^0.1.0",
+ "uuid": "^8.3.1"
+ }
+ },
+ "node_modules/@fluidframework/azure-client/node_modules/@fluidframework/server-services-client/node_modules/@fluidframework/common-utils": {
+ "version": "0.32.2",
+ "resolved": "https://registry.npmjs.org/@fluidframework/common-utils/-/common-utils-0.32.2.tgz",
+ "integrity": "sha512-PoGX7/l0vWKt5JaAxcgFOdGje30Q6qSE06YzFIKh9Ba3oq7B60+TFqu7c2ErQt6sNddmvcAcAiLVNaTGAip3vw==",
+ "dependencies": {
+ "@fluidframework/common-definitions": "^0.20.1",
+ "@types/events": "^3.0.0",
+ "base64-js": "^1.5.1",
+ "buffer": "^6.0.3",
+ "events": "^3.1.0",
+ "lodash": "^4.17.21",
+ "sha.js": "^2.4.11"
+ }
+ },
+ "node_modules/@fluidframework/azure-client/node_modules/@fluidframework/server-services-client/node_modules/@fluidframework/protocol-definitions": {
+ "version": "0.1028.2000",
+ "resolved": "https://registry.npmjs.org/@fluidframework/protocol-definitions/-/protocol-definitions-0.1028.2000.tgz",
+ "integrity": "sha512-ZUPCmPFcK7UAK4RkfVWfzQPAWFvYNm6ywP51V42YC38gCGye+Epvyr3beA+FSaHPIZGxm5+Uw52+ykTvmDb2UA==",
+ "dependencies": {
+ "@fluidframework/common-definitions": "^0.20.1"
+ }
+ },
+ "node_modules/@fluidframework/azure-client/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/@fluidframework/azure-client/node_modules/jwt-decode": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
+ "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
+ },
"node_modules/@fluidframework/common-definitions": {
"version": "0.20.1",
"resolved": "https://registry.npmjs.org/@fluidframework/common-definitions/-/common-definitions-0.20.1.tgz",
@@ -1256,14 +1329,6 @@
"@fluidframework/common-definitions": "^0.20.1"
}
},
- "node_modules/@fluidframework/driver-utils/node_modules/axios": {
- "version": "0.26.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
- "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
- "dependencies": {
- "follow-redirects": "^1.14.8"
- }
- },
"node_modules/@fluidframework/driver-utils/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -1687,6 +1752,26 @@
"@fluidframework/common-definitions": "^0.20.1"
}
},
+ "node_modules/@fluidframework/routerlicious-driver/node_modules/@fluidframework/server-services-client": {
+ "version": "0.1036.5001",
+ "resolved": "https://registry.npmjs.org/@fluidframework/server-services-client/-/server-services-client-0.1036.5001.tgz",
+ "integrity": "sha512-e+Zk2uPcds9yqlalAZ0PpfEAKPPUIpIoQb3YSm42ZVpAgQmLYIRqTpXrmTC7qdeQnSGFJUAliW4DfHBEwpSXlQ==",
+ "dependencies": {
+ "@fluidframework/common-utils": "^0.32.2",
+ "@fluidframework/gitresources": "^0.1036.5001",
+ "@fluidframework/protocol-base": "^0.1036.5001",
+ "@fluidframework/protocol-definitions": "^0.1028.2000",
+ "axios": "^0.26.0",
+ "crc-32": "1.2.0",
+ "debug": "^4.1.1",
+ "json-stringify-safe": "^5.0.1",
+ "jsrsasign": "^10.2.0",
+ "jwt-decode": "^3.0.0",
+ "querystring": "^0.2.0",
+ "sillyname": "^0.1.0",
+ "uuid": "^8.3.1"
+ }
+ },
"node_modules/@fluidframework/routerlicious-driver/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -1710,6 +1795,11 @@
"ieee754": "^1.2.1"
}
},
+ "node_modules/@fluidframework/routerlicious-driver/node_modules/jwt-decode": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
+ "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
+ },
"node_modules/@fluidframework/runtime-definitions": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/@fluidframework/runtime-definitions/-/runtime-definitions-1.3.7.tgz",
@@ -1895,84 +1985,6 @@
"ieee754": "^1.2.1"
}
},
- "node_modules/@fluidframework/server-services-client": {
- "version": "0.1036.5001",
- "resolved": "https://registry.npmjs.org/@fluidframework/server-services-client/-/server-services-client-0.1036.5001.tgz",
- "integrity": "sha512-e+Zk2uPcds9yqlalAZ0PpfEAKPPUIpIoQb3YSm42ZVpAgQmLYIRqTpXrmTC7qdeQnSGFJUAliW4DfHBEwpSXlQ==",
- "dependencies": {
- "@fluidframework/common-utils": "^0.32.2",
- "@fluidframework/gitresources": "^0.1036.5001",
- "@fluidframework/protocol-base": "^0.1036.5001",
- "@fluidframework/protocol-definitions": "^0.1028.2000",
- "axios": "^0.26.0",
- "crc-32": "1.2.0",
- "debug": "^4.1.1",
- "json-stringify-safe": "^5.0.1",
- "jsrsasign": "^10.2.0",
- "jwt-decode": "^3.0.0",
- "querystring": "^0.2.0",
- "sillyname": "^0.1.0",
- "uuid": "^8.3.1"
- }
- },
- "node_modules/@fluidframework/server-services-client/node_modules/@fluidframework/common-utils": {
- "version": "0.32.2",
- "resolved": "https://registry.npmjs.org/@fluidframework/common-utils/-/common-utils-0.32.2.tgz",
- "integrity": "sha512-PoGX7/l0vWKt5JaAxcgFOdGje30Q6qSE06YzFIKh9Ba3oq7B60+TFqu7c2ErQt6sNddmvcAcAiLVNaTGAip3vw==",
- "dependencies": {
- "@fluidframework/common-definitions": "^0.20.1",
- "@types/events": "^3.0.0",
- "base64-js": "^1.5.1",
- "buffer": "^6.0.3",
- "events": "^3.1.0",
- "lodash": "^4.17.21",
- "sha.js": "^2.4.11"
- }
- },
- "node_modules/@fluidframework/server-services-client/node_modules/@fluidframework/protocol-definitions": {
- "version": "0.1028.2000",
- "resolved": "https://registry.npmjs.org/@fluidframework/protocol-definitions/-/protocol-definitions-0.1028.2000.tgz",
- "integrity": "sha512-ZUPCmPFcK7UAK4RkfVWfzQPAWFvYNm6ywP51V42YC38gCGye+Epvyr3beA+FSaHPIZGxm5+Uw52+ykTvmDb2UA==",
- "dependencies": {
- "@fluidframework/common-definitions": "^0.20.1"
- }
- },
- "node_modules/@fluidframework/server-services-client/node_modules/axios": {
- "version": "0.26.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
- "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
- "dependencies": {
- "follow-redirects": "^1.14.8"
- }
- },
- "node_modules/@fluidframework/server-services-client/node_modules/buffer": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
- "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.2.1"
- }
- },
- "node_modules/@fluidframework/server-services-client/node_modules/jwt-decode": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
- "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
- },
"node_modules/@fluidframework/shared-object-base": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/@fluidframework/shared-object-base/-/shared-object-base-1.3.7.tgz",
@@ -3430,6 +3442,11 @@
"integrity": "sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==",
"dev": true
},
+ "node_modules/@types/xmldom": {
+ "version": "0.1.34",
+ "resolved": "https://registry.npmjs.org/@types/xmldom/-/xmldom-0.1.34.tgz",
+ "integrity": "sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA=="
+ },
"node_modules/@types/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
@@ -5012,8 +5029,7 @@
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "dev": true
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/at-least-node": {
"version": "1.0.0",
@@ -5049,11 +5065,26 @@
}
},
"node_modules/axios": {
- "version": "0.21.4",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
- "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "version": "0.28.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.0.tgz",
+ "integrity": "sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==",
"dependencies": {
- "follow-redirects": "^1.14.0"
+ "follow-redirects": "^1.15.0",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/axios/node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
"node_modules/azure-devops-node-api": {
@@ -6399,7 +6430,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -7117,7 +7147,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "dev": true,
"engines": {
"node": ">=0.4.0"
}
@@ -11277,9 +11306,9 @@
}
},
"node_modules/ip": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
- "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz",
+ "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ=="
},
"node_modules/is-absolute": {
"version": "1.0.0",
@@ -12348,9 +12377,9 @@
]
},
"node_modules/jsrsasign": {
- "version": "10.8.6",
- "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.8.6.tgz",
- "integrity": "sha512-bQmbVtsfbgaKBTWCKiDCPlUPbdlRIK/FzSwT3BzIgZl/cU6TqXu6pZJsCI/dJVrZ9Gir5GC4woqw9shH/v7MBw==",
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-11.0.0.tgz",
+ "integrity": "sha512-BtRwVKS+5dsgPpAtzJcpo5OoWjSs1/zllSBG0+8o8/aV0Ki76m6iZwHnwnsqoTdhfFZDN1XIdcaZr5ZkP+H2gg==",
"funding": {
"url": "https://github.com/kjur/jsrsasign#donations"
}
@@ -15467,9 +15496,9 @@
}
},
"node_modules/pac-resolver/node_modules/ip": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
- "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz",
+ "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==",
"dev": true
},
"node_modules/package-hash": {
@@ -21392,6 +21421,14 @@
"node": ">=4.0"
}
},
+ "node_modules/xmldom": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz",
+ "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
diff --git a/package.json b/package.json
index 6b09ad17..2d648033 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,8 @@
"email": "PPTools@microsoft.com"
},
"engines": {
- "vscode": "^1.73.0"
+ "vscode": "^1.73.0",
+ "npm": ">=8.3.0"
},
"extensionKind": [
"workspace"
@@ -659,7 +660,7 @@
"command": "powerPlatform.previewCurrentActiveUsers",
"alt": "current active users",
"group": "navigation",
- "when": "never"
+ "when": "isWeb && virtualWorkspace"
}
],
"commandPalette": [
@@ -954,7 +955,7 @@
{
"id": "powerpages.collaborationView",
"name": "People On The Site",
- "when": "never",
+ "when": "isWeb && virtualWorkspace",
"contextualTitle": "People On The Site",
"visibility": "visible"
}
@@ -1021,6 +1022,8 @@
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "1.0.2",
+ "@microsoft/1ds-core-js": "4.0.5",
+ "@microsoft/1ds-post-js": "4.0.5",
"@types/chai": "^4.2.14",
"@types/command-exists": "^1.2.0",
"@types/debug": "^4.1.9",
@@ -1079,17 +1082,16 @@
"webpack": "^5.76.0",
"webpack-cli": "^4.7.0",
"webpack-stream": "^7.0.0",
- "yargs": "^16.2.0",
- "@microsoft/1ds-core-js": "4.0.5",
- "@microsoft/1ds-post-js": "4.0.5"
+ "yargs": "^16.2.0"
},
"dependencies": {
"@fluidframework/azure-client": "^1.1.1",
- "@microsoft/generator-powerpages": "1.21.19",
- "@types/jwt-decode": "2.2.0",
"@microsoft/1ds-core-js": "4.0.5",
"@microsoft/1ds-post-js": "4.0.5",
+ "@microsoft/generator-powerpages": "1.21.19",
+ "@types/jwt-decode": "2.2.0",
"@types/node-fetch": "^2.6.2",
+ "@types/xmldom": "^0.1.34",
"@vscode/extension-telemetry": "^0.6.2",
"cockatiel": "^3.1.1",
"command-exists": "^1.2.9",
@@ -1110,6 +1112,7 @@
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"worker-loader": "^3.0.8",
+ "xmldom": "^0.6.0",
"yaml": "^2.2.2"
},
"__metadata": {
@@ -1121,5 +1124,9 @@
"optionalDependencies": {
"bufferutil": "^4.0.6",
"utf-8-validate": "^5.0.9"
+ },
+ "overrides": {
+ "jsrsasign": "^11.0.0",
+ "axios": "^0.28.0"
}
-}
\ No newline at end of file
+}
diff --git a/src/common/OneDSLoggerTelemetry/oneDSLogger.ts b/src/common/OneDSLoggerTelemetry/oneDSLogger.ts
index e6a42737..15a6826a 100644
--- a/src/common/OneDSLoggerTelemetry/oneDSLogger.ts
+++ b/src/common/OneDSLoggerTelemetry/oneDSLogger.ts
@@ -16,7 +16,6 @@ import { EXTENSION_ID } from "../../client/constants";
import {OneDSCollectorEventName} from "./EventContants";
import { telemetryEventNames } from "../../web/client/telemetry/constants";
import { region } from "../telemetry-generated/buildRegionConfiguration";
-import { geoMappingsToAzureRegion } from "./shortNameMappingToAzureRegion";
interface IInstrumentationSettings {
endpointURL: string;
@@ -139,10 +138,6 @@ export class OneDSLogger implements ITelemetryLogger{
endpointURL: 'https://self.pipe.aria.int.microsoft.com/OneCollector/1.0/',
instrumentationKey: 'ffdb4c99ca3a4ad5b8e9ffb08bf7da0d-65357ff3-efcd-47fc-b2fd-ad95a52373f4-7402'
};
- let geoName = 'us';
- if(geoMappingsToAzureRegion[geo!]) {
- geoName = geoMappingsToAzureRegion[geo!].geoName;
- }
switch (buildRegion) {
case 'tie':
case 'test':
@@ -150,7 +145,7 @@ export class OneDSLogger implements ITelemetryLogger{
break;
case 'prod':
case 'preview':
- switch (geoName) {
+ switch (geo) {
case 'us':
case 'br':
case 'jp':
diff --git a/src/common/copilot/IntelligenceApiService.ts b/src/common/copilot/IntelligenceApiService.ts
index dc133a71..07add9e6 100644
--- a/src/common/copilot/IntelligenceApiService.ts
+++ b/src/common/copilot/IntelligenceApiService.ts
@@ -15,12 +15,13 @@ import { EXTENSION_NAME } from "../../client/constants";
const clientType = EXTENSION_NAME + '-' + getExtensionType();
const clientVersion = getExtensionVersion();
-export async function sendApiRequest(userPrompt: UserPrompt[], activeFileParams: IActiveFileParams, orgID: string, apiToken: string, sessionID: string, entityName: string, entityColumns: string[], telemetry: ITelemetry, aibEndpoint: string | null, geoName: string | null) {
+export async function sendApiRequest(userPrompt: UserPrompt[], activeFileParams: IActiveFileParams, orgID: string, apiToken: string, sessionID: string, entityName: string, entityColumns: string [], telemetry: ITelemetry, aibEndpoint: string | null, geoName: string | null) {
if (!aibEndpoint) {
return NetworkError;
}
+ // eslint-disable-next-line prefer-const
let requestBody = {
"question": userPrompt[0].displayText,
"top": 1,
diff --git a/src/common/copilot/PowerPagesCopilot.ts b/src/common/copilot/PowerPagesCopilot.ts
index 5767c3b5..535377c7 100644
--- a/src/common/copilot/PowerPagesCopilot.ts
+++ b/src/common/copilot/PowerPagesCopilot.ts
@@ -21,7 +21,7 @@ import { sendTelemetryEvent } from "./telemetry/copilotTelemetry";
import { INTELLIGENCE_SCOPE_DEFAULT, PROVIDER_ID } from "../../web/client/common/constants";
import { getIntelligenceEndpoint } from "../ArtemisService";
import TelemetryReporter from "@vscode/extension-telemetry";
-import { getEntityColumns, getEntityName } from "./dataverseMetadata";
+import { getEntityColumns, getEntityName, getFormXml } from "./dataverseMetadata";
import { COPILOT_STRINGS } from "./assets/copilotStrings";
import { isWithinTokenLimit, encode } from "gpt-tokenizer";
@@ -344,17 +344,24 @@ export class PowerPagesCopilot implements vscode.WebviewViewProvider {
this.sendMessageToWebview({ type: 'userName', value: userName });
- let entityName = "";
- let entityColumns: string[] = [];
+ let metadataInfo = { entityName: '', formName: '' };
+ let entityInfo : string [] = [];
if (activeFileParams.dataverseEntity == "adx_entityform" || activeFileParams.dataverseEntity == 'adx_entitylist') {
- entityName = await getEntityName(telemetry, sessionID, activeFileParams.dataverseEntity);
+ metadataInfo = await getEntityName(telemetry, sessionID, activeFileParams.dataverseEntity);
const dataverseToken = await dataverseAuthentication(activeOrgUrl, true);
- entityColumns = await getEntityColumns(entityName, activeOrgUrl, dataverseToken, telemetry, sessionID);
+ if (activeFileParams.dataverseEntity == "adx_entityform") {
+ const formColumns = await getFormXml(metadataInfo.entityName, metadataInfo.formName, activeOrgUrl, dataverseToken, telemetry, sessionID);
+ entityInfo = formColumns;
+ } else {
+ const entityColumns = await getEntityColumns(metadataInfo.entityName, activeOrgUrl, dataverseToken, telemetry, sessionID);
+ entityInfo = entityColumns;
+ }
+
}
- return sendApiRequest(data, activeFileParams, orgID, intelligenceApiToken, sessionID, entityName, entityColumns, telemetry, this.aibEndpoint, this.geoName);
+ return sendApiRequest(data, activeFileParams, orgID, intelligenceApiToken, sessionID, metadataInfo.entityName, entityInfo, telemetry, this.aibEndpoint, this.geoName);
})
.then(apiResponse => {
this.sendMessageToWebview({ type: 'apiResponse', value: apiResponse });
diff --git a/src/common/copilot/dataverseMetadata.ts b/src/common/copilot/dataverseMetadata.ts
index fb23b0e1..14bdf8a3 100644
--- a/src/common/copilot/dataverseMetadata.ts
+++ b/src/common/copilot/dataverseMetadata.ts
@@ -10,7 +10,8 @@ import yaml from 'yaml';
import { ITelemetry } from "../../client/telemetry/ITelemetry";
import { sendTelemetryEvent } from "./telemetry/copilotTelemetry";
import { CopilotDataverseMetadataFailureEvent, CopilotDataverseMetadataSuccessEvent, CopilotGetEntityFailureEvent, CopilotYamlParsingFailureEvent } from "./telemetry/telemetryConstants";
-import { getFileLogicalEntityName } from "../../web/client/utilities/fileAndEntityUtil";
+import { getFileLogicalEntityName, getFormLogicalName } from "../../web/client/utilities/fileAndEntityUtil";
+import { DOMParser } from "xmldom";
interface Attribute {
LogicalName: string;
@@ -44,6 +45,32 @@ export async function getEntityColumns(entityName: string, orgUrl: string, apiTo
}
}
+export async function getFormXml(entityName: string, formName: string, orgUrl: string, apiToken: string, telemetry: ITelemetry, sessionID: string): Promise<(string [])>{
+ try {
+ const dataverseURL = `${orgUrl.endsWith('/') ? orgUrl : orgUrl.concat('/')}api/data/v9.2/systemforms?$filter=objecttypecode eq '${entityName}' and name eq '${formName}'`;
+ const requestInit: RequestInit = {
+ method: "GET",
+ headers: {
+ 'Content-Type': "application/json",
+ Authorization: `Bearer ${apiToken}`,
+ },
+ };
+
+ const startTime = performance.now();
+ const jsonResponse = await fetchJsonResponse(dataverseURL, requestInit);
+ const endTime = performance.now();
+ const responseTime = endTime - startTime || 0;
+ const formxml =getFormXMLFromResponse(jsonResponse);
+
+ sendTelemetryEvent(telemetry, { eventName: CopilotDataverseMetadataSuccessEvent, copilotSessionId: sessionID, durationInMills: responseTime, orgUrl: orgUrl })
+ return parseXML(formxml);
+
+ } catch (error) {
+ sendTelemetryEvent(telemetry, { eventName: CopilotDataverseMetadataFailureEvent, copilotSessionId: sessionID, error: error as Error, orgUrl: orgUrl })
+ return [];
+ }
+}
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function fetchJsonResponse(url: string, requestInit: RequestInit): Promise {
const response = await fetch(url, requestInit);
@@ -64,9 +91,51 @@ function getAttributesFromResponse(jsonResponse: any): Attribute[] {
return [];
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+function getFormXMLFromResponse(jsonResponse: any): string {
+ if (jsonResponse.value[0].formxml) {
+ return jsonResponse.value[0].formxml;
+ }
+
+ return '';
+}
+
+function parseXML(formXml: string) {
+ const parser = new DOMParser();
+ const xmlDoc = parser.parseFromString(formXml, "text/xml");
+
+ // Get all 'row' elements
+ const rows = xmlDoc.getElementsByTagName('row');
+
+ const result = [];
+
+ // Iterate over all 'row' elements
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
+
+ // Get the 'label' and 'control' elements within the current 'row'
+ const label = row.getElementsByTagName('label')[0];
+ const control = row.getElementsByTagName('control')[0];
+
+ // If both 'label' and 'control' elements exist, create an object and add it to the result array
+ if (label && control) {
+ const description = label.getAttribute('description');
+ const datafieldname = control.getAttribute('datafieldname');
+ //const classid = control.getAttribute('classid');
+
+ if (description && datafieldname) {
+ result.push(description, datafieldname);
+ }
+ }
+ }
+
+ return result
+}
+
-export async function getEntityName(telemetry: ITelemetry, sessionID: string, dataverseEntity: string): Promise {
+export async function getEntityName(telemetry: ITelemetry, sessionID: string, dataverseEntity: string): Promise<{entityName: string, formName: string}> {
let entityName = '';
+ let formName = '';
try {
const activeEditor = vscode.window.activeTextEditor;
@@ -86,15 +155,17 @@ export async function getEntityName(telemetry: ITelemetry, sessionID: string, da
const yamlContent = diskRead.readFileSync(yamlFilePath, 'utf8');
const parsedData = parseYamlContent(yamlContent, telemetry, sessionID, dataverseEntity);
entityName = parsedData['adx_entityname'] || parsedData['adx_targetentitylogicalname'];
+ formName = parsedData['adx_formname'];
} else if (!IS_DESKTOP) {
entityName = getFileLogicalEntityName(document.uri.fsPath);
+ formName = getFormLogicalName(document.uri.fsPath);
}
}
} catch (error) {
sendTelemetryEvent(telemetry, { eventName: CopilotGetEntityFailureEvent, copilotSessionId: sessionID, dataverseEntity: dataverseEntity, error: error as Error });
entityName = '';
}
- return entityName;
+ return {entityName, formName};
}
async function getMatchingFiles(folderPath: string, fileNameFirstPart: string): Promise {
diff --git a/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts b/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts
index d3c86f8f..72dd3f37 100644
--- a/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts
+++ b/src/common/copilot/welcome-notification/CopilotNotificationPanel.ts
@@ -19,8 +19,6 @@ export async function copilotNotificationPanel(context: vscode.ExtensionContext,
NotificationPanel = createNotificationPanel();
- console.log(telemetry, telemetryData, countOfActivePortals)
-
const { notificationCssUri, notificationJsUri, copilotImageUri, arrowImageUri } = getWebviewURIs(context, NotificationPanel);
const nonce = getNonce();
diff --git a/src/web/client/WebExtensionContext.ts b/src/web/client/WebExtensionContext.ts
index a24d96ea..14a80ea7 100644
--- a/src/web/client/WebExtensionContext.ts
+++ b/src/web/client/WebExtensionContext.ts
@@ -402,7 +402,8 @@ class WebExtensionContext implements IWebExtensionContext {
encodeAsBase64: boolean,
mimeType?: string,
isContentLoaded?: boolean,
- logicalEntityName?: string
+ logicalEntityName?: string,
+ logicalFormName?: string
) {
this.fileDataMap.setEntity(
fileUri,
@@ -415,7 +416,8 @@ class WebExtensionContext implements IWebExtensionContext {
encodeAsBase64,
mimeType,
isContentLoaded,
- logicalEntityName);
+ logicalEntityName,
+ logicalFormName);
}
public async updateEntityDetailsInContext(
diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts
index 060a9ae1..6ef7ecfe 100644
--- a/src/web/client/common/constants.ts
+++ b/src/web/client/common/constants.ts
@@ -98,7 +98,7 @@ export enum queryParameters {
ORG_URL = "orgurl",
REGION = "region",
ENV_ID = "envid",
- GEO = "geo",
+ GEO = "geo", // User geo location
ENABLE_MULTIFILE = "enablemultifile",
WEBSITE_PREVIEW_URL = "websitepreviewurl",
ENTITY = "entity",
diff --git a/src/web/client/context/fileData.ts b/src/web/client/context/fileData.ts
index 2097ae12..e5389794 100644
--- a/src/web/client/context/fileData.ts
+++ b/src/web/client/context/fileData.ts
@@ -30,6 +30,7 @@ export class FileData implements IFileData {
private _mimeType: string | undefined;
private _isContentLoaded: boolean | undefined;
private _logicalEntityName: string | undefined;
+ private _logicalFormName: string | undefined;
// Getters
public get entityName(): string {
@@ -70,6 +71,11 @@ export class FileData implements IFileData {
return this._logicalEntityName;
}
+ public get logicalFormName(): string | undefined {
+ return this._logicalFormName;
+ }
+
+
// Setters
public set setHasDirtyChanges(value: boolean) {
this._hasDirtyChanges = value;
@@ -85,6 +91,10 @@ export class FileData implements IFileData {
this._logicalEntityName = value;
}
+ public set setLogicalFormName(value: string | undefined) {
+ this._logicalFormName = value;
+ }
+
constructor(
entityId: string,
entityName: string,
@@ -95,7 +105,8 @@ export class FileData implements IFileData {
encodeAsBase64?: boolean,
mimeType?: string,
isContentLoaded?: boolean,
- logicalEntityName?: string
+ logicalEntityName?: string,
+ logicalFormName?: string
) {
this._entityId = entityId;
this._entityName = entityName;
@@ -109,5 +120,6 @@ export class FileData implements IFileData {
this._hasDiffViewTriggered = false;
this._isContentLoaded = isContentLoaded;
this._logicalEntityName = logicalEntityName;
+ this._logicalFormName = logicalFormName;
}
}
diff --git a/src/web/client/context/fileDataMap.ts b/src/web/client/context/fileDataMap.ts
index 47979077..b3b65693 100644
--- a/src/web/client/context/fileDataMap.ts
+++ b/src/web/client/context/fileDataMap.ts
@@ -25,7 +25,8 @@ export class FileDataMap {
isBase64Encoded: boolean,
mimeType?: string,
isContentLoaded?: boolean,
- logicalEntityName?: string
+ logicalEntityName?: string,
+ logicalFormName?: string
) {
const fileData = new FileData(
entityId,
@@ -37,7 +38,8 @@ export class FileDataMap {
isBase64Encoded,
mimeType,
isContentLoaded,
- logicalEntityName
+ logicalEntityName,
+ logicalFormName
);
this.fileMap.set(vscode.Uri.parse(fileUri).fsPath, fileData);
}
diff --git a/src/web/client/dal/remoteFetchProvider.ts b/src/web/client/dal/remoteFetchProvider.ts
index 1ae78b2d..0e9802e5 100644
--- a/src/web/client/dal/remoteFetchProvider.ts
+++ b/src/web/client/dal/remoteFetchProvider.ts
@@ -14,7 +14,7 @@ import {
isWebfileContentLoadNeeded,
setFileContent,
} from "../utilities/commonUtil";
-import { getCustomRequestURL, getLogicalEntityName, getMappingEntityContent, getMappingEntityId, getMimeType, getRequestURL } from "../utilities/urlBuilderUtil";
+import { getCustomRequestURL, getMappingEntityContent, getMappingEntityId, getMetadataInfo, getMimeType, getRequestURL } from "../utilities/urlBuilderUtil";
import { getCommonHeaders } from "../common/authenticationProvider";
import * as Constants from "../common/constants";
import { ERRORS, showErrorDialog } from "../common/errorHandler";
@@ -24,6 +24,7 @@ import {
getAttributePath,
getEntity,
getLogicalEntityParameter,
+ getLogicalFormNameParameter,
isBase64Encoded,
} from "../utilities/schemaHelperUtil";
import WebExtensionContext from "../WebExtensionContext";
@@ -431,6 +432,7 @@ async function createFile(
// By default content is preloaded for all the files except for non-text webfiles for V2
const isPreloadedContent = mappingEntityFetchQuery ? isWebfileContentLoadNeeded(fileNameWithExtension, fileUri) : true;
const logicalEntityName = getLogicalEntityParameter(entityName);
+ const logicalFormNameParameter = getLogicalFormNameParameter(entityName);
// update func for webfiles for V2
const attributePath: IAttributePath = getAttributePath(
@@ -453,6 +455,9 @@ async function createFile(
fileContent = getAttributeContent(result, attributePath, entityName, entityId);
}
+ const metadataKeys = [logicalEntityName, logicalFormNameParameter];
+ const metadataValues = getMetadataInfo(result, metadataKeys.filter(key => key !== undefined) as string[]);
+
await createVirtualFile(
portalsFS,
fileUri,
@@ -468,7 +473,8 @@ async function createFile(
mimeType ?? result[Constants.MIMETYPE],
isPreloadedContent,
mappingEntityId,
- getLogicalEntityName(result, logicalEntityName),
+ metadataValues[logicalEntityName ?? ''] ?? '',
+ metadataValues[logicalFormNameParameter ?? ''] ?? '',
rootWebPageId,
);
}
@@ -620,6 +626,7 @@ async function createVirtualFile(
isPreloadedContent?: boolean,
mappingEntityId?: string,
logicalEntityName?: string,
+ logicalFormName?: string,
rootWebPageId?: string,
) {
// Maintain file information in context
@@ -634,7 +641,8 @@ async function createVirtualFile(
encodeAsBase64,
mimeType,
isPreloadedContent,
- logicalEntityName
+ logicalEntityName,
+ logicalFormName
);
// Call file system provider write call for buffering file data in VFS
diff --git a/src/web/client/extension.ts b/src/web/client/extension.ts
index df30945f..581b231d 100644
--- a/src/web/client/extension.ts
+++ b/src/web/client/extension.ts
@@ -92,12 +92,9 @@ export function activate(context: vscode.ExtensionContext): void {
);
}
}
- const geo = queryParamsMap.get('geo')?.toLowerCase();
- // Authenticated scenario. Pass the geo to OneDSLogger for data boundary
- if(geo){
- oneDSLoggerWrapper.instantiate(geo);
- }
-
+ const orgId = queryParamsMap.get(queryParameters.ORG_ID) as string;
+ const orgGeo = await fetchArtemisData(orgId);
+ oneDSLoggerWrapper.instantiate(orgGeo);
if (
!checkMandatoryParameters(
appName,
@@ -601,6 +598,16 @@ function isActiveDocument(fileFsPath: string): boolean {
);
}
+async function fetchArtemisData(orgId: string) : Promise {
+ const artemisResponse = await fetchArtemisResponse(orgId, WebExtensionContext.telemetry.getTelemetryReporter());
+ if (!artemisResponse) {
+ // Todo: Log in error telemetry. Runtime maintains another table for this kind of failure. We should do the same.
+ return '';
+ }
+
+ return artemisResponse[0].geoName as string;
+}
+
async function logArtemisTelemetry() {
try {
@@ -608,13 +615,7 @@ async function logArtemisTelemetry() {
queryParameters.ORG_ID
) as string
- const artemisResponse = await fetchArtemisResponse(orgId, WebExtensionContext.telemetry.getTelemetryReporter());
-
- if (!artemisResponse) {
- return;
- }
-
- const { geoName } = artemisResponse[0];
+ const geoName= fetchArtemisData(orgId);
WebExtensionContext.telemetry.sendInfoTelemetry(telemetryEventNames.WEB_EXTENSION_ARTEMIS_RESPONSE,
{ orgId: orgId, geoName: String(geoName) });
} catch (error) {
diff --git a/src/web/client/schema/constants.ts b/src/web/client/schema/constants.ts
index 60cfb451..af80629b 100644
--- a/src/web/client/schema/constants.ts
+++ b/src/web/client/schema/constants.ts
@@ -35,6 +35,7 @@ export enum schemaEntityKey {
export enum schemaMetaDataKey {
DATAVERSE_LOGICAL_ENTITY_NAME = "_dataverselogicalentityname",
+ DATAVERSE_FORM_NAME = "_dataverseformname",
}
export enum schemaEntityName {
diff --git a/src/web/client/schema/portalSchema.ts b/src/web/client/schema/portalSchema.ts
index 5ac54ef7..950e7956 100644
--- a/src/web/client/schema/portalSchema.ts
+++ b/src/web/client/schema/portalSchema.ts
@@ -379,7 +379,7 @@ export const portal_schema_V2 = {
relationships: "",
_vscodeentityname: "basicforms",
_dataverseenityname: "powerpagecomponents",
- _dataverseentitymetadata: new Map([["_dataverselogicalentityname", "content.entityname"]]),
+ _dataverseentitymetadata: new Map([["_dataverselogicalentityname", "content.entityname"], ["_dataverseformname", "content.formname"]]),
_displayname: "Basic Forms",
_etc: "10271",
_primaryidfield: "powerpagecomponentid",
diff --git a/src/web/client/telemetry/webExtensionTelemetry.ts b/src/web/client/telemetry/webExtensionTelemetry.ts
index db39fffc..b561c883 100644
--- a/src/web/client/telemetry/webExtensionTelemetry.ts
+++ b/src/web/client/telemetry/webExtensionTelemetry.ts
@@ -29,10 +29,14 @@ export class WebExtensionTelemetry {
eventName: telemetryEventNames.WEB_EXTENSION_INIT_PATH_PARAMETERS,
properties: {
appName: this.getPathParameterValue(appName),
- entity: this.getPathParameterValue(entity),
- entityId: this.getPathParameterValue(entityId)
}
}
+
+ if (entity && entityId) {
+ telemetryData.properties.entity = this.getPathParameterValue(entity),
+ telemetryData.properties.entityId = this.getPathParameterValue(entityId)
+ }
+
this._telemetry?.sendTelemetryEvent(telemetryData.eventName, telemetryData.properties);
oneDSLoggerWrapper.getLogger().traceInfo(telemetryData.eventName, telemetryData.properties);
}
@@ -56,6 +60,12 @@ export class WebExtensionTelemetry {
referrerSource: queryParamsMap.get(queryParameters.REFERRER_SOURCE)
}
}
+
+ if (queryParamsMap.has(queryParameters.ENTITY) && queryParamsMap.has(queryParameters.ENTITY_ID)) {
+ telemetryData.properties.entity = queryParamsMap.get(queryParameters.ENTITY);
+ telemetryData.properties.entityId = queryParamsMap.get(queryParameters.ENTITY_ID);
+ }
+
this._telemetry?.sendTelemetryEvent(telemetryData.eventName, telemetryData.properties);
oneDSLoggerWrapper.getLogger().traceInfo(telemetryData.eventName, telemetryData.properties);
}
diff --git a/src/web/client/test/integration/webExtensionTelemetry.test.ts b/src/web/client/test/integration/webExtensionTelemetry.test.ts
index 02dcce9a..94e0a87a 100644
--- a/src/web/client/test/integration/webExtensionTelemetry.test.ts
+++ b/src/web/client/test/integration/webExtensionTelemetry.test.ts
@@ -69,8 +69,6 @@ describe("webExtensionTelemetry", () => {
//Assert
const properties = {
appName: "",
- entity: "",
- entityId: "",
};
assert.calledOnceWithExactly(
sendTelemetryEvent,
@@ -100,6 +98,11 @@ describe("webExtensionTelemetry", () => {
[queryParameters.REGION, "NAM"],
[queryParameters.GEO, "US"],
[queryParameters.ENV_ID, "c4dc3686-1e6b-e428-b886-16cd0b9f4918"],
+ [queryParameters.ENTITY, "webpage"],
+ [
+ queryParameters.ENTITY_ID,
+ "e5dce21c-f85f-4849-b699-920c0fad5fbf",
+ ],
[queryParameters.REFERRER_SOURCE, "test"],
]);
@@ -119,6 +122,8 @@ describe("webExtensionTelemetry", () => {
region: queryParamsMap.get(queryParameters.REGION),
geo: queryParamsMap.get(queryParameters.GEO),
envId: queryParamsMap.get(queryParameters.ENV_ID),
+ entity: queryParamsMap.get(queryParameters.ENTITY),
+ entityId: queryParamsMap.get(queryParameters.ENTITY_ID),
referrerSource: queryParamsMap.get(queryParameters.REFERRER_SOURCE),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any;
diff --git a/src/web/client/utilities/commonUtil.ts b/src/web/client/utilities/commonUtil.ts
index f1828075..56562cd7 100644
--- a/src/web/client/utilities/commonUtil.ts
+++ b/src/web/client/utilities/commonUtil.ts
@@ -151,9 +151,7 @@ export function isCoPresenceEnabled() {
);
}
- // return isCoPresenceEnabled as boolean;
- // this feature is under development and will be enabled in future
- return false;
+ return isCoPresenceEnabled as boolean;
}
/**
diff --git a/src/web/client/utilities/fileAndEntityUtil.ts b/src/web/client/utilities/fileAndEntityUtil.ts
index 27fd8105..b72ddc60 100644
--- a/src/web/client/utilities/fileAndEntityUtil.ts
+++ b/src/web/client/utilities/fileAndEntityUtil.ts
@@ -43,6 +43,10 @@ export function getFileLogicalEntityName(fileFsPath: string) {
?.logicalEntityName as string;
}
+export function getFormLogicalName(fileFsPath: string) {
+ return WebExtensionContext.fileDataMap.getFileMap.get(fileFsPath)?.logicalFormName as string;
+}
+
export function updateFileEntityEtag(fileFsPath: string, entityEtag: string) {
WebExtensionContext.fileDataMap.updateEtagValue(fileFsPath, entityEtag);
}
diff --git a/src/web/client/utilities/schemaHelperUtil.ts b/src/web/client/utilities/schemaHelperUtil.ts
index 5867d2e5..192a63ba 100644
--- a/src/web/client/utilities/schemaHelperUtil.ts
+++ b/src/web/client/utilities/schemaHelperUtil.ts
@@ -27,6 +27,11 @@ export function getLogicalEntityParameter(entity: string) {
return entityMetadata ? (entityMetadata as unknown as Map).get(schemaMetaDataKey.DATAVERSE_LOGICAL_ENTITY_NAME) : undefined;
}
+export function getLogicalFormNameParameter(entity: string) {
+ const entityMetadata = getEntity(entity)?.get(schemaEntityKey.DATAVERSE_ENTITY_METADATA);
+ return entityMetadata ? (entityMetadata as unknown as Map).get(schemaMetaDataKey.DATAVERSE_FORM_NAME) : undefined;
+}
+
export function getPortalSchema(schema: string) {
if (
schema.toLowerCase() ===
diff --git a/src/web/client/utilities/urlBuilderUtil.ts b/src/web/client/utilities/urlBuilderUtil.ts
index 94c779c9..07a20aee 100644
--- a/src/web/client/utilities/urlBuilderUtil.ts
+++ b/src/web/client/utilities/urlBuilderUtil.ts
@@ -216,6 +216,25 @@ export function getLogicalEntityName(result: any, logicalEntityName?: string) {
return logicalEntity;
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function getMetadataInfo(result: any, metadataKeys?: string[]) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const metadataValues: { [key: string]: any } = {};
+
+ if (metadataKeys) {
+ // eslint-disable-next-line prefer-const
+ for (let key of metadataKeys) {
+ const attributePath = getAttributePath(key);
+ const value = attributePath.relativePath.length > 0 ?
+ JSON.parse(result[attributePath.source])[attributePath.relativePath] :
+ result[attributePath.source];
+ metadataValues[key] = value;
+ }
+ }
+
+ return metadataValues;
+}
+
export function pathHasEntityFolderName(uri: string): boolean {
for (const entry of WebExtensionContext.entitiesFolderNameMap.entries()) {
if (uri.includes(entry[1])) {