Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 85ef47b

Browse files
committed
release: 0.14.0
soft release (release post later)
1 parent c98b71f commit 85ef47b

File tree

2 files changed

+135
-135
lines changed

2 files changed

+135
-135
lines changed

package.json

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
{
2-
"name": "@gluon-framework/gluon",
3-
"version": "0.14.0-alpha.0",
4-
"description": "Make websites into desktop apps with system installed browsers and NodeJS.",
5-
"main": "src/index.js",
6-
"types": "gluon.d.ts",
7-
"scripts": {},
8-
"repository": {
9-
"type": "git",
10-
"url": "git+https://github.com/gluon-framework/gluon.git"
11-
},
12-
"author": "Gluon Framework",
13-
"license": "MIT",
14-
"bugs": {
15-
"url": "https://github.com/gluon-framework/gluon/issues"
16-
},
17-
"homepage": "https://github.com/gluon-framework/gluon#readme",
18-
"type": "module",
19-
"dependencies": {
20-
"ws": "^8.11.0"
21-
}
1+
{
2+
"name": "@gluon-framework/gluon",
3+
"version": "0.14.0",
4+
"description": "Make websites into desktop apps with system installed browsers and NodeJS.",
5+
"main": "src/index.js",
6+
"types": "gluon.d.ts",
7+
"scripts": {},
8+
"repository": {
9+
"type": "git",
10+
"url": "git+https://github.com/gluon-framework/gluon.git"
11+
},
12+
"author": "Gluon Framework",
13+
"license": "MIT",
14+
"bugs": {
15+
"url": "https://github.com/gluon-framework/gluon/issues"
16+
},
17+
"homepage": "https://github.com/gluon-framework/gluon#readme",
18+
"type": "module",
19+
"dependencies": {
20+
"ws": "^8.11.0"
21+
}
2222
}

src/index.js

+114-114
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,115 @@
1-
import { join, dirname, extname, isAbsolute } from 'path';
2-
3-
import { fileURLToPath } from 'url';
4-
import { log, dangerousAPI } from './lib/logger.js';
5-
6-
import Chromium from './browser/chromium.js';
7-
import Firefox from './browser/firefox.js';
8-
9-
import * as ExtensionsAPI from './extensions.js';
10-
import LocalHTTP from './lib/local/http.js';
11-
import { findBrowserPath, getBrowserType } from './lib/browserPaths.js';
12-
13-
process.versions.gluon = '0.14.0-alpha.0';
14-
15-
const __filename = fileURLToPath(import.meta.url);
16-
const __dirname = dirname(__filename);
17-
18-
const getFriendlyName = whichBrowser => whichBrowser[0].toUpperCase() + whichBrowser.slice(1).replace(/[a-z]_[a-z]/g, _ => _[0] + ' ' + _[2].toUpperCase());
19-
20-
const ranJsDir = !process.argv[1] ? __dirname : (extname(process.argv[1]) ? dirname(process.argv[1]) : process.argv[1]);
21-
const getDataPath = browser => join(ranJsDir, 'gluon_data', browser);
22-
23-
const portRange = [ 10000, 60000 ];
24-
const generatePort = () => (Math.floor(Math.random() * (portRange[1] - portRange[0] + 1)) + portRange[0]);
25-
26-
// default CSP policy. tl;dr: allow everything if same-origin, and allow all mostly non-dangerous things for all domains (images, css, requests)
27-
const defaultCSP = [ 'upgrade-insecure-requests' ].concat(
28-
[ 'default-src' ].map(x => `${x} 'self' 'unsafe-inline'`)
29-
).concat(
30-
[ 'connect-src', 'font-src', 'img-src', 'media-src', 'style-src', 'form-action' ].map(x => `${x} https: data: blob: 'unsafe-inline'`)
31-
).join('; ');
32-
33-
const startBrowser = async (url, parentDir, { allowHTTP = false, allowNavigation = 'same-origin', windowSize, forceBrowser, forceEngine, localCSP = defaultCSP, devtools, userAgent, incognito }) => {
34-
const [ browserPath, browserName ] = await findBrowserPath(forceBrowser, forceEngine);
35-
if (!browserPath) {
36-
throw new Error('Failed to find a usable browser installed');
37-
}
38-
39-
const browserFriendlyName = getFriendlyName(browserName);
40-
const browserType = getBrowserType(browserName);
41-
42-
let dataPath = getDataPath(browserName);
43-
if (incognito) dataPath = join(dataPath, 'incognito-' + Math.random().toString().slice(2));
44-
45-
log('found browser', browserName, `(${browserType} based)`, 'at path:', browserPath);
46-
log('data path:', dataPath);
47-
48-
const openingLocal = !url.includes('://') && !url.includes('data:');
49-
const localUrl = browserType === 'firefox' ? `http://localhost:${generatePort()}` : 'https://app.gluon';
50-
const basePath = isAbsolute(url) ? url : join(parentDir, url);
51-
52-
const closeHandlers = [];
53-
if (openingLocal && browserType === 'firefox') closeHandlers.push(await LocalHTTP({ url: localUrl, basePath, csp: localCSP }));
54-
55-
const Window = await (browserType === 'firefox' ? Firefox : Chromium)({
56-
dataPath,
57-
browserPath
58-
}, {
59-
url: openingLocal ? localUrl : url,
60-
windowSize,
61-
allowHTTP,
62-
extensions: ExtensionsAPI._extensions[browserType],
63-
devtools: devtools === false ? process.argv.includes('--enable-devtools') : true,
64-
userAgent
65-
}, {
66-
browserName: browserFriendlyName,
67-
url: openingLocal ? localUrl : url,
68-
basePath,
69-
openingLocal,
70-
closeHandlers,
71-
browserType,
72-
dataPath,
73-
allowNavigation,
74-
localCSP
75-
});
76-
77-
return Window;
78-
};
79-
80-
// get parent directory of where function was called from
81-
const getParentDir = () => {
82-
let place = (new Error()).stack.split('\n')[3].slice(7).trim().split(':').slice(0, -2).join(':');
83-
if (place.includes('(') && place.includes(')')) {
84-
place = place.split('(').slice(1).join('(')
85-
}
86-
87-
if (place.startsWith('file://')) place = fileURLToPath(place);
88-
return dirname(place);
89-
};
90-
91-
const checkForDangerousOptions = ({ allowHTTP, allowNavigation, localCSP }) => {
92-
if (allowHTTP === true) dangerousAPI('Gluon.open', 'allowHTTP', 'true');
93-
if (allowNavigation === true) dangerousAPI('Gluon.open', 'allowNavigation', 'true');
94-
if (localCSP === '') dangerousAPI('Gluon.open', 'localCSP', '\'\'');
95-
};
96-
97-
export const open = async (url, opts = {}) => {
98-
const { allowHTTP = false } = opts;
99-
100-
if (allowHTTP !== true && url.startsWith('http://')) throw new Error(`HTTP URLs are blocked by default. Please use HTTPS, or if not possible, enable the 'allowHTTP' option.`);
101-
102-
checkForDangerousOptions(opts);
103-
log('starting browser...');
104-
105-
const Browser = await startBrowser(url, getParentDir(), opts);
106-
107-
return Browser;
108-
};
109-
110-
export const extensions = {
111-
add: ExtensionsAPI.add,
112-
remove: ExtensionsAPI.remove
113-
};
114-
1+
import { join, dirname, extname, isAbsolute } from 'path';
2+
3+
import { fileURLToPath } from 'url';
4+
import { log, dangerousAPI } from './lib/logger.js';
5+
6+
import Chromium from './browser/chromium.js';
7+
import Firefox from './browser/firefox.js';
8+
9+
import * as ExtensionsAPI from './extensions.js';
10+
import LocalHTTP from './lib/local/http.js';
11+
import { findBrowserPath, getBrowserType } from './lib/browserPaths.js';
12+
13+
process.versions.gluon = '0.14.0';
14+
15+
const __filename = fileURLToPath(import.meta.url);
16+
const __dirname = dirname(__filename);
17+
18+
const getFriendlyName = whichBrowser => whichBrowser[0].toUpperCase() + whichBrowser.slice(1).replace(/[a-z]_[a-z]/g, _ => _[0] + ' ' + _[2].toUpperCase());
19+
20+
const ranJsDir = !process.argv[1] ? __dirname : (extname(process.argv[1]) ? dirname(process.argv[1]) : process.argv[1]);
21+
const getDataPath = browser => join(ranJsDir, 'gluon_data', browser);
22+
23+
const portRange = [ 10000, 60000 ];
24+
const generatePort = () => (Math.floor(Math.random() * (portRange[1] - portRange[0] + 1)) + portRange[0]);
25+
26+
// default CSP policy. tl;dr: allow everything if same-origin, and allow all mostly non-dangerous things for all domains (images, css, requests)
27+
const defaultCSP = [ 'upgrade-insecure-requests' ].concat(
28+
[ 'default-src' ].map(x => `${x} 'self' 'unsafe-inline'`)
29+
).concat(
30+
[ 'connect-src', 'font-src', 'img-src', 'media-src', 'style-src', 'form-action' ].map(x => `${x} https: data: blob: 'unsafe-inline'`)
31+
).join('; ');
32+
33+
const startBrowser = async (url, parentDir, { allowHTTP = false, allowNavigation = 'same-origin', windowSize, forceBrowser, forceEngine, localCSP = defaultCSP, devtools, userAgent, incognito }) => {
34+
const [ browserPath, browserName ] = await findBrowserPath(forceBrowser, forceEngine);
35+
if (!browserPath) {
36+
throw new Error('Failed to find a usable browser installed');
37+
}
38+
39+
const browserFriendlyName = getFriendlyName(browserName);
40+
const browserType = getBrowserType(browserName);
41+
42+
let dataPath = getDataPath(browserName);
43+
if (incognito) dataPath = join(dataPath, 'incognito-' + Math.random().toString().slice(2));
44+
45+
log('found browser', browserName, `(${browserType} based)`, 'at path:', browserPath);
46+
log('data path:', dataPath);
47+
48+
const openingLocal = !url.includes('://') && !url.includes('data:');
49+
const localUrl = browserType === 'firefox' ? `http://localhost:${generatePort()}` : 'https://app.gluon';
50+
const basePath = isAbsolute(url) ? url : join(parentDir, url);
51+
52+
const closeHandlers = [];
53+
if (openingLocal && browserType === 'firefox') closeHandlers.push(await LocalHTTP({ url: localUrl, basePath, csp: localCSP }));
54+
55+
const Window = await (browserType === 'firefox' ? Firefox : Chromium)({
56+
dataPath,
57+
browserPath
58+
}, {
59+
url: openingLocal ? localUrl : url,
60+
windowSize,
61+
allowHTTP,
62+
extensions: ExtensionsAPI._extensions[browserType],
63+
devtools: devtools === false ? process.argv.includes('--enable-devtools') : true,
64+
userAgent
65+
}, {
66+
browserName: browserFriendlyName,
67+
url: openingLocal ? localUrl : url,
68+
basePath,
69+
openingLocal,
70+
closeHandlers,
71+
browserType,
72+
dataPath,
73+
allowNavigation,
74+
localCSP
75+
});
76+
77+
return Window;
78+
};
79+
80+
// get parent directory of where function was called from
81+
const getParentDir = () => {
82+
let place = (new Error()).stack.split('\n')[3].slice(7).trim().split(':').slice(0, -2).join(':');
83+
if (place.includes('(') && place.includes(')')) {
84+
place = place.split('(').slice(1).join('(')
85+
}
86+
87+
if (place.startsWith('file://')) place = fileURLToPath(place);
88+
return dirname(place);
89+
};
90+
91+
const checkForDangerousOptions = ({ allowHTTP, allowNavigation, localCSP }) => {
92+
if (allowHTTP === true) dangerousAPI('Gluon.open', 'allowHTTP', 'true');
93+
if (allowNavigation === true) dangerousAPI('Gluon.open', 'allowNavigation', 'true');
94+
if (localCSP === '') dangerousAPI('Gluon.open', 'localCSP', '\'\'');
95+
};
96+
97+
export const open = async (url, opts = {}) => {
98+
const { allowHTTP = false } = opts;
99+
100+
if (allowHTTP !== true && url.startsWith('http://')) throw new Error(`HTTP URLs are blocked by default. Please use HTTPS, or if not possible, enable the 'allowHTTP' option.`);
101+
102+
checkForDangerousOptions(opts);
103+
log('starting browser...');
104+
105+
const Browser = await startBrowser(url, getParentDir(), opts);
106+
107+
return Browser;
108+
};
109+
110+
export const extensions = {
111+
add: ExtensionsAPI.add,
112+
remove: ExtensionsAPI.remove
113+
};
114+
115115
export { default as openAbout } from "./menus/about.js";

0 commit comments

Comments
 (0)