push neon reactor
This commit is contained in:
+153
@@ -0,0 +1,153 @@
|
||||
MICROSOFT SOFTWARE LICENSE TERMS
|
||||
MICROSOFT POWER PLATFORM – @MICROSOFT/POWER-APPS
|
||||
|
||||
August 2025
|
||||
These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates). They
|
||||
apply to the software named above and any Microsoft services or software updates (except to the extent such
|
||||
services or updates are accompanied by new or additional terms, in which case those different terms apply
|
||||
prospectively and do not alter your or Microsoft’s rights relating to pre-updated software or services). IF YOU
|
||||
COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU
|
||||
ACCEPT THESE TERMS.
|
||||
1. INSTALLATION AND USE RIGHTS.
|
||||
a) General. You may install and use any number of copies of the software to develop and test your
|
||||
applications.
|
||||
b) Third Party Components. The software may include third party components with separate legal
|
||||
notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s)
|
||||
accompanying the software.
|
||||
c) Work or School Accounts. You can sign into the software with a work or school email address. If
|
||||
you do, you agree that the owner of the domain associated with your email address may control and
|
||||
administer your account, and access and process your data, including the contents of your
|
||||
communications and files. You further agree that your use of the software may be subject to: i) your
|
||||
organization’s guidelines and policies regarding the use of the software; and ii) the agreements
|
||||
Microsoft has with you or your organization, and in such case these terms may not apply. If you
|
||||
already have a Microsoft account and you use a separate work or school email address to access the
|
||||
software, you may be prompted to update the email address associated with your Microsoft account to
|
||||
continue accessing the software.
|
||||
2. SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all other rights. Unless
|
||||
applicable law gives you more rights despite this limitation, you will not (and have no right to):
|
||||
a) work around any technical limitations in the software that only allow you to use it in certain ways;
|
||||
b) reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source
|
||||
code for the software, except and to the extent required by third party licensing terms governing use
|
||||
of certain open source components that may be included in the software;
|
||||
c) remove, minimize, block, or modify any notices of Microsoft or its suppliers in the software;
|
||||
d) use the software in any way that is against the law or to create or propagate malware; or
|
||||
e) share, publish, distribute, or lease the software (except for any distributable code, subject to the
|
||||
terms above), provide the software as a stand-alone offering for others to use, or transfer the
|
||||
software or this agreement to any third party.
|
||||
3. DATA.
|
||||
a) Data Collection. The software may collect information about you and your use of the software, and
|
||||
send that to Microsoft. Microsoft may use this information to provide services and improve our
|
||||
products and services. You may opt-out of many of these scenarios, but not all, as described in the
|
||||
product documentation. There are also some features in the software that may enable you to collect
|
||||
data from users of your applications. If you use these features to enable data collection in your
|
||||
applications, you must comply with applicable law, including providing appropriate notices to users of
|
||||
your applications. You can learn more about data collection and use in the help documentation and
|
||||
the privacy statement at https://go.microsoft.com/fwlink/?linkid=521839. Your use of the software
|
||||
operates as your consent to these practices.
|
||||
b) Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal
|
||||
data in connection with the software, Microsoft makes the commitments in the European Union
|
||||
General Data Protection Regulation Terms of the Microsoft Products and Services Data Protection
|
||||
Addendum to all customers effective May 25, 2018, at
|
||||
https://go.microsoft.com/fwlink/?linkid=2135030.
|
||||
4. COMPLIANCE WITH TRADE LAWS. Microsoft products, software, technology, and services (“Items”)
|
||||
may be subject to U.S. and other countries’ export jurisdictions. Each party will comply with all laws and
|
||||
regulations applicable to the import or export of the Items, including, without limitation, trade laws of the
|
||||
U.S., EU, and UK, such as the U.S. Export Administration Regulations, sanctions regulations administered
|
||||
by the U.S. Office of Foreign Assets Control, the EU Dual Use Regulation 2021/821, and/or other end-user,
|
||||
end use, and destination restrictions (“Trade Laws”) as well as the global legal compliance standards
|
||||
detailed in the Microsoft Standards of Business Conduct. Customer will not, and will ensure its Affiliates
|
||||
will not, take any action that causes Microsoft to violate applicable Trade Laws. Microsoft may suspend or
|
||||
terminate this agreement immediately without notice to the extent that Microsoft reasonably believes that
|
||||
performance would cause it to violate Trade Laws or put it at risk of becoming subject to sanctions and
|
||||
penalties under such laws. Customer remains responsible for its and for its Affiliates’ compliance with this
|
||||
section and, to the extent applicable, the Regional Trade Compliance Addendum incorporated herein by
|
||||
reference.
|
||||
5. SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any support services for
|
||||
the software. Any support provided is “as is”, “with all faults”, and without warranty of any kind.
|
||||
6. ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for supplements,
|
||||
updates, or third-party applications, is the entire agreement for the software.
|
||||
7. APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in the United
|
||||
States or Canada, the laws of the state or province where you live (or, if a business, where your principal
|
||||
place of business is located) govern the interpretation of this agreement, claims for its breach, and all
|
||||
other claims (including consumer protection, unfair competition, and tort claims), regardless of conflict of
|
||||
laws principles. If you acquired the software in any other country, its laws apply. If U.S. federal jurisdiction
|
||||
exists, you and Microsoft consent to exclusive jurisdiction and venue in the federal court in King County,
|
||||
Washington for all disputes heard in court. If not, you and Microsoft consent to exclusive jurisdiction and
|
||||
venue in the Superior Court of King County, Washington for all disputes heard in court.
|
||||
8. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You
|
||||
may have other rights, including consumer rights, under the laws of your state or country. Separate and
|
||||
apart from your relationship with Microsoft, you may also have rights with respect to the party from which
|
||||
you acquired the software. This agreement does not change those other rights if the laws of your state or
|
||||
country do not permit it to do so. For example, if you acquired the software in one of the below regions, or
|
||||
mandatory country law applies, then the following provisions apply to you:
|
||||
a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this
|
||||
agreement is intended to affect those rights.
|
||||
b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the
|
||||
automatic update feature, disconnecting your device from the Internet (if and when you re-connect to
|
||||
the Internet, however, the software will resume checking for and installing updates), or uninstalling
|
||||
the software. The product documentation, if any, may also specify how to turn off updates for your
|
||||
specific device or software.
|
||||
c) Germany and Austria.
|
||||
i. Warranty. The properly licensed software will perform substantially as described in any Microsoft
|
||||
materials that accompany the software. However, Microsoft gives no contractual guarantee in
|
||||
relation to the licensed software.
|
||||
ii. Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the
|
||||
Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable
|
||||
according to the statutory law.
|
||||
Subject to the foregoing clause ii., Microsoft will only be liable for slight negligence if Microsoft is in
|
||||
breach of such material contractual obligations, the fulfillment of which facilitate the due performance
|
||||
of this agreement, the breach of which would endanger the purpose of this agreement and the
|
||||
compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases
|
||||
of slight negligence, Microsoft will not be liable for slight negligence.
|
||||
9. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF
|
||||
USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS.
|
||||
TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED
|
||||
WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
||||
NON-INFRINGEMENT.
|
||||
10. LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING
|
||||
DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM
|
||||
MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT
|
||||
RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL,
|
||||
INDIRECT, OR INCIDENTAL DAMAGES.
|
||||
This limitation applies to (a) anything related to the software, services, content (including
|
||||
code) on third party Internet sites, or third party applications; and (b) claims for breach of
|
||||
contract, warranty, guarantee, or condition; strict liability, negligence, or other tort; or any
|
||||
other claim; in each case to the extent permitted by applicable law.
|
||||
It also applies even if Microsoft knew or should have known about the possibility of the
|
||||
damages. The above limitation or exclusion may not apply to you because your state,
|
||||
province, or country may not allow the exclusion or limitation of incidental, consequential, or
|
||||
other damages.
|
||||
|
||||
Please note: As this software is distributed in Canada, some of the clauses in this agreement are
|
||||
provided below in French.
|
||||
Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat sont
|
||||
fournies ci-dessous en français.
|
||||
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute
|
||||
utilisation de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre
|
||||
garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la
|
||||
protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le
|
||||
droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et
|
||||
d’absence de contrefaçon sont exclues.
|
||||
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES
|
||||
DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de
|
||||
dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune
|
||||
indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou
|
||||
accessoires et pertes de bénéfices.
|
||||
Cette limitation concerne:
|
||||
• tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur
|
||||
des sites Internet tiers ou dans des programmes tiers; et
|
||||
• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité
|
||||
stricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.
|
||||
Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un
|
||||
tel dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les
|
||||
dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou
|
||||
l’exclusion ci-dessus ne s’appliquera pas à votre égard.
|
||||
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir
|
||||
d’autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que
|
||||
vous confèrent les lois de votre pays si celles-ci ne le permettent pas.
|
||||
|
||||
|
||||
DWT 28909173v1 0085000-001126
|
||||
|
||||
|
||||
DWT 28909173v1 0085000-001126
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
# @microsoft/power-apps-vite
|
||||
|
||||
Extended Vite support for developing Power Apps code apps.
|
||||
|
||||
# Who is this for?
|
||||
|
||||
Developers using Vite or a Vite-based template for developing their Power Apps code apps.
|
||||
|
||||
# Why use this plugin?
|
||||
|
||||
This plugin streamlines the experience of developing Power Apps code apps by leveraging Vite-specific tools.
|
||||
|
||||
It does this by configuring your build settings for Power Apps and letting the Power Apps host communicate with your Vite dev server. All you need to do is run `vite` or `npm run dev` and the plugin will print out a URL where you can open, interact, and test your local app using the Power Apps host, which gives you full access to the Power Platform connectors, services and authentication exposed via the Power Apps SDK `@microsoft/power-apps`.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install @microsoft/power-apps-vite --save-dev
|
||||
|
||||
# yarn
|
||||
yarn add @microsoft/power-apps-vite --dev
|
||||
|
||||
# pnpm
|
||||
pnpm add @microsoft/power-apps-vite --save-dev
|
||||
|
||||
# bun
|
||||
bun add @microsoft/power-apps-vite --dev
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Add the plugin to your Vite config
|
||||
|
||||
```ts
|
||||
// vite.config.ts
|
||||
import { defineConfig } from 'vite';
|
||||
import { powerApps } from '@microsoft/power-apps-vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [powerApps()],
|
||||
});
|
||||
```
|
||||
|
||||
That's it! No need to further modify your `vite.config.ts` or `package.json` scripts.
|
||||
|
||||
### 2. Set up your app with Power Apps and create a `power.config.json`
|
||||
|
||||
Run `pac code init` in your project root. It will create a power.config.json required for running your app.
|
||||
|
||||
## Usage
|
||||
|
||||
Start your Vite dev server:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# pnpm
|
||||
pnpm dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
|
||||
The plugin will output a **Local Play URL** in the console:
|
||||
|
||||
```
|
||||
Power Apps Vite Plugin
|
||||
|
||||
➜ Local Play: https://apps.powerapps.com/play/e/{environmentId}/a/local?_localAppUrl=...
|
||||
```
|
||||
|
||||
Open this URL in your browser to run your app in the Power Apps host.
|
||||
|
||||
## Features
|
||||
|
||||
- **Standalone** – `pac code run` is not needed when using this plugin. You can open your local app using the Power Apps host by just running the Vite dev server. No other changes to `vite.config.ts` and `package.json` scripts are required if using the plugin.
|
||||
- **Convenience** – Prints a ready-to-use URL for testing using the Power Apps host.
|
||||
- **Hot reload** – Changes to `power.config.json` automatically restart the dev server.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js >= 18
|
||||
- Vite >= 5.0.0
|
||||
|
||||
## License
|
||||
|
||||
See LICENSE file.
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
export { powerApps } from './plugin/index.js';
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.powerApps = void 0;
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
var index_js_1 = require("./plugin/index.js");
|
||||
Object.defineProperty(exports, "powerApps", { enumerable: true, get: function () { return index_js_1.powerApps; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,8CAA8C;AAArC,qGAAA,SAAS,OAAA"}
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
export { powerApps } from './powerApps.js';
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
||||
Generated
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.powerApps = void 0;
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
var powerApps_js_1 = require("./powerApps.js");
|
||||
Object.defineProperty(exports, "powerApps", { enumerable: true, get: function () { return powerApps_js_1.powerApps; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA"}
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
import type { Plugin } from 'vite';
|
||||
export declare function powerApps(): Plugin;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"powerApps.d.ts","sourceRoot":"","sources":["../../src/plugin/powerApps.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAOlD,wBAAgB,SAAS,IAAI,MAAM,CAqBlC"}
|
||||
Generated
Vendored
+190
@@ -0,0 +1,190 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.powerApps = void 0;
|
||||
var picocolors_1 = __importDefault(require("picocolors"));
|
||||
var node_fs_1 = require("node:fs");
|
||||
var node_path_1 = require("node:path");
|
||||
var utils_js_1 = require("./utils.js");
|
||||
function powerApps() {
|
||||
return {
|
||||
name: 'powerApps',
|
||||
config: function () {
|
||||
return {
|
||||
// Needed for publishing static assets correctly
|
||||
base: './',
|
||||
// Automatically inject CORS configuration needed for Vite 7+
|
||||
server: {
|
||||
cors: {
|
||||
origin: utils_js_1.powerAppsCorsOrigins,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
configureServer: function (server) {
|
||||
printLocalPlayUrl(server);
|
||||
servePowerConfig(server);
|
||||
watchPowerConfig(server);
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.powerApps = powerApps;
|
||||
function getLocalBaseUrl(server) {
|
||||
var _a, _b;
|
||||
// Vite 6+
|
||||
if ((_b = (_a = server.resolvedUrls) === null || _a === void 0 ? void 0 : _a.local) === null || _b === void 0 ? void 0 : _b[0]) {
|
||||
return server.resolvedUrls.local[0];
|
||||
}
|
||||
// In Vite 5 and below, resolvedUrls may not be available, fallback to httpServer address
|
||||
var address = server.httpServer.address();
|
||||
if (typeof address === 'string') {
|
||||
return address;
|
||||
}
|
||||
if (typeof address === 'object' && address !== null) {
|
||||
var rawHost = address.address, port = address.port;
|
||||
var host = rawHost === '::1' ? 'localhost' : rawHost;
|
||||
var https = server.config.server.https;
|
||||
return "".concat(https ? 'https' : 'http', "://").concat(host, ":").concat(port, "/");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Cache for power config to avoid repeated file reads
|
||||
var cachedPowerConfig = null;
|
||||
function getPowerConfig(server) {
|
||||
if (cachedPowerConfig) {
|
||||
return cachedPowerConfig;
|
||||
}
|
||||
var configPath = (0, node_path_1.join)(server.config.root, 'power.config.json');
|
||||
try {
|
||||
var configContent = (0, node_fs_1.readFileSync)(configPath, 'utf-8');
|
||||
var parsed = JSON.parse(configContent);
|
||||
if (!(0, utils_js_1.isPowerConfig)(parsed)) {
|
||||
throw new Error('Invalid power.config.json structure. Missing environmentId.');
|
||||
}
|
||||
cachedPowerConfig = parsed;
|
||||
return parsed;
|
||||
}
|
||||
catch (error) {
|
||||
// Handle specific error types
|
||||
if (error.code === 'ENOENT') {
|
||||
throw new Error("Missing file. Ensure you have run 'pac code init' first. power.config.json expected at ".concat(configPath, "."));
|
||||
}
|
||||
if (error instanceof SyntaxError) {
|
||||
throw new Error("Invalid JSON in power.config.json: ".concat(error.message));
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
function watchPowerConfig(server) {
|
||||
var configPath = (0, node_path_1.join)(server.config.root, 'power.config.json');
|
||||
server.watcher.add(configPath);
|
||||
server.watcher.on('change', function (file) {
|
||||
if (file === configPath) {
|
||||
server.config.logger.info(picocolors_1.default.yellow('[powerApps] power.config.json changed, restarting server...'));
|
||||
// Clear cache so new config is loaded
|
||||
cachedPowerConfig = null;
|
||||
server.restart();
|
||||
}
|
||||
});
|
||||
}
|
||||
function getWebPlayerBaseUrl(region) {
|
||||
if (!region) {
|
||||
return 'https://apps.powerapps.com';
|
||||
}
|
||||
region = region.toLowerCase();
|
||||
switch (region) {
|
||||
case 'public':
|
||||
case 'prod':
|
||||
return 'https://apps.powerapps.com';
|
||||
case 'preprod':
|
||||
return 'https://apps.preprod.powerapps.com';
|
||||
case 'test':
|
||||
return 'https://apps.test.powerapps.com';
|
||||
case 'preview':
|
||||
return 'https://apps.preview.powerapps.com';
|
||||
case 'usgov':
|
||||
case 'gccmoderate':
|
||||
return 'https://apps.gov.powerapps.us';
|
||||
case 'usgovhigh':
|
||||
case 'gcchigh':
|
||||
return 'https://apps.high.powerapps.us';
|
||||
case 'usgovdod':
|
||||
case 'dod':
|
||||
return 'https://play.apps.appsplatform.us';
|
||||
case 'china':
|
||||
case 'mooncake':
|
||||
return 'https://apps.powerapps.cn';
|
||||
default:
|
||||
return 'https://apps.powerapps.com';
|
||||
}
|
||||
}
|
||||
// Prints the apps.powerapps.com play URL to the console
|
||||
function printLocalPlayUrl(server) {
|
||||
var _a;
|
||||
(_a = server.httpServer) === null || _a === void 0 ? void 0 : _a.on('listening', function () {
|
||||
var _a;
|
||||
var powerConfig;
|
||||
try {
|
||||
powerConfig = getPowerConfig(server);
|
||||
}
|
||||
catch (error) {
|
||||
server.config.logger.error(picocolors_1.default.red("[powerApps] Error loading power.config.json:\n \u2937".concat((_a = error.message) !== null && _a !== void 0 ? _a : error)));
|
||||
return;
|
||||
}
|
||||
var environmentId = powerConfig.environmentId;
|
||||
if (!environmentId) {
|
||||
server.config.logger.error('[powerApps] environmentId is not defined in power.config.json');
|
||||
return;
|
||||
}
|
||||
var baseUrl = getLocalBaseUrl(server);
|
||||
if (!baseUrl) {
|
||||
server.config.logger.error('[powerApps] Unable to determine vite dev server URL');
|
||||
return;
|
||||
}
|
||||
var localAppUrl = "".concat(baseUrl);
|
||||
var localConnectionUrl = "".concat(baseUrl).concat(utils_js_1.powerConfigPath);
|
||||
var playUrl = "".concat(picocolors_1.default.magenta("".concat(getWebPlayerBaseUrl(powerConfig.region || 'prod'), "/play/e/")) +
|
||||
picocolors_1.default.magentaBright(environmentId) +
|
||||
picocolors_1.default.magenta('/a/local')) +
|
||||
"".concat(picocolors_1.default.magenta('?_localAppUrl=') + picocolors_1.default.magentaBright(localAppUrl)) +
|
||||
"".concat(picocolors_1.default.magenta('&_localConnectionUrl=') + picocolors_1.default.magentaBright(localConnectionUrl)) +
|
||||
"".concat(picocolors_1.default.reset(''));
|
||||
// Nicely formatted console output
|
||||
server.config.logger.info(" ".concat(picocolors_1.default.magentaBright('Power Apps Vite Plugin'), "\n"));
|
||||
server.config.logger.info(" ".concat(picocolors_1.default.magenta('➜'), " Local Play: ").concat(playUrl));
|
||||
});
|
||||
}
|
||||
// Serves the power.config.json content at a specific path to be accessed by apps.powerapps.com
|
||||
function servePowerConfig(server) {
|
||||
server.middlewares.use("/".concat(utils_js_1.powerConfigPath), function (req, res) {
|
||||
var _a;
|
||||
// Manual CORS headers are needed for Vite 6 and below
|
||||
var origin = req.headers.origin;
|
||||
if (origin && (0, utils_js_1.isOriginAllowed)(origin)) {
|
||||
res.setHeader('Access-Control-Allow-Origin', origin);
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
||||
res.setHeader('Access-Control-Allow-Headers', '*');
|
||||
}
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.statusCode = 204;
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.setHeader('Cache-Control', 'no-store');
|
||||
var powerConfig;
|
||||
try {
|
||||
powerConfig = getPowerConfig(server);
|
||||
}
|
||||
catch (error) {
|
||||
server.config.logger.error(picocolors_1.default.red("[powerApps] Error serving power.config.json:\n \u2937".concat((_a = error.message) !== null && _a !== void 0 ? _a : error)));
|
||||
// Player can sometimes work without power.config.json
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
res.end(JSON.stringify(powerConfig));
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=powerApps.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
/**
|
||||
* Power Apps config file structure from pac cli
|
||||
*/
|
||||
export interface PowerConfig {
|
||||
appId?: string;
|
||||
appDisplayName?: string;
|
||||
description?: string | null;
|
||||
environmentId: string;
|
||||
buildPath?: string;
|
||||
buildEntryPoint?: string;
|
||||
logoPath?: string;
|
||||
localAppUrl?: string;
|
||||
connectionReferences?: unknown;
|
||||
databaseReferences?: unknown;
|
||||
region?: string;
|
||||
}
|
||||
/**
|
||||
* CORS origin patterns for Power Apps domains
|
||||
*/
|
||||
export declare const powerAppsCorsOrigins: RegExp[];
|
||||
/**
|
||||
* Path used to serve power.config.json content
|
||||
*/
|
||||
export declare const powerConfigPath = "__vite_powerapps_plugin__/power.config.json";
|
||||
/**
|
||||
* Type guard to validate PowerConfig structure
|
||||
*/
|
||||
export declare function isPowerConfig(obj: unknown): obj is PowerConfig;
|
||||
/**
|
||||
* Check if an origin is allowed by the CORS patterns
|
||||
*/
|
||||
export declare function isOriginAllowed(origin: string): boolean;
|
||||
/**
|
||||
* Generate the Power Apps local play URL
|
||||
*/
|
||||
export declare function generatePlayUrl(environmentId: string, localAppUrl: string, localConnectionUrl: string): string;
|
||||
/**
|
||||
* Parse power.config.json content and validate it
|
||||
* @throws Error if the content is invalid
|
||||
*/
|
||||
export declare function parsePowerConfig(content: string): PowerConfig;
|
||||
/**
|
||||
* Generate the local connection URL from a base URL
|
||||
*/
|
||||
export declare function getLocalConnectionUrl(baseUrl: string): string;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/plugin/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAoBxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,gDAAgD,CAAC;AAE7E;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW,CAO9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAgB7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI7D"}
|
||||
Generated
Vendored
+91
@@ -0,0 +1,91 @@
|
||||
"use strict";
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getLocalConnectionUrl = exports.parsePowerConfig = exports.generatePlayUrl = exports.isOriginAllowed = exports.isPowerConfig = exports.powerConfigPath = exports.powerAppsCorsOrigins = void 0;
|
||||
/**
|
||||
* CORS origin patterns for Power Apps domains
|
||||
*/
|
||||
exports.powerAppsCorsOrigins = [
|
||||
// vite default localhost origins
|
||||
// eslint-disable-next-line security/detect-unsafe-regex -- input bounded by origin header length
|
||||
/^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/,
|
||||
// apps.powerapps.com
|
||||
/^https:\/\/apps\.powerapps\.com$/,
|
||||
// apps.*.powerapps.com
|
||||
// eslint-disable-next-line security/detect-unsafe-regex -- input bounded by origin header length
|
||||
/^https:\/\/apps\.(?:[^.]+\.)*powerapps\.com$/,
|
||||
// apps.*.powerapps.us
|
||||
// eslint-disable-next-line security/detect-unsafe-regex -- input bounded by origin header length
|
||||
/^https:\/\/apps\.(?:[^.]+\.)*powerapps\.us$/,
|
||||
// play.apps.appsplatform.us
|
||||
/^https:\/\/play\.apps\.appsplatform\.us$/,
|
||||
// apps.powerapps.cn
|
||||
/^https:\/\/apps\.powerapps\.cn$/,
|
||||
// apps.powerapps.eaglex.ic.gov
|
||||
/^https:\/\/apps\.powerapps\.eaglex\.ic\.gov$/,
|
||||
// apps.powerapps.microsoft.scloud
|
||||
/^https:\/\/apps\.powerapps\.microsoft\.scloud$/,
|
||||
];
|
||||
/**
|
||||
* Path used to serve power.config.json content
|
||||
*/
|
||||
exports.powerConfigPath = '__vite_powerapps_plugin__/power.config.json';
|
||||
/**
|
||||
* Type guard to validate PowerConfig structure
|
||||
*/
|
||||
function isPowerConfig(obj) {
|
||||
return (typeof obj === 'object' &&
|
||||
obj !== null &&
|
||||
'environmentId' in obj &&
|
||||
typeof obj.environmentId === 'string');
|
||||
}
|
||||
exports.isPowerConfig = isPowerConfig;
|
||||
/**
|
||||
* Check if an origin is allowed by the CORS patterns
|
||||
*/
|
||||
function isOriginAllowed(origin) {
|
||||
return exports.powerAppsCorsOrigins.some(function (pattern) { return pattern.test(origin); });
|
||||
}
|
||||
exports.isOriginAllowed = isOriginAllowed;
|
||||
/**
|
||||
* Generate the Power Apps local play URL
|
||||
*/
|
||||
function generatePlayUrl(environmentId, localAppUrl, localConnectionUrl) {
|
||||
return ("https://apps.powerapps.com/play/e/".concat(environmentId, "/a/local") +
|
||||
"?_localAppUrl=".concat(encodeURIComponent(localAppUrl)) +
|
||||
"&_localConnectionUrl=".concat(encodeURIComponent(localConnectionUrl)));
|
||||
}
|
||||
exports.generatePlayUrl = generatePlayUrl;
|
||||
/**
|
||||
* Parse power.config.json content and validate it
|
||||
* @throws Error if the content is invalid
|
||||
*/
|
||||
function parsePowerConfig(content) {
|
||||
var parsed;
|
||||
try {
|
||||
parsed = JSON.parse(content);
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof SyntaxError) {
|
||||
throw new Error("Invalid JSON in power.config.json: ".concat(error.message));
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!isPowerConfig(parsed)) {
|
||||
throw new Error('Invalid power.config.json structure. Missing environmentId.');
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
exports.parsePowerConfig = parsePowerConfig;
|
||||
/**
|
||||
* Generate the local connection URL from a base URL
|
||||
*/
|
||||
function getLocalConnectionUrl(baseUrl) {
|
||||
// Ensure base URL ends with /
|
||||
var normalizedBase = baseUrl.endsWith('/') ? baseUrl : "".concat(baseUrl, "/");
|
||||
return "".concat(normalizedBase).concat(exports.powerConfigPath);
|
||||
}
|
||||
exports.getLocalConnectionUrl = getLocalConnectionUrl;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/plugin/utils.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAmBH;;GAEG;AACU,QAAA,oBAAoB,GAAa;IAC5C,iCAAiC;IACjC,iGAAiG;IACjG,sEAAsE;IACtE,qBAAqB;IACrB,kCAAkC;IAClC,uBAAuB;IACvB,iGAAiG;IACjG,8CAA8C;IAC9C,sBAAsB;IACtB,iGAAiG;IACjG,6CAA6C;IAC7C,4BAA4B;IAC5B,0CAA0C;IAC1C,oBAAoB;IACpB,iCAAiC;IACjC,+BAA+B;IAC/B,8CAA8C;IAC9C,kCAAkC;IAClC,gDAAgD;CACjD,CAAC;AAEF;;GAEG;AACU,QAAA,eAAe,GAAG,6CAA6C,CAAC;AAE7E;;GAEG;AACH,SAAgB,aAAa,CAAC,GAAY;IACxC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,eAAe,IAAI,GAAG;QACtB,OAAQ,GAAmB,CAAC,aAAa,KAAK,QAAQ,CACvD,CAAC;AACJ,CAAC;AAPD,sCAOC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAAc;IAC5C,OAAO,4BAAoB,CAAC,IAAI,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAApB,CAAoB,CAAC,CAAC;AACtE,CAAC;AAFD,0CAEC;AAED;;GAEG;AACH,SAAgB,eAAe,CAC7B,aAAqB,EACrB,WAAmB,EACnB,kBAA0B;IAE1B,OAAO,CACL,4CAAqC,aAAa,aAAU;QAC5D,wBAAiB,kBAAkB,CAAC,WAAW,CAAC,CAAE;QAClD,+BAAwB,kBAAkB,CAAC,kBAAkB,CAAC,CAAE,CACjE,CAAC;AACJ,CAAC;AAVD,0CAUC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,IAAI,MAAe,CAAC;IACpB,IAAI;QACF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAC9B;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,WAAW,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,6CAAsC,KAAK,CAAC,OAAO,CAAE,CAAC,CAAC;SACxE;QACD,MAAM,KAAK,CAAC;KACb;IAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;KAChF;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAhBD,4CAgBC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,OAAe;IACnD,8BAA8B;IAC9B,IAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAG,OAAO,MAAG,CAAC;IACvE,OAAO,UAAG,cAAc,SAAG,uBAAe,CAAE,CAAC;AAC/C,CAAC;AAJD,sDAIC"}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
export { powerApps } from './plugin/index.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
export { powerApps } from './plugin/index.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
export { powerApps } from './powerApps.js';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
export { powerApps } from './powerApps.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
import type { Plugin } from 'vite';
|
||||
export declare function powerApps(): Plugin;
|
||||
//# sourceMappingURL=powerApps.d.ts.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"powerApps.d.ts","sourceRoot":"","sources":["../../src/plugin/powerApps.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAOlD,wBAAgB,SAAS,IAAI,MAAM,CAqBlC"}
|
||||
Generated
Vendored
+183
@@ -0,0 +1,183 @@
|
||||
import pc from 'picocolors';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { isOriginAllowed, isPowerConfig, powerAppsCorsOrigins, powerConfigPath } from './utils.js';
|
||||
export function powerApps() {
|
||||
return {
|
||||
name: 'powerApps',
|
||||
config() {
|
||||
return {
|
||||
// Needed for publishing static assets correctly
|
||||
base: './',
|
||||
// Automatically inject CORS configuration needed for Vite 7+
|
||||
server: {
|
||||
cors: {
|
||||
origin: powerAppsCorsOrigins,
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
configureServer(server) {
|
||||
printLocalPlayUrl(server);
|
||||
servePowerConfig(server);
|
||||
watchPowerConfig(server);
|
||||
},
|
||||
};
|
||||
}
|
||||
function getLocalBaseUrl(server) {
|
||||
var _a, _b;
|
||||
// Vite 6+
|
||||
if ((_b = (_a = server.resolvedUrls) === null || _a === void 0 ? void 0 : _a.local) === null || _b === void 0 ? void 0 : _b[0]) {
|
||||
return server.resolvedUrls.local[0];
|
||||
}
|
||||
// In Vite 5 and below, resolvedUrls may not be available, fallback to httpServer address
|
||||
const address = server.httpServer.address();
|
||||
if (typeof address === 'string') {
|
||||
return address;
|
||||
}
|
||||
if (typeof address === 'object' && address !== null) {
|
||||
const { address: rawHost, port } = address;
|
||||
const host = rawHost === '::1' ? 'localhost' : rawHost;
|
||||
const https = server.config.server.https;
|
||||
return `${https ? 'https' : 'http'}://${host}:${port}/`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Cache for power config to avoid repeated file reads
|
||||
let cachedPowerConfig = null;
|
||||
function getPowerConfig(server) {
|
||||
if (cachedPowerConfig) {
|
||||
return cachedPowerConfig;
|
||||
}
|
||||
const configPath = join(server.config.root, 'power.config.json');
|
||||
try {
|
||||
const configContent = readFileSync(configPath, 'utf-8');
|
||||
const parsed = JSON.parse(configContent);
|
||||
if (!isPowerConfig(parsed)) {
|
||||
throw new Error('Invalid power.config.json structure. Missing environmentId.');
|
||||
}
|
||||
cachedPowerConfig = parsed;
|
||||
return parsed;
|
||||
}
|
||||
catch (error) {
|
||||
// Handle specific error types
|
||||
if (error.code === 'ENOENT') {
|
||||
throw new Error(`Missing file. Ensure you have run 'pac code init' first. power.config.json expected at ${configPath}.`);
|
||||
}
|
||||
if (error instanceof SyntaxError) {
|
||||
throw new Error(`Invalid JSON in power.config.json: ${error.message}`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
function watchPowerConfig(server) {
|
||||
const configPath = join(server.config.root, 'power.config.json');
|
||||
server.watcher.add(configPath);
|
||||
server.watcher.on('change', (file) => {
|
||||
if (file === configPath) {
|
||||
server.config.logger.info(pc.yellow('[powerApps] power.config.json changed, restarting server...'));
|
||||
// Clear cache so new config is loaded
|
||||
cachedPowerConfig = null;
|
||||
server.restart();
|
||||
}
|
||||
});
|
||||
}
|
||||
function getWebPlayerBaseUrl(region) {
|
||||
if (!region) {
|
||||
return 'https://apps.powerapps.com';
|
||||
}
|
||||
region = region.toLowerCase();
|
||||
switch (region) {
|
||||
case 'public':
|
||||
case 'prod':
|
||||
return 'https://apps.powerapps.com';
|
||||
case 'preprod':
|
||||
return 'https://apps.preprod.powerapps.com';
|
||||
case 'test':
|
||||
return 'https://apps.test.powerapps.com';
|
||||
case 'preview':
|
||||
return 'https://apps.preview.powerapps.com';
|
||||
case 'usgov':
|
||||
case 'gccmoderate':
|
||||
return 'https://apps.gov.powerapps.us';
|
||||
case 'usgovhigh':
|
||||
case 'gcchigh':
|
||||
return 'https://apps.high.powerapps.us';
|
||||
case 'usgovdod':
|
||||
case 'dod':
|
||||
return 'https://play.apps.appsplatform.us';
|
||||
case 'china':
|
||||
case 'mooncake':
|
||||
return 'https://apps.powerapps.cn';
|
||||
default:
|
||||
return 'https://apps.powerapps.com';
|
||||
}
|
||||
}
|
||||
// Prints the apps.powerapps.com play URL to the console
|
||||
function printLocalPlayUrl(server) {
|
||||
var _a;
|
||||
(_a = server.httpServer) === null || _a === void 0 ? void 0 : _a.on('listening', () => {
|
||||
var _a;
|
||||
let powerConfig;
|
||||
try {
|
||||
powerConfig = getPowerConfig(server);
|
||||
}
|
||||
catch (error) {
|
||||
server.config.logger.error(pc.red(`[powerApps] Error loading power.config.json:\n ⤷${(_a = error.message) !== null && _a !== void 0 ? _a : error}`));
|
||||
return;
|
||||
}
|
||||
const environmentId = powerConfig.environmentId;
|
||||
if (!environmentId) {
|
||||
server.config.logger.error('[powerApps] environmentId is not defined in power.config.json');
|
||||
return;
|
||||
}
|
||||
const baseUrl = getLocalBaseUrl(server);
|
||||
if (!baseUrl) {
|
||||
server.config.logger.error('[powerApps] Unable to determine vite dev server URL');
|
||||
return;
|
||||
}
|
||||
const localAppUrl = `${baseUrl}`;
|
||||
const localConnectionUrl = `${baseUrl}${powerConfigPath}`;
|
||||
const playUrl = `${pc.magenta(`${getWebPlayerBaseUrl(powerConfig.region || 'prod')}/play/e/`) +
|
||||
pc.magentaBright(environmentId) +
|
||||
pc.magenta('/a/local')}` +
|
||||
`${pc.magenta('?_localAppUrl=') + pc.magentaBright(localAppUrl)}` +
|
||||
`${pc.magenta('&_localConnectionUrl=') + pc.magentaBright(localConnectionUrl)}` +
|
||||
`${pc.reset('')}`;
|
||||
// Nicely formatted console output
|
||||
server.config.logger.info(` ${pc.magentaBright('Power Apps Vite Plugin')}\n`);
|
||||
server.config.logger.info(` ${pc.magenta('➜')} Local Play: ${playUrl}`);
|
||||
});
|
||||
}
|
||||
// Serves the power.config.json content at a specific path to be accessed by apps.powerapps.com
|
||||
function servePowerConfig(server) {
|
||||
server.middlewares.use(`/${powerConfigPath}`, (req, res) => {
|
||||
var _a;
|
||||
// Manual CORS headers are needed for Vite 6 and below
|
||||
const origin = req.headers.origin;
|
||||
if (origin && isOriginAllowed(origin)) {
|
||||
res.setHeader('Access-Control-Allow-Origin', origin);
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
||||
res.setHeader('Access-Control-Allow-Headers', '*');
|
||||
}
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.statusCode = 204;
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.setHeader('Cache-Control', 'no-store');
|
||||
let powerConfig;
|
||||
try {
|
||||
powerConfig = getPowerConfig(server);
|
||||
}
|
||||
catch (error) {
|
||||
server.config.logger.error(pc.red(`[powerApps] Error serving power.config.json:\n ⤷${(_a = error.message) !== null && _a !== void 0 ? _a : error}`));
|
||||
// Player can sometimes work without power.config.json
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
res.end(JSON.stringify(powerConfig));
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=powerApps.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
/**
|
||||
* Power Apps config file structure from pac cli
|
||||
*/
|
||||
export interface PowerConfig {
|
||||
appId?: string;
|
||||
appDisplayName?: string;
|
||||
description?: string | null;
|
||||
environmentId: string;
|
||||
buildPath?: string;
|
||||
buildEntryPoint?: string;
|
||||
logoPath?: string;
|
||||
localAppUrl?: string;
|
||||
connectionReferences?: unknown;
|
||||
databaseReferences?: unknown;
|
||||
region?: string;
|
||||
}
|
||||
/**
|
||||
* CORS origin patterns for Power Apps domains
|
||||
*/
|
||||
export declare const powerAppsCorsOrigins: RegExp[];
|
||||
/**
|
||||
* Path used to serve power.config.json content
|
||||
*/
|
||||
export declare const powerConfigPath = "__vite_powerapps_plugin__/power.config.json";
|
||||
/**
|
||||
* Type guard to validate PowerConfig structure
|
||||
*/
|
||||
export declare function isPowerConfig(obj: unknown): obj is PowerConfig;
|
||||
/**
|
||||
* Check if an origin is allowed by the CORS patterns
|
||||
*/
|
||||
export declare function isOriginAllowed(origin: string): boolean;
|
||||
/**
|
||||
* Generate the Power Apps local play URL
|
||||
*/
|
||||
export declare function generatePlayUrl(environmentId: string, localAppUrl: string, localConnectionUrl: string): string;
|
||||
/**
|
||||
* Parse power.config.json content and validate it
|
||||
* @throws Error if the content is invalid
|
||||
*/
|
||||
export declare function parsePowerConfig(content: string): PowerConfig;
|
||||
/**
|
||||
* Generate the local connection URL from a base URL
|
||||
*/
|
||||
export declare function getLocalConnectionUrl(baseUrl: string): string;
|
||||
//# sourceMappingURL=utils.d.ts.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/plugin/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAoBxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,gDAAgD,CAAC;AAE7E;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW,CAO9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,kBAAkB,EAAE,MAAM,GACzB,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAgB7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI7D"}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*!
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
/**
|
||||
* CORS origin patterns for Power Apps domains
|
||||
*/
|
||||
export const powerAppsCorsOrigins = [
|
||||
// vite default localhost origins
|
||||
// eslint-disable-next-line security/detect-unsafe-regex -- input bounded by origin header length
|
||||
/^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/,
|
||||
// apps.powerapps.com
|
||||
/^https:\/\/apps\.powerapps\.com$/,
|
||||
// apps.*.powerapps.com
|
||||
// eslint-disable-next-line security/detect-unsafe-regex -- input bounded by origin header length
|
||||
/^https:\/\/apps\.(?:[^.]+\.)*powerapps\.com$/,
|
||||
// apps.*.powerapps.us
|
||||
// eslint-disable-next-line security/detect-unsafe-regex -- input bounded by origin header length
|
||||
/^https:\/\/apps\.(?:[^.]+\.)*powerapps\.us$/,
|
||||
// play.apps.appsplatform.us
|
||||
/^https:\/\/play\.apps\.appsplatform\.us$/,
|
||||
// apps.powerapps.cn
|
||||
/^https:\/\/apps\.powerapps\.cn$/,
|
||||
// apps.powerapps.eaglex.ic.gov
|
||||
/^https:\/\/apps\.powerapps\.eaglex\.ic\.gov$/,
|
||||
// apps.powerapps.microsoft.scloud
|
||||
/^https:\/\/apps\.powerapps\.microsoft\.scloud$/,
|
||||
];
|
||||
/**
|
||||
* Path used to serve power.config.json content
|
||||
*/
|
||||
export const powerConfigPath = '__vite_powerapps_plugin__/power.config.json';
|
||||
/**
|
||||
* Type guard to validate PowerConfig structure
|
||||
*/
|
||||
export function isPowerConfig(obj) {
|
||||
return (typeof obj === 'object' &&
|
||||
obj !== null &&
|
||||
'environmentId' in obj &&
|
||||
typeof obj.environmentId === 'string');
|
||||
}
|
||||
/**
|
||||
* Check if an origin is allowed by the CORS patterns
|
||||
*/
|
||||
export function isOriginAllowed(origin) {
|
||||
return powerAppsCorsOrigins.some((pattern) => pattern.test(origin));
|
||||
}
|
||||
/**
|
||||
* Generate the Power Apps local play URL
|
||||
*/
|
||||
export function generatePlayUrl(environmentId, localAppUrl, localConnectionUrl) {
|
||||
return (`https://apps.powerapps.com/play/e/${environmentId}/a/local` +
|
||||
`?_localAppUrl=${encodeURIComponent(localAppUrl)}` +
|
||||
`&_localConnectionUrl=${encodeURIComponent(localConnectionUrl)}`);
|
||||
}
|
||||
/**
|
||||
* Parse power.config.json content and validate it
|
||||
* @throws Error if the content is invalid
|
||||
*/
|
||||
export function parsePowerConfig(content) {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(content);
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof SyntaxError) {
|
||||
throw new Error(`Invalid JSON in power.config.json: ${error.message}`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!isPowerConfig(parsed)) {
|
||||
throw new Error('Invalid power.config.json structure. Missing environmentId.');
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
/**
|
||||
* Generate the local connection URL from a base URL
|
||||
*/
|
||||
export function getLocalConnectionUrl(baseUrl) {
|
||||
// Ensure base URL ends with /
|
||||
const normalizedBase = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
|
||||
return `${normalizedBase}${powerConfigPath}`;
|
||||
}
|
||||
//# sourceMappingURL=utils.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/plugin/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAa;IAC5C,iCAAiC;IACjC,iGAAiG;IACjG,sEAAsE;IACtE,qBAAqB;IACrB,kCAAkC;IAClC,uBAAuB;IACvB,iGAAiG;IACjG,8CAA8C;IAC9C,sBAAsB;IACtB,iGAAiG;IACjG,6CAA6C;IAC7C,4BAA4B;IAC5B,0CAA0C;IAC1C,oBAAoB;IACpB,iCAAiC;IACjC,+BAA+B;IAC/B,8CAA8C;IAC9C,kCAAkC;IAClC,gDAAgD;CACjD,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,6CAA6C,CAAC;AAE7E;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,eAAe,IAAI,GAAG;QACtB,OAAQ,GAAmB,CAAC,aAAa,KAAK,QAAQ,CACvD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,aAAqB,EACrB,WAAmB,EACnB,kBAA0B;IAE1B,OAAO,CACL,qCAAqC,aAAa,UAAU;QAC5D,iBAAiB,kBAAkB,CAAC,WAAW,CAAC,EAAE;QAClD,wBAAwB,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,CACjE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,MAAe,CAAC;IACpB,IAAI;QACF,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;KAC9B;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,WAAW,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;SACxE;QACD,MAAM,KAAK,CAAC;KACb;IAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;KAChF;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,8BAA8B;IAC9B,MAAM,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC;IACvE,OAAO,GAAG,cAAc,GAAG,eAAe,EAAE,CAAC;AAC/C,CAAC"}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "@microsoft/power-apps-vite",
|
||||
"version": "1.0.2",
|
||||
"description": "Vite plugin for Power Apps",
|
||||
"license": "See license in LICENSE file",
|
||||
"type": "module",
|
||||
"main": "./lib-cjs/index.js",
|
||||
"module": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./lib/index.d.ts",
|
||||
"default": "./lib/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./lib-cjs/index.d.ts",
|
||||
"default": "./lib-cjs/index.js"
|
||||
}
|
||||
},
|
||||
"./plugin": {
|
||||
"import": {
|
||||
"types": "./lib/plugin/index.d.ts",
|
||||
"default": "./lib/plugin/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./lib-cjs/plugin/index.d.ts",
|
||||
"default": "./lib-cjs/plugin/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"lib/**",
|
||||
"lib-cjs/**",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "pa-client-build",
|
||||
"postbuild": "tsc -p tsconfig.cjs.json",
|
||||
"lint": "pa-client-lint",
|
||||
"test": "pa-client-test"
|
||||
},
|
||||
"layer": "pure-package",
|
||||
"peerDependencies": {
|
||||
"vite": ">=5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vite": {
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pa-client/build-scripts": "1.0.0",
|
||||
"@types/node": "^22.9.0",
|
||||
"@types/jest": "29.5.6",
|
||||
"typescript": "5.2.2",
|
||||
"vite": ">=5.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"vite",
|
||||
"vite-plugin",
|
||||
"powerapps",
|
||||
"power-apps"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user