forked from HeyPuter/puter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
144 lines (126 loc) · 5.74 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
window.puter_gui_enabled = true;
/**
* Initializes and configures the GUI (Graphical User Interface) settings based on the provided options.
*
* The function sets global variables in the window object for various settings such as origins and domain names.
* It also handles loading different resources depending on the environment (development or production).
*
* @param {Object} options - Configuration options to initialize the GUI.
* @param {string} [options.gui_origin='https://puter.com'] - The origin URL for the GUI.
* @param {string} [options.api_origin='https://api.puter.com'] - The origin URL for the API.
* @param {number} [options.max_item_name_length=500] - Maximum allowed length for an item name.
* @param {boolean} [options.require_email_verification_to_publish_website=true] - Flag to decide whether email verification is required to publish a website.
*
* @property {string} [options.app_domain] - Extracted domain name from gui_origin. It's derived automatically if not provided.
* @property {string} [window.gui_env] - The environment in which the GUI is running (e.g., "dev" or "prod").
*
* @returns {Promise<void>} Returns a promise that resolves when initialization and resource loading are complete.
*
* @example
* window.gui({
* gui_origin: 'https://myapp.com',
* api_origin: 'https://myapi.com',
* max_item_name_length: 250
* });
*/
window.gui = async function(options){
options = options ?? {};
// app_origin is deprecated, use gui_origin instead
window.gui_origin = options.gui_origin ?? options.app_origin ?? `https://puter.com`;
window.app_domain = options.app_domain ?? new URL(window.gui_origin).hostname;
window.hosting_domain = options.hosting_domain ?? 'puter.site';
window.api_origin = options.api_origin ?? "https://api.puter.com";
window.max_item_name_length = options.max_item_name_length ?? 500;
window.require_email_verification_to_publish_website = options.require_email_verification_to_publish_website ?? true;
// Add Puter.JS
await loadScript('https://js.puter.com/v2/');
// DEV: Load the initgui.js file if we are in development mode
if(!window.gui_env || window.gui_env === "dev"){
await loadScript('/initgui.js', {isModule: true});
}
// PROD: load the minified bundles if we are in production mode
// note: the order of the bundles is important
// note: Build script will prepend `window.gui_env="prod"` to the top of the file
else if(gui_env === "prod"){
// Load the minified bundles
await loadCSS('/dist/bundle.min.css');
await loadScript('/dist/bundle.min.js');
}
// 🚀 Launch the GUI 🚀
initgui();
}
/**
* Dynamically loads an external JavaScript file.
* @param {string} url The URL of the external script to load.
* @param {Object} [options] Optional configuration for the script.
* @param {boolean} [options.isModule] Whether the script is a module.
* @param {boolean} [options.defer] Whether the script should be deferred.
* @param {Object} [options.dataAttributes] An object containing data attributes to add to the script element.
* @returns {Promise} A promise that resolves once the script has loaded, or rejects on error.
*/
window.loadScript = async function(url, options = {}) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
// Set default script loading behavior
script.async = true;
// Handle if it is a module
if (options.isModule) {
script.type = 'module';
}
// Handle defer attribute
if (options.defer) {
script.defer = true;
script.async = false; // When "defer" is true, "async" should be false as they are mutually exclusive
}
// Add arbitrary data attributes
if (options.dataAttributes && typeof options.dataAttributes === 'object') {
for (const [key, value] of Object.entries(options.dataAttributes)) {
script.setAttribute(`data-${key}`, value);
}
}
// Resolve the promise when the script is loaded
script.onload = () => resolve();
// Reject the promise if there's an error during load
script.onerror = (error) => reject(new Error(`Failed to load script at url: ${url}`));
// Append the script to the body
document.body.appendChild(script);
});
};
/**
* Dynamically loads an external CSS file.
* @param {string} url The URL of the external CSS to load.
* @returns {Promise} A promise that resolves once the CSS has loaded, or rejects on error.
*/
window.loadCSS = async function(url) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
link.onload = () => {
resolve();
};
link.onerror = (error) => {
reject(new Error(`Failed to load CSS at url: ${url}`));
};
document.head.appendChild(link);
});
}