@lowdefy/server-dev 4.0.0-alpha.9 → 4.0.0-rc.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/.npmrc +1 -0
- package/lib/App.js +67 -0
- package/lib/Page.js +50 -0
- package/lib/Reload.js +52 -0
- package/lib/RestartingPage.js +47 -0
- package/lib/auth/Auth.js +35 -0
- package/lib/auth/AuthConfigured.js +47 -0
- package/lib/auth/AuthNotConfigured.js +32 -0
- package/lib/auth/getServerSession.js +28 -0
- package/lib/fileCache.js +20 -0
- package/lib/setPageId.js +30 -0
- package/lib/utils/request.js +38 -0
- package/lib/utils/useMutateCache.js +34 -0
- package/lib/utils/usePageConfig.js +27 -0
- package/lib/utils/useRootConfig.js +26 -0
- package/lib/utils/waitForRestartedServer.js +38 -0
- package/manager/getContext.mjs +77 -0
- package/manager/processes/initialBuild.mjs +27 -0
- package/manager/processes/installPlugins.mjs +31 -0
- package/manager/processes/lowdefyBuild.mjs +34 -0
- package/manager/processes/nextBuild.mjs +31 -0
- package/manager/processes/readDotEnv.mjs +26 -0
- package/manager/processes/reloadClients.mjs +26 -0
- package/manager/processes/restartServer.mjs +28 -0
- package/manager/processes/shutdownServer.mjs +35 -0
- package/manager/processes/startServer.mjs +45 -0
- package/manager/processes/startWatchers.mjs +31 -0
- package/manager/run.mjs +109 -0
- package/manager/utils/BatchChanges.mjs +64 -0
- package/manager/utils/createCustomPluginTypesMap.mjs +72 -0
- package/manager/utils/createLogger.mjs +34 -0
- package/manager/utils/getLowdefyVersion.mjs +51 -0
- package/manager/utils/getNextBin.mjs +36 -0
- package/manager/utils/setupWatcher.mjs +50 -0
- package/manager/watchers/envWatcher.mjs +35 -0
- package/manager/watchers/lowdefyBuildWatcher.mjs +55 -0
- package/manager/watchers/nextBuildWatcher.mjs +99 -0
- package/next.config.js +2 -7
- package/package.json +46 -37
- package/pages/404.js +19 -0
- package/pages/[pageId].js +19 -0
- package/pages/_app.js +37 -0
- package/pages/_document.js +50 -0
- package/pages/api/auth/[...nextauth].js +45 -0
- package/pages/api/page/[pageId].js +40 -0
- package/pages/api/ping.js +19 -0
- package/pages/api/reload.js +50 -0
- package/pages/api/request/[pageId]/[requestId].js +50 -0
- package/pages/api/root.js +35 -0
- package/pages/index.js +19 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
function initialBuild(context) {
|
|
19
|
+
return async () => {
|
|
20
|
+
context.readDotEnv();
|
|
21
|
+
await context.lowdefyBuild();
|
|
22
|
+
await context.installPlugins();
|
|
23
|
+
await context.nextBuild();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default initialBuild;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { spawnProcess } from '@lowdefy/node-utils';
|
|
18
|
+
|
|
19
|
+
function installPlugins({ logger, packageManagerCmd }) {
|
|
20
|
+
return async () => {
|
|
21
|
+
logger.info({ print: 'spin' }, 'Installing plugins...');
|
|
22
|
+
await spawnProcess({
|
|
23
|
+
command: packageManagerCmd,
|
|
24
|
+
args: ['install', '--no-frozen-lockfile'],
|
|
25
|
+
stdOutLineHandler: (line) => logger.debug(line),
|
|
26
|
+
});
|
|
27
|
+
logger.info({ print: 'log' }, 'Installed plugins.');
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default installPlugins;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import build from '@lowdefy/build';
|
|
18
|
+
import createCustomPluginTypesMap from '../utils/createCustomPluginTypesMap.mjs';
|
|
19
|
+
|
|
20
|
+
function lowdefyBuild({ directories, logger, options }) {
|
|
21
|
+
return async () => {
|
|
22
|
+
const customTypesMap = await createCustomPluginTypesMap({ directories });
|
|
23
|
+
await build({
|
|
24
|
+
customTypesMap,
|
|
25
|
+
directories,
|
|
26
|
+
logger,
|
|
27
|
+
refResolver: options.refResolver,
|
|
28
|
+
stage: 'dev',
|
|
29
|
+
});
|
|
30
|
+
logger.info({ print: 'log' }, 'Built config.');
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default lowdefyBuild;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { spawnProcess } from '@lowdefy/node-utils';
|
|
18
|
+
|
|
19
|
+
function nextBuild({ bin, logger }) {
|
|
20
|
+
return async () => {
|
|
21
|
+
logger.info({ print: 'spin' }, 'Building app...');
|
|
22
|
+
await spawnProcess({
|
|
23
|
+
command: 'node',
|
|
24
|
+
args: [bin.next, 'build'],
|
|
25
|
+
stdOutLineHandler: (line) => logger.debug(line),
|
|
26
|
+
});
|
|
27
|
+
logger.info({ print: 'log' }, 'Built app.');
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default nextBuild;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import dotenv from 'dotenv';
|
|
19
|
+
|
|
20
|
+
function readDotEnv(context) {
|
|
21
|
+
return () => {
|
|
22
|
+
dotenv.config({ path: path.join(context.directories.config, '.env'), silent: true });
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default readDotEnv;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { writeFile } from '@lowdefy/node-utils';
|
|
19
|
+
|
|
20
|
+
function reloadClients({ directories }) {
|
|
21
|
+
return async () => {
|
|
22
|
+
await writeFile(path.join(directories.build, 'reload'), `${Date.now()}`);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default reloadClients;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import startServer from './startServer.mjs';
|
|
18
|
+
|
|
19
|
+
function restartServer(context) {
|
|
20
|
+
return () => {
|
|
21
|
+
context.shutdownServer();
|
|
22
|
+
context.logger.info({ print: 'spin' }, 'Restarting server...');
|
|
23
|
+
startServer(context);
|
|
24
|
+
context.logger.info({ print: 'succeed' }, 'Restarted server.');
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default restartServer;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
function shutdownServer(context) {
|
|
18
|
+
return () => {
|
|
19
|
+
if (context.nextServer) {
|
|
20
|
+
context.logger.debug(
|
|
21
|
+
`Existing next server with pid ${context.nextServer.pid}, killed: ${context.nextServer.killed}`
|
|
22
|
+
);
|
|
23
|
+
if (!context.nextServer.killed) {
|
|
24
|
+
context.logger.info({ print: 'spin' }, 'Shutting down server...');
|
|
25
|
+
context.nextServer.kill();
|
|
26
|
+
context.logger.debug(
|
|
27
|
+
`Killed next server with pid ${context.nextServer.pid}, killed: ${context.nextServer.killed}`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
context.nextServer = null;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default shutdownServer;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { spawnProcess } from '@lowdefy/node-utils';
|
|
18
|
+
|
|
19
|
+
function startServer(context) {
|
|
20
|
+
context.shutdownServer();
|
|
21
|
+
|
|
22
|
+
const nextServer = spawnProcess({
|
|
23
|
+
stdOutLineHandler: (line) => context.logger.info({ print: 'log' }, line),
|
|
24
|
+
stdErrLineHandler: (line) => context.logger.error(line),
|
|
25
|
+
command: 'node',
|
|
26
|
+
args: [context.bin.next, 'start'],
|
|
27
|
+
processOptions: {
|
|
28
|
+
env: {
|
|
29
|
+
...process.env,
|
|
30
|
+
PORT: context.options.port,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
returnProcess: true,
|
|
34
|
+
});
|
|
35
|
+
context.logger.debug(`Started next server with pid ${nextServer.pid}.`);
|
|
36
|
+
nextServer.on('exit', (code, signal) => {
|
|
37
|
+
context.logger.debug(`nextServer exit ${nextServer.pid}, signal: ${signal}, code: ${code}`);
|
|
38
|
+
});
|
|
39
|
+
nextServer.on('error', (error) => {
|
|
40
|
+
context.logger.error(error);
|
|
41
|
+
});
|
|
42
|
+
context.nextServer = nextServer;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default startServer;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import envWatcher from '../watchers/envWatcher.mjs';
|
|
18
|
+
import lowdefyBuildWatcher from '../watchers/lowdefyBuildWatcher.mjs';
|
|
19
|
+
import nextBuildWatcher from '../watchers/nextBuildWatcher.mjs';
|
|
20
|
+
|
|
21
|
+
function startWatchers(context) {
|
|
22
|
+
return async () => {
|
|
23
|
+
await Promise.all([
|
|
24
|
+
envWatcher(context),
|
|
25
|
+
lowdefyBuildWatcher(context),
|
|
26
|
+
nextBuildWatcher(context),
|
|
27
|
+
]);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default startWatchers;
|
package/manager/run.mjs
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { wait } from '@lowdefy/helpers';
|
|
19
|
+
import opener from 'opener';
|
|
20
|
+
import getContext from './getContext.mjs';
|
|
21
|
+
import startServer from './processes/startServer.mjs';
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
The run script does the following:
|
|
25
|
+
- Run the initial Lowdefy build, install plugins, and next build and read .env
|
|
26
|
+
- Start file watchers to reload config and restart server if necessary
|
|
27
|
+
- Start the server
|
|
28
|
+
- Open a browser window.
|
|
29
|
+
|
|
30
|
+
Three watchers are started:
|
|
31
|
+
|
|
32
|
+
## Lowdefy build watcher
|
|
33
|
+
Watches:
|
|
34
|
+
- <config-dir>,
|
|
35
|
+
- <watch-dirs>
|
|
36
|
+
- !<ignore-dirs>
|
|
37
|
+
The Lowdefy build watcher watches the Lowdefy config files for changes
|
|
38
|
+
and runs Lowdefy build when they change, and triggers a soft reload.
|
|
39
|
+
|
|
40
|
+
If lowdefy version in lowdefy.yaml
|
|
41
|
+
is changed, the server warns and exits.
|
|
42
|
+
|
|
43
|
+
## .env watcher
|
|
44
|
+
|
|
45
|
+
If the .env file is changed, the new file is parsed, and the server restarted with the new env
|
|
46
|
+
and the server hard reloads.
|
|
47
|
+
|
|
48
|
+
## Next build watcher
|
|
49
|
+
|
|
50
|
+
The Next build watcher watches for any files where the app should be rebuilt and restarted.
|
|
51
|
+
It watches:
|
|
52
|
+
- <build-dir>/plugins/**
|
|
53
|
+
- <build-dir>/config.json
|
|
54
|
+
- <server-dir>/package.json
|
|
55
|
+
|
|
56
|
+
If app config changes:
|
|
57
|
+
- <build-dir>/config.json changes, rebuild and restart server.
|
|
58
|
+
|
|
59
|
+
If user styles change:
|
|
60
|
+
- <public-dir>/styles.less changes, rebuild and restart server.
|
|
61
|
+
|
|
62
|
+
If new plugin type in an existing plugin package is used:
|
|
63
|
+
- <build-dir>/plugins/** changes, rebuild next and restart server.
|
|
64
|
+
|
|
65
|
+
If new plugin type in a new plugin package is used:
|
|
66
|
+
- <server-dir>/package.json changes, run npm install, rebuild next and restart server.
|
|
67
|
+
|
|
68
|
+
# Reload mechanism
|
|
69
|
+
|
|
70
|
+
The web client creates a Server Sent Events connection with the server on the /api/reload route.
|
|
71
|
+
The server watches the <build-dir>/reload file, which is written every time the server should reload,
|
|
72
|
+
and sends an event to the client to reload the config. The client then uses a SWR cache mutation to
|
|
73
|
+
fetch the new config.
|
|
74
|
+
|
|
75
|
+
If the server is restarted, the event stream is closed because the original server was shut down. The client starts
|
|
76
|
+
pinging the /api/ping route, until it detects a new server has started, and then reloads the window.
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/* TODO:
|
|
80
|
+
Not killing server on errors properly
|
|
81
|
+
when:
|
|
82
|
+
- initial build fails
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
const context = await getContext();
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
try {
|
|
89
|
+
await context.initialBuild();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
context.logger.error(error);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// We are not waiting for the startWatchers promise to resolve (all watchers have fired the ready event)
|
|
95
|
+
// because chokidar sometimes doesn't fire this event, and it seems like there isn't an issue with not waiting.
|
|
96
|
+
context.startWatchers();
|
|
97
|
+
|
|
98
|
+
startServer(context);
|
|
99
|
+
await wait(800);
|
|
100
|
+
if (process.env.LOWDEFY_SERVER_DEV_OPEN_BROWSER === 'true') {
|
|
101
|
+
// TODO: Wait 1 sec for a ping and don't open if a ping is seen
|
|
102
|
+
opener(`http://localhost:${context.options.port}`);
|
|
103
|
+
}
|
|
104
|
+
await new Promise(() => {});
|
|
105
|
+
} catch (error) {
|
|
106
|
+
context.logger.error(error);
|
|
107
|
+
context.shutdownServer();
|
|
108
|
+
process.exit();
|
|
109
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
class BatchChanges {
|
|
20
|
+
constructor({ context, fn, delay }) {
|
|
21
|
+
this.context = context;
|
|
22
|
+
this._call = this._call.bind(this);
|
|
23
|
+
this.args = [];
|
|
24
|
+
this.delay = delay || 500;
|
|
25
|
+
this.fn = fn;
|
|
26
|
+
this.repeat = false;
|
|
27
|
+
this.running = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
newChange(...args) {
|
|
31
|
+
this.args.push(args.filter((arg) => type.isString(arg))); // filter for string paths since chokidar also returns an stats object on windows.
|
|
32
|
+
this._startTimer();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
_startTimer() {
|
|
36
|
+
if (this.timer) {
|
|
37
|
+
clearTimeout(this.timer);
|
|
38
|
+
}
|
|
39
|
+
if (this.running) {
|
|
40
|
+
this.repeat = true;
|
|
41
|
+
} else {
|
|
42
|
+
this.timer = setTimeout(this._call, this.delay);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async _call() {
|
|
47
|
+
this.running = true;
|
|
48
|
+
try {
|
|
49
|
+
const args = this.args;
|
|
50
|
+
this.args = [];
|
|
51
|
+
await this.fn(args);
|
|
52
|
+
this.running = false;
|
|
53
|
+
if (this.repeat) {
|
|
54
|
+
this.repeat = false;
|
|
55
|
+
this._call();
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
this.running = false;
|
|
59
|
+
this.context.logger.error(error?.message ?? error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default BatchChanges;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import { get } from '@lowdefy/helpers';
|
|
20
|
+
import { readFile } from '@lowdefy/node-utils';
|
|
21
|
+
import { createPluginTypesMap } from '@lowdefy/build';
|
|
22
|
+
import YAML from 'yaml';
|
|
23
|
+
|
|
24
|
+
async function getPluginDefinitions({ directories }) {
|
|
25
|
+
let lowdefyYaml = await readFile(path.join(directories.config, 'lowdefy.yaml'));
|
|
26
|
+
if (!lowdefyYaml) {
|
|
27
|
+
lowdefyYaml = await readFile(path.join(directories.config, 'lowdefy.yml'));
|
|
28
|
+
}
|
|
29
|
+
const lowdefy = YAML.parse(lowdefyYaml);
|
|
30
|
+
return get(lowdefy, 'plugins', { default: [] });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function createCustomPluginTypesMap({ directories }) {
|
|
34
|
+
const customTypesMap = {
|
|
35
|
+
actions: {},
|
|
36
|
+
auth: {
|
|
37
|
+
adapters: {},
|
|
38
|
+
callbacks: {},
|
|
39
|
+
events: {},
|
|
40
|
+
providers: {},
|
|
41
|
+
},
|
|
42
|
+
blocks: {},
|
|
43
|
+
connections: {},
|
|
44
|
+
icons: {},
|
|
45
|
+
operators: {
|
|
46
|
+
client: {},
|
|
47
|
+
server: {},
|
|
48
|
+
},
|
|
49
|
+
requests: {},
|
|
50
|
+
styles: {
|
|
51
|
+
packages: {},
|
|
52
|
+
blocks: {},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const pluginDefinitions = await getPluginDefinitions({ directories });
|
|
57
|
+
|
|
58
|
+
for (const plugin of pluginDefinitions) {
|
|
59
|
+
const { default: types } = await import(`${plugin.name}/types`);
|
|
60
|
+
createPluginTypesMap({
|
|
61
|
+
packageTypes: types,
|
|
62
|
+
typesMap: customTypesMap,
|
|
63
|
+
packageName: plugin.name,
|
|
64
|
+
version: plugin.version,
|
|
65
|
+
typePrefix: plugin.typePrefix,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return customTypesMap;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default createCustomPluginTypesMap;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import pino from 'pino';
|
|
17
|
+
|
|
18
|
+
function createLogger({ level = 'info' }) {
|
|
19
|
+
const logger = pino({
|
|
20
|
+
name: 'lowdefy build',
|
|
21
|
+
level,
|
|
22
|
+
base: { pid: undefined, hostname: undefined },
|
|
23
|
+
// TODO: Add log as custom level
|
|
24
|
+
mixin: (context, level) => {
|
|
25
|
+
return {
|
|
26
|
+
...context,
|
|
27
|
+
print: context.print ?? logger.levels.labels[level],
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
return logger;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default createLogger;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2022 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { type } from '@lowdefy/helpers';
|
|
19
|
+
import { readFile } from '@lowdefy/node-utils';
|
|
20
|
+
import YAML from 'yaml';
|
|
21
|
+
|
|
22
|
+
async function getLowdefyVersion(context) {
|
|
23
|
+
let lowdefyYaml = await readFile(path.join(context.directories.config, 'lowdefy.yaml'));
|
|
24
|
+
if (!lowdefyYaml) {
|
|
25
|
+
lowdefyYaml = await readFile(path.join(context.directories.config, 'lowdefy.yml'));
|
|
26
|
+
}
|
|
27
|
+
if (!lowdefyYaml) {
|
|
28
|
+
throw new Error(`Could not find "lowdefy.yaml" file.`);
|
|
29
|
+
}
|
|
30
|
+
let lowdefy;
|
|
31
|
+
try {
|
|
32
|
+
lowdefy = YAML.parse(lowdefyYaml);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw new Error(`Could not parse "lowdefy.yaml" file. Received error ${error.message}.`);
|
|
35
|
+
}
|
|
36
|
+
if (!lowdefy.lowdefy) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`No version specified in "lowdefy.yaml" file. Specify a version in the "lowdefy" field.`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
if (!type.isString(lowdefy.lowdefy)) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Version number specified in "lowdefy.yaml" file should be a string. Received ${JSON.stringify(
|
|
44
|
+
lowdefy.lowdefy
|
|
45
|
+
)}.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
return lowdefy.lowdefy;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default getLowdefyVersion;
|