@webqit/webflo 0.11.61 → 0.20.2-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +12 -0
- package/.github/workflows/publish.yml +48 -0
- package/.gitignore +2 -0
- package/LICENSE +2 -2
- package/README.md +71 -2050
- package/package.json +28 -13
- package/site/-/_.md +139 -0
- package/site/-/docs.old.md +2010 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url 2.js +93 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js +93 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js 2.map +7 -0
- package/site/.vitepress/cache/deps/@braintree_sanitize-url.js.map +7 -0
- package/site/.vitepress/cache/deps/_metadata 2.json +85 -0
- package/site/.vitepress/cache/deps/_metadata.json +85 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4 2.js +9 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js +9 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +7 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK 2.js +9719 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js +9719 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-Q2AYPHVK.js.map +7 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7 2.js +12705 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js +12705 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js 2.map +7 -0
- package/site/.vitepress/cache/deps/chunk-QAXAIFA7.js.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape 2.js +30278 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent 2.js +4710 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js +4710 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js 2.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape.js +30278 -0
- package/site/.vitepress/cache/deps/cytoscape.js 2.map +7 -0
- package/site/.vitepress/cache/deps/cytoscape.js.map +7 -0
- package/site/.vitepress/cache/deps/dayjs 2.js +285 -0
- package/site/.vitepress/cache/deps/dayjs.js +285 -0
- package/site/.vitepress/cache/deps/dayjs.js 2.map +7 -0
- package/site/.vitepress/cache/deps/dayjs.js.map +7 -0
- package/site/.vitepress/cache/deps/debug 2.js +453 -0
- package/site/.vitepress/cache/deps/debug.js +453 -0
- package/site/.vitepress/cache/deps/debug.js 2.map +7 -0
- package/site/.vitepress/cache/deps/debug.js.map +7 -0
- package/site/.vitepress/cache/deps/package 2.json +3 -0
- package/site/.vitepress/cache/deps/package.json +3 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api 2.js +4507 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4507 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core 2.js +584 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js +584 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap 2.js +1166 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1166 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js 2.js +1667 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1667 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch 2.js +1815 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js +1815 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
- package/site/.vitepress/cache/deps/vue 2.js +344 -0
- package/site/.vitepress/cache/deps/vue.js +344 -0
- package/site/.vitepress/cache/deps/vue.js 2.map +7 -0
- package/site/.vitepress/cache/deps/vue.js.map +7 -0
- package/site/.vitepress/config.ts +147 -0
- package/site/.vitepress/theme/custom.css +50 -0
- package/site/.vitepress/theme/index.ts +6 -0
- package/site/api/webflo-fetch/FormData.md +0 -0
- package/site/api/webflo-fetch/Headers.md +0 -0
- package/site/api/webflo-fetch/LiveResponse.md +0 -0
- package/site/api/webflo-fetch/Request.md +0 -0
- package/site/api/webflo-fetch/Response.md +0 -0
- package/site/api/webflo-fetch/fetch.md +0 -0
- package/site/api/webflo-routing/HttpCookies.md +0 -0
- package/site/api/webflo-routing/HttpEvent/respondWith.md +1 -0
- package/site/api/webflo-routing/HttpEvent/waitUntil.md +1 -0
- package/site/api/webflo-routing/HttpEvent/waitUntilNavigate.md +1 -0
- package/site/api/webflo-routing/HttpEvent.md +30 -0
- package/site/api/webflo-routing/HttpSession.md +0 -0
- package/site/api/webflo-routing/HttpState.md +0 -0
- package/site/api/webflo-routing/HttpUser.md +0 -0
- package/site/api/webflo-routing/handler/fetch.md +42 -0
- package/site/api/webflo-routing/handler/next.md +54 -0
- package/site/api/webflo-routing/handler.md +119 -0
- package/site/api.md +26 -0
- package/site/contributing.md +16 -0
- package/site/docs/advanced/lifecycles.md +20 -0
- package/site/docs/advanced/redirects.md +0 -0
- package/site/docs/advanced/routing.md +1 -0
- package/site/docs/advanced.md +9 -0
- package/site/docs/concepts/realtime.md +637 -0
- package/site/docs/concepts/rendering.md +60 -0
- package/site/docs/concepts/request-response.md +47 -0
- package/site/docs/concepts/routing.md +656 -0
- package/site/docs/concepts/state.md +44 -0
- package/site/docs/concepts/templates.md +48 -0
- package/site/docs/concepts.md +97 -0
- package/site/docs/getting-started.md +378 -0
- package/site/docs/tech-stack.md +56 -0
- package/site/docs.md +100 -0
- package/site/examples/pwa.md +10 -0
- package/site/examples/web.md +11 -0
- package/site/examples.md +10 -0
- package/site/faq.md +13 -0
- package/site/guides/guide-auth.md +13 -0
- package/site/guides/guide-file-upload.md +11 -0
- package/site/guides/guide-service-worker.md +10 -0
- package/site/guides/tutorial-1-todo.md +24 -0
- package/site/guides.md +15 -0
- package/site/index.md +39 -0
- package/site/public/img/brand/logo-670x670.png +0 -0
- package/site/recipes/realtime.md +11 -0
- package/site/recipes/streaming.md +15 -0
- package/site/reference/cli.md +11 -0
- package/site/reference/config.md +13 -0
- package/site/reference/tools.md +9 -0
- package/src/Context.js +3 -11
- package/src/config-pi/deployment/Env.js +6 -19
- package/src/config-pi/deployment/Layout.js +11 -3
- package/src/config-pi/runtime/Client.js +40 -48
- package/src/config-pi/runtime/Server.js +52 -20
- package/src/config-pi/runtime/client/Worker.js +22 -20
- package/src/config-pi/static/Init.js +57 -0
- package/src/config-pi/static/index.js +2 -0
- package/src/deployment-pi/origins/index.js +1 -1
- package/src/deployment-pi/util.js +161 -0
- package/src/index.js +3 -9
- package/src/init-pi/index.js +117 -0
- package/src/init-pi/templates/pwa/app/handler.server.js +8 -0
- package/src/init-pi/templates/pwa/app/page.html +7 -0
- package/src/init-pi/templates/pwa/package.json +19 -0
- package/src/init-pi/templates/pwa/public/assets/app.css +16 -0
- package/src/init-pi/templates/pwa/public/index.html +39 -0
- package/src/init-pi/templates/pwa/public/manifest.json +29 -0
- package/src/init-pi/templates/web/app/handler.server.js +8 -0
- package/src/init-pi/templates/web/app/page.html +7 -0
- package/src/init-pi/templates/web/package.json +19 -0
- package/src/init-pi/templates/web/public/assets/app.css +16 -0
- package/src/init-pi/templates/web/public/index.html +39 -0
- package/src/runtime-pi/WebfloRuntime.js +350 -0
- package/src/runtime-pi/index.js +3 -10
- package/src/runtime-pi/webflo-client/ClientSideCookies.js +17 -0
- package/src/runtime-pi/webflo-client/ClientSideWorkport.js +63 -0
- package/src/runtime-pi/webflo-client/DeviceCapabilities.js +213 -0
- package/src/runtime-pi/webflo-client/WebfloClient.js +500 -0
- package/src/runtime-pi/webflo-client/WebfloRootClient1.js +206 -0
- package/src/runtime-pi/webflo-client/WebfloRootClient2.js +113 -0
- package/src/runtime-pi/webflo-client/WebfloSubClient.js +118 -0
- package/src/runtime-pi/webflo-client/index.js +17 -0
- package/src/runtime-pi/webflo-client/webflo-codegen.js +469 -0
- package/src/runtime-pi/webflo-client/webflo-devmode.js +243 -0
- package/src/runtime-pi/webflo-client/webflo-embedded.js +50 -0
- package/src/runtime-pi/webflo-fetch/LiveResponse.js +437 -0
- package/src/runtime-pi/webflo-fetch/cookies.js +10 -0
- package/src/runtime-pi/webflo-fetch/fetch.js +16 -0
- package/src/runtime-pi/webflo-fetch/formdata.js +54 -0
- package/src/runtime-pi/webflo-fetch/headers.js +151 -0
- package/src/runtime-pi/webflo-fetch/index.js +5 -0
- package/src/runtime-pi/webflo-fetch/message.js +49 -0
- package/src/runtime-pi/webflo-fetch/request.js +62 -0
- package/src/runtime-pi/webflo-fetch/response.js +110 -0
- package/src/runtime-pi/webflo-fetch/util.js +28 -0
- package/src/runtime-pi/webflo-messaging/WQBroadcastChannel.js +10 -0
- package/src/runtime-pi/webflo-messaging/WQMessageChannel.js +26 -0
- package/src/runtime-pi/webflo-messaging/WQMessageEvent.js +87 -0
- package/src/runtime-pi/webflo-messaging/WQMessagePort.js +38 -0
- package/src/runtime-pi/webflo-messaging/WQRelayPort.js +47 -0
- package/src/runtime-pi/webflo-messaging/WQSockPort.js +113 -0
- package/src/runtime-pi/webflo-messaging/WQStarPort.js +104 -0
- package/src/runtime-pi/webflo-messaging/wq-message-port.js +404 -0
- package/src/runtime-pi/webflo-routing/HttpCookies.js +42 -0
- package/src/runtime-pi/webflo-routing/HttpEvent.js +112 -0
- package/src/runtime-pi/webflo-routing/HttpSession.js +11 -0
- package/src/runtime-pi/webflo-routing/HttpState.js +153 -0
- package/src/runtime-pi/webflo-routing/HttpUser.js +54 -0
- package/src/runtime-pi/webflo-routing/WebfloRouter.js +245 -0
- package/src/runtime-pi/webflo-server/ServerSideCookies.js +19 -0
- package/src/runtime-pi/webflo-server/ServerSideSession.js +38 -0
- package/src/runtime-pi/webflo-server/WebfloServer.js +937 -0
- package/src/runtime-pi/webflo-server/index.js +11 -0
- package/src/runtime-pi/webflo-server/messaging/Client.js +27 -0
- package/src/runtime-pi/webflo-server/messaging/ClientRequestRealtime.js +50 -0
- package/src/runtime-pi/webflo-server/messaging/Clients.js +25 -0
- package/src/runtime-pi/webflo-server/webflo-devmode.js +326 -0
- package/src/runtime-pi/{client → webflo-url}/Url.js +27 -76
- package/src/runtime-pi/webflo-url/index.js +1 -0
- package/src/runtime-pi/webflo-url/urlpattern.js +38 -0
- package/src/runtime-pi/{util-url.js → webflo-url/util.js} +5 -43
- package/src/runtime-pi/webflo-url/xURL.js +94 -0
- package/src/runtime-pi/webflo-worker/WebfloWorker.js +234 -0
- package/src/runtime-pi/webflo-worker/WorkerSideCookies.js +19 -0
- package/src/runtime-pi/webflo-worker/WorkerSideWorkport.js +18 -0
- package/src/runtime-pi/webflo-worker/index.js +11 -0
- package/src/services-pi/index.js +2 -0
- package/src/services-pi/push/index.js +23 -0
- package/src/util.js +10 -0
- package/src/{webflo.js → webflo-cli.js} +4 -4
- package/src/runtime-pi/Application.js +0 -29
- package/src/runtime-pi/Cookies.js +0 -82
- package/src/runtime-pi/HttpEvent.js +0 -107
- package/src/runtime-pi/Router.js +0 -130
- package/src/runtime-pi/Runtime.js +0 -21
- package/src/runtime-pi/client/Application.js +0 -76
- package/src/runtime-pi/client/Context.js +0 -7
- package/src/runtime-pi/client/Router.js +0 -48
- package/src/runtime-pi/client/Runtime.js +0 -525
- package/src/runtime-pi/client/Workport.js +0 -190
- package/src/runtime-pi/client/createStorage.js +0 -58
- package/src/runtime-pi/client/generate.js +0 -481
- package/src/runtime-pi/client/index.js +0 -21
- package/src/runtime-pi/client/worker/Application.js +0 -44
- package/src/runtime-pi/client/worker/Context.js +0 -7
- package/src/runtime-pi/client/worker/Runtime.js +0 -275
- package/src/runtime-pi/client/worker/Workport.js +0 -78
- package/src/runtime-pi/client/worker/index.js +0 -21
- package/src/runtime-pi/server/Application.js +0 -101
- package/src/runtime-pi/server/Context.js +0 -16
- package/src/runtime-pi/server/Router.js +0 -159
- package/src/runtime-pi/server/Runtime.js +0 -558
- package/src/runtime-pi/server/index.js +0 -21
- package/src/runtime-pi/util-http.js +0 -86
- package/src/runtime-pi/xFormData.js +0 -24
- package/src/runtime-pi/xHeaders.js +0 -146
- package/src/runtime-pi/xRequest.js +0 -46
- package/src/runtime-pi/xRequestHeaders.js +0 -109
- package/src/runtime-pi/xResponse.js +0 -33
- package/src/runtime-pi/xResponseHeaders.js +0 -117
- package/src/runtime-pi/xURL.js +0 -105
- package/src/runtime-pi/xfetch.js +0 -23
- package/src/runtime-pi/xxHttpMessage.js +0 -102
- package/src/static-pi/index.js +0 -11
|
@@ -20,16 +20,22 @@ export default class Server extends Dotfile {
|
|
|
20
20
|
withDefaults(config) {
|
|
21
21
|
return this.merge({
|
|
22
22
|
port: process.env.PORT || 3000,
|
|
23
|
-
|
|
23
|
+
hostnames: [],
|
|
24
24
|
https: {
|
|
25
25
|
port: process.env.SSL_PORT || 0,
|
|
26
|
-
|
|
26
|
+
hostnames: [],
|
|
27
27
|
keyfile: '/etc/letsencrypt/live/[domain]/privkey.pem',
|
|
28
28
|
certfile: '/etc/letsencrypt/live/[domain]/fullchain.pem',
|
|
29
29
|
force: false,
|
|
30
30
|
},
|
|
31
31
|
force_www: '',
|
|
32
|
-
|
|
32
|
+
capabilities: {
|
|
33
|
+
database: false,
|
|
34
|
+
database_dialect: 'postgres',
|
|
35
|
+
redis: false,
|
|
36
|
+
webpush: false,
|
|
37
|
+
vapid_subject: 'mailto:foo@example.com',
|
|
38
|
+
},
|
|
33
39
|
}, config, 'patch');
|
|
34
40
|
}
|
|
35
41
|
|
|
@@ -42,13 +48,6 @@ export default class Server extends Dotfile {
|
|
|
42
48
|
{value: 'add',},
|
|
43
49
|
{value: 'remove',},
|
|
44
50
|
],
|
|
45
|
-
oohtml_support: [
|
|
46
|
-
{value: 'full', title: 'full'},
|
|
47
|
-
{value: 'namespacing', title: 'namespacing'},
|
|
48
|
-
{value: 'scripting', title: 'scripting'},
|
|
49
|
-
{value: 'templating', title: 'templating'},
|
|
50
|
-
{value: 'none', title: 'none'},
|
|
51
|
-
],
|
|
52
51
|
}, choices, 'patch');
|
|
53
52
|
// Questions
|
|
54
53
|
return [
|
|
@@ -60,9 +59,10 @@ export default class Server extends Dotfile {
|
|
|
60
59
|
validation: ['important'],
|
|
61
60
|
},
|
|
62
61
|
{
|
|
63
|
-
name: '
|
|
62
|
+
name: 'hostnames',
|
|
64
63
|
type: 'list',
|
|
65
|
-
message: '[
|
|
64
|
+
message: '[hostnames]: Enter a list of allowed hostnames if necessary (comma-separated)',
|
|
65
|
+
initial: (config.hostnames || []).join(', '),
|
|
66
66
|
validation: ['important'],
|
|
67
67
|
},
|
|
68
68
|
{
|
|
@@ -98,9 +98,9 @@ export default class Server extends Dotfile {
|
|
|
98
98
|
validation: ['important'],
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
|
-
name: '
|
|
101
|
+
name: 'hostnames',
|
|
102
102
|
type: 'list',
|
|
103
|
-
message: '[
|
|
103
|
+
message: '[hostnames]: Enter the CERT hostnames (comma-separated)',
|
|
104
104
|
validation: ['important'],
|
|
105
105
|
},
|
|
106
106
|
{
|
|
@@ -113,12 +113,44 @@ export default class Server extends Dotfile {
|
|
|
113
113
|
],
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
|
-
name: '
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
initial:
|
|
121
|
-
|
|
116
|
+
name: 'capabilities',
|
|
117
|
+
controls: {
|
|
118
|
+
name: 'capabilities',
|
|
119
|
+
},
|
|
120
|
+
initial: config.capabilities,
|
|
121
|
+
schema: [
|
|
122
|
+
{
|
|
123
|
+
name: 'database',
|
|
124
|
+
type: 'toggle',
|
|
125
|
+
message: 'Add database integration?',
|
|
126
|
+
active: 'YES',
|
|
127
|
+
inactive: 'NO',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'database_dialect',
|
|
131
|
+
type: (prev, answers) => !answers.database ? null : 'text',
|
|
132
|
+
message: 'Enter the database dialect (postgres for now)',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'redis',
|
|
136
|
+
type: 'toggle',
|
|
137
|
+
message: 'Add redis integration?',
|
|
138
|
+
active: 'YES',
|
|
139
|
+
inactive: 'NO',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'webpush',
|
|
143
|
+
type: 'toggle',
|
|
144
|
+
message: 'Add webpush integration?',
|
|
145
|
+
active: 'YES',
|
|
146
|
+
inactive: 'NO',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'vapid_subject',
|
|
150
|
+
type: (prev, answers) => !answers.webpush ? null : 'text',
|
|
151
|
+
message: 'Enter the vapid_subject URL',
|
|
152
|
+
}
|
|
153
|
+
]
|
|
122
154
|
},
|
|
123
155
|
];
|
|
124
156
|
}
|
|
@@ -21,14 +21,15 @@ export default class Worker extends Dotfile {
|
|
|
21
21
|
// Defaults merger
|
|
22
22
|
withDefaults(config) {
|
|
23
23
|
return this.merge({
|
|
24
|
+
filename: 'app.worker.js',
|
|
25
|
+
scope: '/',
|
|
26
|
+
skip_waiting: true,
|
|
24
27
|
cache_name: 'cache_v0',
|
|
25
28
|
default_fetching_strategy: 'network-first',
|
|
26
29
|
network_first_urls: [],
|
|
27
30
|
cache_first_urls: [],
|
|
28
31
|
network_only_urls: [],
|
|
29
32
|
cache_only_urls: [],
|
|
30
|
-
skip_waiting: true,
|
|
31
|
-
bundle_public_env: false,
|
|
32
33
|
}, config, 'patch');
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -49,6 +50,24 @@ export default class Worker extends Dotfile {
|
|
|
49
50
|
}, choices, 'patch');
|
|
50
51
|
// Questions
|
|
51
52
|
return [
|
|
53
|
+
{
|
|
54
|
+
name: 'filename',
|
|
55
|
+
type: 'text',
|
|
56
|
+
message: 'Specify the Service Worker filename',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'scope',
|
|
60
|
+
type: 'text',
|
|
61
|
+
message: 'Specify the Service Worker scope',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'skip_waiting',
|
|
65
|
+
type: 'toggle',
|
|
66
|
+
message: 'Choose whether to skip the "waiting" state for updated Service Workers',
|
|
67
|
+
active: 'YES',
|
|
68
|
+
inactive: 'NO',
|
|
69
|
+
initial: config.skip_waiting,
|
|
70
|
+
},
|
|
52
71
|
{
|
|
53
72
|
name: 'cache_name',
|
|
54
73
|
type: 'text',
|
|
@@ -86,24 +105,7 @@ export default class Worker extends Dotfile {
|
|
|
86
105
|
type: (prev, answers) => answers.default_fetching_strategy === 'cache-only' ? null : 'list',
|
|
87
106
|
message: 'Specify URLs for a "cache-only" fetching strategy (comma-separated, globe supported)',
|
|
88
107
|
initial: (config.cache_only_urls || []).join(', '),
|
|
89
|
-
}
|
|
90
|
-
{
|
|
91
|
-
name: 'skip_waiting',
|
|
92
|
-
type: 'toggle',
|
|
93
|
-
message: 'Choose whether to skip the "waiting" state for updated Service Workers',
|
|
94
|
-
active: 'YES',
|
|
95
|
-
inactive: 'NO',
|
|
96
|
-
initial: config.skip_waiting,
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'bundle_public_env',
|
|
100
|
-
type: 'toggle',
|
|
101
|
-
message: '[bundle_public_env]: Bundle public ENV variables?',
|
|
102
|
-
active: 'YES',
|
|
103
|
-
inactive: 'NO',
|
|
104
|
-
initial: config.bundle_public_env,
|
|
105
|
-
validation: ['important'],
|
|
106
|
-
},
|
|
108
|
+
}
|
|
107
109
|
];
|
|
108
110
|
}
|
|
109
111
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* imports
|
|
4
|
+
*/
|
|
5
|
+
import { Dotfile } from '@webqit/backpack';
|
|
6
|
+
|
|
7
|
+
export default class Init extends Dotfile {
|
|
8
|
+
|
|
9
|
+
// Base name
|
|
10
|
+
get name() {
|
|
11
|
+
return 'init';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// @desc
|
|
15
|
+
static get ['@desc']() {
|
|
16
|
+
return 'Webflo starter app config.';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Defaults merger
|
|
20
|
+
withDefaults(config) {
|
|
21
|
+
return this.merge({
|
|
22
|
+
template: 'web',
|
|
23
|
+
install: true,
|
|
24
|
+
git: true,
|
|
25
|
+
}, config, 'patch');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Questions generator
|
|
29
|
+
getSchema(config, choices = {}) {
|
|
30
|
+
// Questions
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
name: 'template',
|
|
34
|
+
type: 'text',
|
|
35
|
+
message: 'Enter the application template',
|
|
36
|
+
initial: config.template,
|
|
37
|
+
validation: ['important'],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'install',
|
|
41
|
+
type: 'toggle',
|
|
42
|
+
message: 'Run "npm install" after initialization?',
|
|
43
|
+
active: 'YES',
|
|
44
|
+
inactive: 'NO',
|
|
45
|
+
initial: config.install,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'git',
|
|
49
|
+
type: 'toggle',
|
|
50
|
+
message: 'Run "git init" after initialization?',
|
|
51
|
+
active: 'YES',
|
|
52
|
+
inactive: 'NO',
|
|
53
|
+
initial: config.git,
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -198,7 +198,7 @@ export async function webhook(httpEvent, router, next) {
|
|
|
198
198
|
}, _isNumeric(deployParams.ondeploy_autoexit) ? parseInt(deployParams.ondeploy_autoexit) : 0);
|
|
199
199
|
}
|
|
200
200
|
resolve(
|
|
201
|
-
new
|
|
201
|
+
new Response(`Deployment ${ exitCode === 0 ? 'success' : 'error: ' + exitCode }!`, { status: exitCode === 0 ? 200 : 500 })
|
|
202
202
|
);
|
|
203
203
|
if (cx.logger) {
|
|
204
204
|
cx.logger.log('');
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import Fs from 'fs';
|
|
2
|
+
import Path from 'path';
|
|
3
|
+
|
|
4
|
+
function parseHostnames(hostnames) {
|
|
5
|
+
return [].concat(hostnames).reduce((arr, str) => arr.concat(str.split(',')), []).map((str) => str.trim()).filter(str => str);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function selectHostnames(serverDefs, matchingPort = null) {
|
|
9
|
+
return serverDefs.reduce((hosts, def) => hosts.length ? hosts : (((!matchingPort || def.port === matchingPort) && parseHostnames(def.hostnames)) || []), []);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// config.runtime
|
|
13
|
+
|
|
14
|
+
export async function readInitConfig($context) {
|
|
15
|
+
if (!$context.config.static.Init) {
|
|
16
|
+
throw new Error(`The Client configurator "config.static.Init" is required in context.`);
|
|
17
|
+
}
|
|
18
|
+
return await (new $context.config.static.Init($context)).read();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function readClientConfig($context) {
|
|
22
|
+
if (!$context.config.runtime?.Client) {
|
|
23
|
+
throw new Error(`The Client configurator "config.runtime.Client" is required in context.`);
|
|
24
|
+
}
|
|
25
|
+
return await (new $context.config.runtime.Client($context)).read();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function readWorkerConfig($context) {
|
|
29
|
+
if (!$context.config.runtime?.client.Worker) {
|
|
30
|
+
throw new Error(`The Client configurator "config.runtime.client.Worker" is required in context.`);
|
|
31
|
+
}
|
|
32
|
+
return await (new $context.config.runtime.client.Worker($context)).read();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function readServerConfig($context) {
|
|
36
|
+
if (!$context.config.runtime?.Server) {
|
|
37
|
+
throw new Error(`The Client configurator "config.runtime.Server" is required in context.`);
|
|
38
|
+
}
|
|
39
|
+
const serverConfig = await (new $context.config.runtime.Server($context)).read();
|
|
40
|
+
serverConfig.hostnames = serverConfig.hostnames.length ? parseHostnames(serverConfig.hostnames) : ['*'];
|
|
41
|
+
if (serverConfig.https.port) {
|
|
42
|
+
serverConfig.https.hostnames = serverConfig.https.hostnames.length ? parseHostnames(serverConfig.https.hostnames) : ['*'];
|
|
43
|
+
}
|
|
44
|
+
return serverConfig;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function readHeadersConfig($context) {
|
|
48
|
+
if (!$context.config.runtime?.server.Headers) {
|
|
49
|
+
throw new Error(`The Client configurator "config.runtime.server.Headers" is required in context.`);
|
|
50
|
+
}
|
|
51
|
+
return await (new $context.config.runtime.server.Headers($context)).read();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function readRedirectsConfig($context) {
|
|
55
|
+
if (!$context.config.runtime?.server.Redirects) {
|
|
56
|
+
throw new Error(`The Client configurator "config.runtime.server.Redirects" is required in context.`);
|
|
57
|
+
}
|
|
58
|
+
return await (new $context.config.runtime.server.Redirects($context)).read();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// config.deployment
|
|
62
|
+
|
|
63
|
+
export async function readLayoutConfig($context) {
|
|
64
|
+
if (!$context.config.deployment?.Layout) {
|
|
65
|
+
throw new Error(`The Client configurator "config.deployment.Layout" is required in context.`);
|
|
66
|
+
}
|
|
67
|
+
const layoutConfig = await (new $context.config.deployment.Layout($context)).read();
|
|
68
|
+
return Object.fromEntries(['CLIENT_DIR', 'WORKER_DIR', 'SERVER_DIR', 'PUBLIC_DIR', 'VIEWS_DIR'].map((name) => {
|
|
69
|
+
return [name, Path.resolve($context.CWD || '', layoutConfig[name])];
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function readEnvConfig($context) {
|
|
74
|
+
if (!$context.config.deployment?.Env) {
|
|
75
|
+
throw new Error(`The Client configurator "config.deployment.Env" is required in context.`);
|
|
76
|
+
}
|
|
77
|
+
return await (new $context.config.deployment.Env($context)).read();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function readOriginsConfig($context) {
|
|
81
|
+
if (!$context.config.deployment?.Origins) {
|
|
82
|
+
throw new Error(`The Client configurator "config.deployment.Origins" is required in context.`);
|
|
83
|
+
}
|
|
84
|
+
return await (new $context.config.deployment.Origins($context)).read();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function readProxyConfig($context) {
|
|
88
|
+
if (!$context.config.deployment?.Proxy) {
|
|
89
|
+
throw new Error(`The Client configurator "config.deployment.Proxy" is required in context.`);
|
|
90
|
+
}
|
|
91
|
+
const proxyConfig = await (new $context.config.deployment.Proxy($context)).read();
|
|
92
|
+
const entries = await Promise.all(proxyConfig.entries.map(async ({ ...proxy }) => {
|
|
93
|
+
if (proxy.hostnames) {
|
|
94
|
+
proxy.hostnames = parseHostnames(proxy.hostnames);
|
|
95
|
+
}
|
|
96
|
+
if (proxy.path) {
|
|
97
|
+
const $$context = $context.constructor.create($context, Path.join($context.CWD, proxy.path));
|
|
98
|
+
proxy.SERVER = await (new $$context.config.runtime.Server($$context)).read();
|
|
99
|
+
if (!proxy.port) {
|
|
100
|
+
// Dynamically figure the local port on which this could be running
|
|
101
|
+
proxy.port = proxy.SERVER.https.port || proxy.SERVER.port;
|
|
102
|
+
}
|
|
103
|
+
if (!proxy.proto) {
|
|
104
|
+
// Dynamically figure the proto to forward the request with - to match running server
|
|
105
|
+
proxy.proto = proxy.port === proxy.SERVER.https.port ? 'https' : 'http';
|
|
106
|
+
}
|
|
107
|
+
if (!proxy.hostnames?.length) {
|
|
108
|
+
// Dynamically figure the hostnames to forward
|
|
109
|
+
proxy.hostnames = selectHostnames([proxy.SERVER.https, proxy.SERVER], proxy.port);
|
|
110
|
+
if (!proxy.hostnames.length) {
|
|
111
|
+
proxy.hostnames = selectHostnames([proxy.SERVER.https, proxy.SERVER]);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Whether local or remote...
|
|
116
|
+
if (!proxy.hostnames) {
|
|
117
|
+
proxy.hostnames = ['*'];
|
|
118
|
+
}
|
|
119
|
+
return proxy;
|
|
120
|
+
}));
|
|
121
|
+
return { entries };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// -----------
|
|
125
|
+
|
|
126
|
+
export function scanRoots(DIR, rootFileName, offset = '') {
|
|
127
|
+
return Fs.readdirSync(Path.join(DIR, offset)).reduce((roots, f) => {
|
|
128
|
+
const resource = Path.join(DIR, offset, f);
|
|
129
|
+
if (Fs.statSync(resource).isDirectory()) {
|
|
130
|
+
const $offset = Path.join(offset, f);
|
|
131
|
+
if (Fs.existsSync(Path.join(resource, rootFileName))) {
|
|
132
|
+
return roots.concat($offset.replace(/\\/g, '/'));
|
|
133
|
+
}
|
|
134
|
+
return roots.concat(scanRoots(DIR, rootFileName, $offset));
|
|
135
|
+
}
|
|
136
|
+
return roots;
|
|
137
|
+
}, []);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function scanRouteHandlers(LAYOUT, which, callback, offset, roots = []) {
|
|
141
|
+
const routingDir = LAYOUT[`${which.toUpperCase()}_DIR`];
|
|
142
|
+
const dir = Path.join(routingDir, offset);
|
|
143
|
+
const routeFileEnding = new RegExp(`(?:handler\\.${which}|handler)\\.js$`);
|
|
144
|
+
const dedicatedRouteFileName = `handler.${which}.js`;
|
|
145
|
+
const hasDedicatedRouteFile = Fs.existsSync(Path.join(dir, dedicatedRouteFileName));
|
|
146
|
+
try {
|
|
147
|
+
Fs.readdirSync(dir).forEach((f) => {
|
|
148
|
+
const resource = Path.join(dir, f);
|
|
149
|
+
const fstat = Fs.statSync(resource);
|
|
150
|
+
if (fstat.isDirectory()) {
|
|
151
|
+
const $offset = Path.join(offset, f).replace(/\\/g, '/');
|
|
152
|
+
if (roots.includes($offset)) return;
|
|
153
|
+
scanRouteHandlers(LAYOUT, which, callback, $offset, roots);
|
|
154
|
+
} else {
|
|
155
|
+
if (!routeFileEnding.test(f)
|
|
156
|
+
|| (hasDedicatedRouteFile && f !== dedicatedRouteFileName)) return;
|
|
157
|
+
callback(resource, `/${offset}`, f, fstat);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
} catch(e) {}
|
|
161
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
1
|
import * as config from './config-pi/index.js';
|
|
6
2
|
import * as deployment from './deployment-pi/index.js';
|
|
7
3
|
import * as runtime from './runtime-pi/index.js';
|
|
8
4
|
import * as services from './services-pi/index.js';
|
|
9
|
-
import
|
|
5
|
+
import * as starter from './init-pi/index.js';
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
* @exports
|
|
13
|
-
*/
|
|
7
|
+
export { Context } from './Context.js';
|
|
14
8
|
export {
|
|
15
9
|
config,
|
|
16
10
|
deployment,
|
|
17
11
|
runtime,
|
|
18
12
|
services,
|
|
19
|
-
|
|
13
|
+
starter,
|
|
20
14
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import Fs from 'fs';
|
|
2
|
+
import Fs2 from 'fs/promises';
|
|
3
|
+
import Path from 'path';
|
|
4
|
+
import { exec } from 'child_process';
|
|
5
|
+
import { _toTitle } from '@webqit/util/str/index.js';
|
|
6
|
+
import { readInitConfig } from '../deployment-pi/util.js';
|
|
7
|
+
import { Context } from '../Context.js';
|
|
8
|
+
|
|
9
|
+
export const desc = {
|
|
10
|
+
init: 'Generate a preset Webflo starter app.',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export async function init(projectName = 'my-webflo-app', projectTitle = '', projectDescription = '') {
|
|
14
|
+
const $context = this;
|
|
15
|
+
|
|
16
|
+
if (!($context instanceof Context)) {
|
|
17
|
+
throw new Error(`The "this" context must be a Webflo Context object.`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { flags: FLAGS, logger: LOGGER } = $context;
|
|
21
|
+
const $config = {
|
|
22
|
+
INIT: await readInitConfig($context),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Validate chosen tamplate
|
|
26
|
+
const template = FLAGS.template || $config.INIT.template;
|
|
27
|
+
const templateDir = Path.resolve(new URL(import.meta.url).pathname, '../templates', template);
|
|
28
|
+
if (!Fs.existsSync(templateDir)) {
|
|
29
|
+
LOGGER?.error(LOGGER.style.err(`Error: template "${template}" not found.`));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Validate target dir
|
|
34
|
+
const targetDir = Path.resolve(process.cwd(), projectName);
|
|
35
|
+
if (Fs.existsSync(targetDir)) {
|
|
36
|
+
LOGGER?.error(LOGGER.style.err(`Error: directory ${projectName} already exists.`));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
LOGGER?.log(LOGGER.style.keyword(`> `) + `Initializing your webflo app: "${projectName}" using template "${template}"...\n`);
|
|
41
|
+
|
|
42
|
+
// 1. Create project dir
|
|
43
|
+
await Fs2.mkdir(targetDir, { recursive: true });
|
|
44
|
+
// 2. Copy template files
|
|
45
|
+
await Fs2.cp(templateDir, targetDir, { recursive: true });
|
|
46
|
+
|
|
47
|
+
if (!projectTitle) {
|
|
48
|
+
projectTitle = _toTitle(projectName.replace(/-/g, ' '));
|
|
49
|
+
}
|
|
50
|
+
if (!projectDescription) {
|
|
51
|
+
projectDescription = `${projectTitle} - powered by Webflo`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 3. Customize package.json
|
|
55
|
+
const pkgFile = Path.join(targetDir, 'package.json');
|
|
56
|
+
if (Fs.existsSync(pkgFile)) {
|
|
57
|
+
const pkgData = JSON.parse(await Fs2.readFile(pkgFile, 'utf8'));
|
|
58
|
+
pkgData.name = projectName;
|
|
59
|
+
pkgData.title = projectTitle;
|
|
60
|
+
pkgData.description = projectDescription;
|
|
61
|
+
await Fs2.writeFile(pkgFile, JSON.stringify(pkgData, null, 2));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 4. Customize index.html and manifest.json
|
|
65
|
+
for (const fileName of ['public/index.html', 'public/manifest.json']) {
|
|
66
|
+
const filePath = Path.join(targetDir, fileName);
|
|
67
|
+
if (Fs.existsSync(filePath)) {
|
|
68
|
+
let fileContents = await Fs2.readFile(filePath, 'utf8');
|
|
69
|
+
fileContents = fileContents.replace(/APP_NAME/g, projectName);
|
|
70
|
+
fileContents = fileContents.replace(/APP_TITLE/g, projectTitle);
|
|
71
|
+
fileContents = fileContents.replace(/APP_DESCRIPTION/g, projectDescription);
|
|
72
|
+
await Fs2.writeFile(filePath, fileContents);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 5. Run setup commands
|
|
77
|
+
const comands = [];
|
|
78
|
+
const nextSteps = [];
|
|
79
|
+
if (FLAGS.install ?? $config.INIT.install) {
|
|
80
|
+
comands.push('npm install');
|
|
81
|
+
comands.push('npm run build');
|
|
82
|
+
} else {
|
|
83
|
+
nextSteps.push('npm install');
|
|
84
|
+
}
|
|
85
|
+
if (FLAGS.git ?? $config.INIT.git) {
|
|
86
|
+
comands.push('git init');
|
|
87
|
+
} else {
|
|
88
|
+
nextSteps.push('git init');
|
|
89
|
+
}
|
|
90
|
+
if (comands.length) {
|
|
91
|
+
LOGGER?.log(LOGGER.style.keyword(`> `) + `Running setup commands...`);
|
|
92
|
+
for (const cmd of comands) {
|
|
93
|
+
LOGGER?.log(LOGGER.style.token(`$ `) + cmd);
|
|
94
|
+
await new Promise((resolve, reject) => {
|
|
95
|
+
exec(cmd, { cwd: targetDir }, (error, stdout, stderr) => {
|
|
96
|
+
if (error) {
|
|
97
|
+
LOGGER?.log(LOGGER.style.err(stderr || error.message));
|
|
98
|
+
return reject(error);
|
|
99
|
+
}
|
|
100
|
+
resolve();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 6. Done message
|
|
107
|
+
LOGGER?.log(`\n✔ Successfully created "${projectName}" using template "${template}"`);
|
|
108
|
+
LOGGER?.log(`\nNext steps:`);
|
|
109
|
+
LOGGER?.log(` cd ${projectName}`);
|
|
110
|
+
if (nextSteps.length) {
|
|
111
|
+
LOGGER?.log(` # Additional setup commands:`);
|
|
112
|
+
for (const step of nextSteps) {
|
|
113
|
+
LOGGER?.log(` ${step}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
LOGGER?.log(` npm run dev -- --open\n`);
|
|
117
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "",
|
|
3
|
+
"name": "",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build:html": "oohtml bundle --recursive --outdir=public/assets --auto-embed=app",
|
|
8
|
+
"build:js": "webflo generate::client --recursive --outdir=public/assets --auto-embed",
|
|
9
|
+
"build": "npm run build:html && npm run build:js",
|
|
10
|
+
"dev": "webflo start --dev --build-sensitivity=2",
|
|
11
|
+
"start": "webflo start"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@webqit/webflo": "file:../../webflo"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@webqit/oohtml-cli": "latest"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en-US">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
+
<title render="#text: titleBar || title">APP_TITLE</title>
|
|
8
|
+
<meta name="description" content="APP_DESCRIPTION">
|
|
9
|
+
<meta name="apple-mobile-web-app-title" content="APP_TITLE">
|
|
10
|
+
<meta name="color-scheme" content="dark">
|
|
11
|
+
<meta name="theme-color" content="#313131">
|
|
12
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
13
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
14
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
15
|
+
<link rel="manifest" href="/manifest.json">
|
|
16
|
+
<!--
|
|
17
|
+
<link rel="icon" href="/assets/..." type="image/png">
|
|
18
|
+
<link rel="apple-touch-icon" href="/assets/...">
|
|
19
|
+
-->
|
|
20
|
+
<script crossorigin ssr src="https://unpkg.com/@webqit/oohtml@latest/dist/main.lite.js"></script>
|
|
21
|
+
<template def="app" ssr src="/assets/app.html" by="oohtml-cli"></template>
|
|
22
|
+
<script type="module" src="/assets/app.js" by="webflo"></script>
|
|
23
|
+
<link rel="stylesheet" href="/assets/app.css">
|
|
24
|
+
</head>
|
|
25
|
+
|
|
26
|
+
<body importscontext="/app">
|
|
27
|
+
|
|
28
|
+
<h1>
|
|
29
|
+
<span><?{ data.title }?></span><br>
|
|
30
|
+
<span><?{ data.greeting }?></span>
|
|
31
|
+
</h1>
|
|
32
|
+
|
|
33
|
+
<import ref="#page.html">
|
|
34
|
+
Import will show here...
|
|
35
|
+
</import>
|
|
36
|
+
|
|
37
|
+
</body>
|
|
38
|
+
|
|
39
|
+
</html>
|