Skip to content

Commit 8e54255

Browse files
committed
deploy: 606b7d0
1 parent eb84657 commit 8e54255

File tree

80 files changed

+1677
-235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1677
-235
lines changed

appConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ window.AppConfig = {
2424
"app_notification_url": "assets/notifications/dev/",
2525
"app_update_url": "https://updates.phcode.io/tauri/update-latest-experimental-build.json",
2626
"linting.enabled_by_default": true,
27-
"build_timestamp": "2024-05-03T08:38:36.496Z",
27+
"build_timestamp": "2024-05-04T11:44:52.252Z",
2828
"googleAnalyticsID": "G-P4HJFPDB76",
2929
"googleAnalyticsIDDesktop": "G-VE5BXWJ0HF",
3030
"mixPanelID": "49c4d164b592be2350fc7af06a259bf3",
@@ -36,7 +36,7 @@ window.AppConfig = {
3636
"bugsnagEnv": "development"
3737
},
3838
"name": "Phoenix Code",
39-
"version": "3.7.2-20245",
39+
"version": "3.7.2-20253",
4040
"apiVersion": "3.7.2",
4141
"homepage": "https://core.ai",
4242
"issues": {

assets/default-project/en.zip

0 Bytes
Binary file not shown.

assets/sample-projects/HTML5.zip

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

assets/sample-projects/explore.zip

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

brackets-min.js

Lines changed: 175 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27148,11 +27148,13 @@ define("editor/MultiRangeInlineEditor", function (require, exports, module) {
2714827148
*
2714927149
*/
2715027150

27151-
/*global path*/
27151+
/*global path, jsPromise, catchToNull*/
2715227152

2715327153
define("extensibility/ExtensionDownloader", function (require, exports, module) {
2715427154
const EventDispatcher = require("utils/EventDispatcher"),
2715527155
ExtensionLoader = require("utils/ExtensionLoader"),
27156+
FileUtils = require("file/FileUtils"),
27157+
NodeUtils = require("utils/NodeUtils"),
2715627158
Package = require("extensibility/Package"),
2715727159
FileSystem = require("filesystem/FileSystem"),
2715827160
ZipUtils = require("utils/ZipUtils");
@@ -27234,14 +27236,97 @@ define("extensibility/ExtensionDownloader", function (require, exports, module)
2723427236
downloadCancelled[downloadId] = true;
2723527237
}
2723627238

27239+
async function _validateAndNpmInstallIfNodeExtension(nodeExtPath) {
27240+
const packageJSONFile = FileSystem.getFileForPath(path.join(nodeExtPath, "package.json"));
27241+
let packageJson = await catchToNull(jsPromise(FileUtils.readAsText(packageJSONFile)),
27242+
"package.json not found for installing extension, trying to continue "+ nodeExtPath);
27243+
try{
27244+
if(packageJson){
27245+
packageJson = JSON.parse(packageJson);
27246+
}
27247+
} catch (e) {
27248+
console.error("Error parsing package json for extension", nodeExtPath, e);
27249+
return null; // let it flow, we are only concerned of node extensions
27250+
}
27251+
if(!packageJson || !packageJson.nodeConfig || !packageJson.nodeConfig.main){
27252+
// legacy extensions can be loaded with no package.json
27253+
// else if no node config, or node main is not defined, we just treat it as a non node extension
27254+
return null;
27255+
}
27256+
if(packageJson.nodeConfig.nodeIsRequired && !Phoenix.isNativeApp) {
27257+
return "Extension can only be installed in native builds!";
27258+
}
27259+
let nodeMainFile = path.join(nodeExtPath, packageJson.nodeConfig.main);
27260+
let file = FileSystem.getFileForPath(nodeMainFile);
27261+
let isExists = await file.existsAsync();
27262+
if(!isExists){
27263+
console.error("Extension cannot be installed; could not find node main file: ",
27264+
nodeMainFile, packageJson.nodeConfig.main);
27265+
return "Extension is broken, (Err: node main file not found)";
27266+
}
27267+
27268+
let npmInstallFolder = packageJson.nodeConfig.npmInstall;
27269+
if(!npmInstallFolder) {
27270+
return null;
27271+
}
27272+
npmInstallFolder = path.join(nodeExtPath, packageJson.nodeConfig.npmInstall);
27273+
const nodeModulesFolder = path.join(npmInstallFolder, "node_modules");
27274+
let directory = FileSystem.getDirectoryForPath(npmInstallFolder);
27275+
isExists = await directory.existsAsync();
27276+
if(!isExists){
27277+
console.error("Extension cannot be installed; could not find folder to run npm install: ",
27278+
npmInstallFolder);
27279+
return "Extension is broken, (Err: node source folder not found)";
27280+
}
27281+
27282+
const nodePackageJson = path.join(npmInstallFolder, "package.json");
27283+
let nodePackageFile = FileSystem.getFileForPath(nodePackageJson);
27284+
isExists = await nodePackageFile.existsAsync();
27285+
if(!isExists){
27286+
console.error("Extension cannot be installed; could not find package.json file to npm install in: ",
27287+
npmInstallFolder);
27288+
return "Extension is broken, (Err: it's node package.json not found)";
27289+
}
27290+
27291+
directory = FileSystem.getDirectoryForPath(nodeModulesFolder);
27292+
isExists = await directory.existsAsync();
27293+
if(isExists) {
27294+
console.error("Could not install extension as the extension has node_modules folder in" +
27295+
" the package", nodeModulesFolder, "Extensions that defines a nodeConfig.npmInstall" +
27296+
" path should not package node_modules!");
27297+
return "Extension is broken. (Err: cannot npm install inside extension folder" +
27298+
" as it already has node_modules)";
27299+
}
27300+
const npmInstallPlatformPath = Phoenix.fs.getTauriPlatformPath(npmInstallFolder);
27301+
return NodeUtils._npmInstallInFolder(npmInstallPlatformPath);
27302+
}
27303+
2723727304
function install(path, destinationDirectory, config) {
2723827305
const d = new $.Deferred();
27239-
// if we reached here in phoenix, install succeded
27240-
d.resolve({
27241-
name: _getExtensionName(config.nameHint),
27242-
installationStatus: Package.InstallationStatuses.INSTALLED,
27243-
installedTo: path
27244-
});
27306+
// if we reached here in phoenix, install succeeded
27307+
_validateAndNpmInstallIfNodeExtension(path)
27308+
.then(validationErr =>{
27309+
if(validationErr) {
27310+
d.resolve({
27311+
name: _getExtensionName(config.nameHint),
27312+
installationStatus: Package.InstallationStatuses.FAILED,
27313+
errors: [validationErr]
27314+
});
27315+
return;
27316+
}
27317+
d.resolve({
27318+
name: _getExtensionName(config.nameHint),
27319+
installationStatus: Package.InstallationStatuses.INSTALLED,
27320+
installedTo: path
27321+
});
27322+
}).catch(err=>{
27323+
console.error("Error installing extension", err);
27324+
d.resolve({
27325+
name: _getExtensionName(config.nameHint),
27326+
installationStatus: Package.InstallationStatuses.FAILED,
27327+
errors: ["Error installing extension"]
27328+
});
27329+
});
2724527330
return d.promise();
2724627331
}
2724727332

@@ -27543,6 +27628,30 @@ define("extensibility/ExtensionManager", function (require, exports, module) {
2754327628
});
2754427629
}
2754527630

27631+
/**
27632+
* Filters out extensions that needs node in the browser from being listed.
27633+
*
27634+
* @param {Object} registry - The registry object to filter
27635+
* @return {Object} - The filtered registry object
27636+
* @private
27637+
*/
27638+
function _filterIncompatibleEntries(registry) {
27639+
let filteredRegistry = {};
27640+
for(let registryKey of Object.keys(registry)){
27641+
const registryEntry = registry[registryKey];
27642+
let nodeNeeded = false;
27643+
if(registryEntry.metadata && registryEntry.metadata.nodeConfig &&
27644+
registryEntry.metadata.nodeConfig.nodeIsRequired) {
27645+
nodeNeeded = true;
27646+
}
27647+
if(nodeNeeded && !Phoenix.isNativeApp) {
27648+
continue;
27649+
}
27650+
filteredRegistry[registryKey] = registryEntry;
27651+
}
27652+
return filteredRegistry;
27653+
}
27654+
2754627655
/**
2754727656
* Downloads the registry of Brackets extensions and stores the information in our
2754827657
* extension info.
@@ -27565,6 +27674,7 @@ define("extensibility/ExtensionManager", function (require, exports, module) {
2756527674
cache: false
2756627675
})
2756727676
.done(function (registry) {
27677+
registry = _filterIncompatibleEntries(registry);
2756827678
localStorage.setItem(EXTENSION_REGISTRY_LOCAL_STORAGE_VERSION_KEY, newVersion);
2756927679
localStorage.setItem(EXTENSION_REGISTRY_LOCAL_STORAGE_KEY, JSON.stringify(registry));
2757027680
if(!pendingDownloadRegistry.alreadyResolvedFromCache){
@@ -27595,7 +27705,9 @@ define("extensibility/ExtensionManager", function (require, exports, module) {
2759527705
// resolve for ui responsiveness and then check for updates.
2759627706
setTimeout(()=>{
2759727707
Metrics.countEvent(Metrics.EVENT_TYPE.EXTENSIONS, "registry", "cachedUse");
27598-
_populateExtensions(JSON.parse(registryJson));
27708+
let registry = JSON.parse(registryJson);
27709+
registry = _filterIncompatibleEntries(registry);
27710+
_populateExtensions(registry);
2759927711
pendingDownloadRegistry.resolve();
2760027712
}, 0);
2760127713
pendingDownloadRegistry.alreadyResolvedFromCache = true;
@@ -137882,7 +137994,7 @@ define("utils/ExtensionInterface", function (require, exports, module) {
137882137994
* extension root.
137883137995
*/
137884137996
// jshint ignore: start
137885-
/*global logger, Phoenix*/
137997+
/*global logger, path*/
137886137998
/*eslint-env es6*/
137887137999
/*eslint no-console: 0*/
137888138000
/*eslint strict: ["error", "global"]*/
@@ -137900,6 +138012,7 @@ define("utils/ExtensionLoader", function (require, exports, module) {
137900138012
ExtensionUtils = require("utils/ExtensionUtils"),
137901138013
ThemeManager = require("view/ThemeManager"),
137902138014
UrlParams = require("utils/UrlParams").UrlParams,
138015+
NodeUtils = require("utils/NodeUtils"),
137903138016
PathUtils = require("thirdparty/path-utils/path-utils"),
137904138017
DefaultExtensionsList = JSON.parse(require("text!extensions/default/DefaultExtensions.json"))
137905138018
.defaultExtensionsList;
@@ -138059,17 +138172,24 @@ define("utils/ExtensionLoader", function (require, exports, module) {
138059138172
}
138060138173
const savedFSlib = window.fs;
138061138174

138175+
function _loadNodeExtension(name, extensionMainPath, nodeConfig) {
138176+
const mainPlatformPath = Phoenix.fs.getTauriPlatformPath(extensionMainPath);
138177+
console.log("Loading node extension for " + name, extensionMainPath, ":", mainPlatformPath, nodeConfig);
138178+
NodeUtils._loadNodeExtensionModule(mainPlatformPath); // let load errors get reported to bugsnag
138179+
}
138180+
138062138181
/**
138063138182
* Loads the extension module that lives at baseUrl into its own Require.js context
138064138183
*
138065138184
* @param {!string} name, used to identify the extension
138066138185
* @param {!{baseUrl: string}} config object with baseUrl property containing absolute path of extension
138067-
* @param {!string} entryPoint, name of the main js file to load
138186+
* @param {string} entryPoint name of the main js file to load
138187+
* @param {Object} metadata
138068138188
* @return {!$.Promise} A promise object that is resolved when the extension is loaded, or rejected
138069138189
* if the extension fails to load or throws an exception immediately when loaded.
138070138190
* (Note: if extension contains a JS syntax error, promise is resolved not rejected).
138071138191
*/
138072-
function loadExtensionModule(name, config, entryPoint) {
138192+
function loadExtensionModule(name, config, entryPoint, metadata) {
138073138193
let extensionConfig = {
138074138194
context: name,
138075138195
baseUrl: config.baseUrl,
@@ -138094,7 +138214,24 @@ define("utils/ExtensionLoader", function (require, exports, module) {
138094138214
// Create new RequireJS context and load extension entry point
138095138215
var extensionRequire = brackets.libRequire.config(mergedConfig),
138096138216
extensionRequireDeferred = new $.Deferred();
138097-
138217+
if(!isDefaultExtensionModule && config.nativeDir && metadata.nodeConfig){
138218+
if(!Phoenix.isNativeApp && metadata.nodeConfig.nodeIsRequired) {
138219+
extensionRequireDeferred.reject(
138220+
new Error(`Extension ${name} cannot be loaded in browser as it needs node(nodeConfig.nodeIsRequired:true)`));
138221+
return extensionRequireDeferred.promise();
138222+
}
138223+
if(Phoenix.isNativeApp) {
138224+
if(!metadata.nodeConfig.main){
138225+
extensionRequireDeferred.reject(
138226+
new Error(`Extension ${name} doesnt specify a main file(nodeConfig.main) in package.json!`));
138227+
return extensionRequireDeferred.promise();
138228+
}
138229+
_loadNodeExtension(name, path.join(config.nativeDir, metadata.nodeConfig.main),
138230+
metadata.nodeConfig);
138231+
} else {
138232+
console.log(`Extension ${name} optionally needs node. Node not loaded in browser.`);
138233+
}
138234+
}
138098138235
contexts[name] = extensionRequire;
138099138236
extensionRequire([entryPoint], extensionRequireDeferred.resolve, extensionRequireDeferred.reject);
138100138237

@@ -138189,7 +138326,7 @@ define("utils/ExtensionLoader", function (require, exports, module) {
138189138326
}
138190138327

138191138328
if (!metadata.disabled) {
138192-
return loadExtensionModule(name, config, entryPoint);
138329+
return loadExtensionModule(name, config, entryPoint, metadata);
138193138330
}
138194138331
return new $.Deferred().reject("disabled").promise();
138195138332

@@ -138308,9 +138445,10 @@ define("utils/ExtensionLoader", function (require, exports, module) {
138308138445
}
138309138446

138310138447
Async.doInParallel(extensions, function (item) {
138311-
var extConfig = {
138448+
const extConfig = {
138312138449
// we load user installed extensions in file system from our virtual/asset server URL
138313138450
baseUrl: Phoenix.VFS.getVirtualServingURLForPath(directory + "/" + item),
138451+
nativeDir: directory + "/" + item,
138314138452
paths: {}
138315138453
};
138316138454
console.log("Loading Extension from virtual fs: ", extConfig);
@@ -138371,7 +138509,8 @@ define("utils/ExtensionLoader", function (require, exports, module) {
138371138509
function loadExtensionFromNativeDirectory(directory) {
138372138510
logger.leaveTrail("loading custom extension from path: " + directory);
138373138511
const extConfig = {
138374-
baseUrl: Phoenix.VFS.getVirtualServingURLForPath(directory.replace(/\/$/, ""))
138512+
baseUrl: Phoenix.VFS.getVirtualServingURLForPath(directory.replace(/\/$/, "")),
138513+
nativeDir: directory
138375138514
};
138376138515
return loadExtension("ext" + directory.replace("/", "-"), // /fs/user/extpath to ext-fs-user-extpath
138377138516
extConfig, 'main');
@@ -140758,7 +140897,7 @@ define("utils/NodeUtils", function (require, exports, module) {
140758140897
* updates the localized strings in brackets `Strings` to node.
140759140898
* @return {Promise<boolean>} Promise resolves to true if strings was updated in node, else false(in browser.)
140760140899
*/
140761-
async function updateNodeLocaleStrings() {
140900+
async function _updateNodeLocaleStrings() {
140762140901
if(!Phoenix.isNativeApp) {
140763140902
// this does nothing in browser builds.
140764140903
return false;
@@ -140790,14 +140929,32 @@ define("utils/NodeUtils", function (require, exports, module) {
140790140929
return utilsConnector.execPeer("openUrlInBrowser", {url, browserName});
140791140930
}
140792140931

140932+
async function _loadNodeExtensionModule(moduleNativeDir) {
140933+
if(!Phoenix.isNativeApp) {
140934+
throw new Error("_loadNodeExtensionModule not available in browser");
140935+
}
140936+
return utilsConnector.execPeer("_loadNodeExtensionModule", {moduleNativeDir});
140937+
}
140938+
140939+
async function _npmInstallInFolder(moduleNativeDir) {
140940+
if(!Phoenix.isNativeApp) {
140941+
throw new Error("_npmInstallInFolder not available in browser");
140942+
}
140943+
return utilsConnector.execPeer("_npmInstallInFolder", {moduleNativeDir});
140944+
}
140945+
140793140946
if(NodeConnector.isNodeAvailable()) {
140794140947
// todo we need to update the strings if a user extension adds its translations. Since we dont support
140795140948
// node extensions for now, should consider when we support node extensions.
140796-
updateNodeLocaleStrings();
140949+
_updateNodeLocaleStrings();
140797140950
}
140798140951

140952+
// private apis
140953+
exports._loadNodeExtensionModule = _loadNodeExtensionModule;
140954+
exports._npmInstallInFolder = _npmInstallInFolder;
140955+
140956+
// public apis
140799140957
exports.fetchURLText = fetchURLText;
140800-
exports.updateNodeLocaleStrings = updateNodeLocaleStrings;
140801140958
exports.getPhoenixBinaryVersion = getPhoenixBinaryVersion;
140802140959
exports.getLinuxOSFlavorName = getLinuxOSFlavorName;
140803140960
exports.openUrlInBrowser = openUrlInBrowser;

0 commit comments

Comments
 (0)