-
Notifications
You must be signed in to change notification settings - Fork 186
/
Copy pathdev-server-wrapper.html
88 lines (77 loc) · 2.97 KB
/
dev-server-wrapper.html
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
<!--
This is a development server page that serves as a wrapper for Google Apps Script (GAS) client-side development.
It is meant to be run inside a Google Sheets/Docs/Forms dialog window during local development.
It loads the gas-client library (as an external), sets up an iframe that points to a local development
server (such as running with vite), and establishes a communication bridge between the GAS server functions and the local development server.
This allows for local development and testing of client-side code while still being able to interact with
the GAS server-side functions.
Two placeholders are used in this file that will need to be replaced in a build step:
- _ _PORT_ _: The port number of the local development server. (e.g. 3000)
- _ _FILE_NAME_ _: The name of the file being loaded. (e.g. dialog-demo-bootstrap/index.html)
-->
<!DOCTYPE html>
<html>
<head>
<base target="_top" />
<title>Dev Server</title>
<!-- Load gas-client as external. Exposed global variable is GASClient. -->
<script src="https://unpkg.com/[email protected]/dist/index.js"></script>
<style>
body,
html {
margin: 0;
width: 100%;
height: 100%;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
// These values need to be replaced during the build process
const PORT = '__PORT__';
const FILE_NAME = '__FILE_NAME__';
const iframe = document.getElementById('iframe');
iframe.src = 'https://localhost:' + PORT + '/' + FILE_NAME;
const { serverFunctions, scriptHostFunctions } =
new window.GASClient.GASClient({
allowedDevelopmentDomains: (origin) =>
/https:\/\/.*\.googleusercontent\.com$/.test(origin),
});
const handleRequest = (event) => {
const request = event.data;
const { type, functionName, id, args } = request;
if (type === 'SCRIPT_HOST_FUNCTION_REQUEST') {
scriptHostFunctions[functionName](...args);
}
if (type !== 'REQUEST') return;
serverFunctions[functionName](...args)
.then((response) => {
iframe.contentWindow.postMessage(
{ type: 'RESPONSE', id, status: 'SUCCESS', response },
'https://localhost:' + PORT
);
})
.catch((err) => {
iframe.contentWindow.postMessage(
{
type: 'RESPONSE',
id,
status: 'ERROR',
response: err,
},
'https://localhost:' + PORT
);
});
};
window.addEventListener('message', handleRequest, false);
});
</script>
</head>
<body>
<div style="width: 100%; height: 100%">
<iframe
id="iframe"
style="width: 100%; height: 100%; border: 0; position: absolute"
></iframe>
</div>
</body>
</html>