@lowdefy/server-dev 4.0.0-alpha.24 → 4.0.0-alpha.27

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.
@@ -13,13 +13,13 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable no-console */
17
16
 
18
17
  import path from 'path';
19
18
 
20
19
  import yargs from 'yargs';
21
20
  import { hideBin } from 'yargs/helpers';
22
21
 
22
+ import createLogger from './utils/createLogger.mjs';
23
23
  import initialBuild from './processes/initialBuild.mjs';
24
24
  import installPlugins from './processes/installPlugins.mjs';
25
25
  import lowdefyBuild from './processes/lowdefyBuild.mjs';
@@ -46,6 +46,7 @@ async function getContext() {
46
46
  config: path.resolve(argv.configDirectory || env.LOWDEFY_DIRECTORY_CONFIG || process.cwd()),
47
47
  server: process.cwd(),
48
48
  },
49
+ logger: createLogger({ level: env.LOWDEFY_LOG_LEVEL }),
49
50
  options: {
50
51
  port: argv.port || env.PORT || 3000,
51
52
  refResolver: argv.refResolver || env.LOWDEFY_BUILD_REF_RESOLVER,
@@ -55,8 +56,6 @@ async function getContext() {
55
56
  argv.watchIgnore || env.LOWDEFY_SERVER_DEV_WATCH_IGNORE
56
57
  ? JSON.parse(env.LOWDEFY_SERVER_DEV_WATCH_IGNORE)
57
58
  : [],
58
- // TODO: read option from env
59
- verbose: argv.verbose || false,
60
59
  },
61
60
  packageManager: argv.packageManager || env.LOWDEFY_PACKAGE_MANAGER || 'npm',
62
61
  version: env.npm_package_version,
@@ -21,15 +21,15 @@ const args = {
21
21
  yarn: ['install'],
22
22
  };
23
23
 
24
- function installPlugins({ packageManager, packageManagerCmd, options }) {
24
+ function installPlugins({ logger, packageManager, packageManagerCmd }) {
25
25
  return async () => {
26
- console.log('Installing plugins...');
26
+ logger.info({ print: 'spin' }, 'Installing plugins...');
27
27
  await spawnProcess({
28
- logger: console,
29
28
  command: packageManagerCmd,
30
29
  args: args[packageManager],
31
- silent: !options.verbose,
30
+ stdOutLineHandler: (line) => logger.debug(line),
32
31
  });
32
+ logger.info({ print: 'log' }, 'Installed plugins.');
33
33
  };
34
34
  }
35
35
 
@@ -17,16 +17,17 @@
17
17
  import build from '@lowdefy/build';
18
18
  import createCustomPluginTypesMap from '../utils/createCustomPluginTypesMap.mjs';
19
19
 
20
- function lowdefyBuild({ directories, options }) {
20
+ function lowdefyBuild({ directories, logger, options }) {
21
21
  return async () => {
22
22
  const customTypesMap = await createCustomPluginTypesMap({ directories });
23
23
  await build({
24
24
  customTypesMap,
25
25
  directories,
26
- logger: console,
26
+ logger,
27
27
  refResolver: options.refResolver,
28
28
  stage: 'dev',
29
29
  });
30
+ logger.info({ print: 'log' }, 'Built config.');
30
31
  };
31
32
  }
32
33
 
@@ -16,15 +16,15 @@
16
16
 
17
17
  import { spawnProcess } from '@lowdefy/node-utils';
18
18
 
19
- function nextBuild({ bin, options }) {
19
+ function nextBuild({ bin, logger }) {
20
20
  return async () => {
21
- console.log('Building app...');
21
+ logger.info({ print: 'spin' }, 'Building app...');
22
22
  await spawnProcess({
23
- logger: console,
24
23
  command: 'node',
25
24
  args: [bin.next, 'build'],
26
- silent: !options.verbose,
25
+ stdOutLineHandler: (line) => logger.debug(line),
27
26
  });
27
+ logger.info({ print: 'log' }, 'Built app.');
28
28
  };
29
29
  }
30
30
 
@@ -14,13 +14,14 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
- import startNextServer from './startNextServer.mjs';
17
+ import startServer from './startServer.mjs';
18
18
 
19
19
  function restartServer(context) {
20
20
  return () => {
21
- context.shutdownServer(); // Is this needed here?
22
- console.log('Restarting server...');
23
- startNextServer(context);
21
+ context.shutdownServer();
22
+ context.logger.info({ print: 'spin' }, 'Restarting server...');
23
+ startServer(context);
24
+ context.logger.info({ print: 'succeed' }, 'Restarted server.');
24
25
  };
25
26
  }
26
27
 
@@ -17,15 +17,15 @@
17
17
  function shutdownServer(context) {
18
18
  return () => {
19
19
  if (context.nextServer) {
20
- // console.log(
21
- // `Existing server ${context.nextServer.pid}, killed: ${context.nextServer.killed}`
22
- // );
20
+ context.logger.debug(
21
+ `Existing next server with pid ${context.nextServer.pid}, killed: ${context.nextServer.killed}`
22
+ );
23
23
  if (!context.nextServer.killed) {
24
- console.log('Shutting down server...');
24
+ context.logger.info({ print: 'spin' }, 'Shutting down server...');
25
25
  context.nextServer.kill();
26
- // console.log(
27
- // `Killed server ${context.nextServer.pid}, killed: ${context.nextServer.killed}`
28
- // );
26
+ context.logger.debug(
27
+ `Killed next server with pid ${context.nextServer.pid}, killed: ${context.nextServer.killed}`
28
+ );
29
29
  }
30
30
  context.nextServer = null;
31
31
  }
@@ -13,19 +13,33 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable no-console */
17
16
 
18
- import startNextServer from './startNextServer.mjs';
17
+ import { spawnProcess } from '@lowdefy/node-utils';
19
18
 
20
- async function startServer(context) {
21
- return new Promise((resolve, reject) => {
22
- try {
23
- startNextServer(context);
24
- } catch (error) {
25
- console.log(error);
26
- reject(error);
27
- }
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);
28
41
  });
42
+ context.nextServer = nextServer;
29
43
  }
30
44
 
31
45
  export default startServer;
package/manager/run.mjs CHANGED
@@ -73,23 +73,34 @@ The run script does the following:
73
73
  pinging the /api/ping route, until it detects a new server has started, and then reloads the window.
74
74
  */
75
75
 
76
- async function run() {
77
- const context = await getContext();
78
- await context.initialBuild();
79
- await context.startWatchers();
76
+ /* TODO:
77
+ Not killing server on errors properly
78
+ when:
79
+ - initial build fails
80
+ */
81
+
82
+ const context = await getContext();
83
+
84
+ try {
80
85
  try {
81
- const serverPromise = startServer(context);
82
- await wait(800);
83
- if (process.env.LOWDEFY_SERVER_DEV_OPEN_BROWSER === 'true') {
84
- // TODO: Wait 1 sec for a ping and don't open if a ping is seen
85
- opener(`http://localhost:${context.options.port}`);
86
- }
87
- await serverPromise;
86
+ await context.initialBuild();
88
87
  } catch (error) {
89
- console.log(error);
90
- context.shutdownServer();
91
- throw error;
88
+ context.logger.error(error);
92
89
  }
93
- }
94
90
 
95
- run();
91
+ // We are not waiting for the startWatchers promise to resolve (all watchers have fired the ready event)
92
+ // because chokidar sometimes doesn't fire this event, and it seems like there isn't an issue with not waiting.
93
+ context.startWatchers();
94
+
95
+ startServer(context);
96
+ await wait(800);
97
+ if (process.env.LOWDEFY_SERVER_DEV_OPEN_BROWSER === 'true') {
98
+ // TODO: Wait 1 sec for a ping and don't open if a ping is seen
99
+ opener(`http://localhost:${context.options.port}`);
100
+ }
101
+ await new Promise(() => {});
102
+ } catch (error) {
103
+ context.logger.error(error);
104
+ context.shutdownServer();
105
+ process.exit();
106
+ }
@@ -13,24 +13,22 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable no-console */
17
16
 
18
17
  import { type } from '@lowdefy/helpers';
19
18
 
20
19
  class BatchChanges {
21
- constructor({ fn, minDelay }) {
20
+ constructor({ context, fn, delay }) {
21
+ this.context = context;
22
22
  this._call = this._call.bind(this);
23
23
  this.args = [];
24
- this.delay = minDelay || 500;
24
+ this.delay = delay || 500;
25
25
  this.fn = fn;
26
- this.minDelay = minDelay || 500;
27
26
  this.repeat = false;
28
27
  this.running = false;
29
28
  }
30
29
 
31
30
  newChange(...args) {
32
31
  this.args.push(args.filter((arg) => type.isString(arg))); // filter for string paths since chokidar also returns an stats object on windows.
33
- this.delay = this.minDelay;
34
32
  this._startTimer();
35
33
  }
36
34
 
@@ -58,10 +56,7 @@ class BatchChanges {
58
56
  }
59
57
  } catch (error) {
60
58
  this.running = false;
61
- console.error(error);
62
- this.delay *= 2;
63
- console.warn(`Retrying in ${this.delay / 1000}s.`);
64
- this._startTimer();
59
+ this.context.logger.error(error?.message ?? error);
65
60
  }
66
61
  }
67
62
  }
@@ -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;
@@ -19,16 +19,17 @@ import BatchChanges from './BatchChanges.mjs';
19
19
 
20
20
  function setupWatcher({
21
21
  callback,
22
+ context,
22
23
  watchDotfiles = false,
23
24
  ignorePaths = [],
24
25
  watchPaths,
25
- minDelay = 500,
26
+ delay = 500,
26
27
  }) {
27
28
  return new Promise((resolve) => {
28
29
  // const { watch = [], watchIgnore = [] } = context.options;
29
30
  // const resolvedWatchPaths = watch.map((pathName) => path.resolve(pathName));
30
31
 
31
- const batchChanges = new BatchChanges({ fn: callback, minDelay });
32
+ const batchChanges = new BatchChanges({ context, fn: callback, delay });
32
33
  const defaultIgnorePaths = watchDotfiles
33
34
  ? []
34
35
  : [
@@ -13,20 +13,20 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable no-console */
17
16
 
18
17
  import path from 'path';
19
18
  import setupWatcher from '../utils/setupWatcher.mjs';
20
19
 
21
20
  function envWatcher(context) {
22
21
  const callback = async () => {
23
- console.warn('.env file changed.');
22
+ context.logger.warn('.env file changed.');
24
23
  context.readDotEnv();
25
24
  await context.lowdefyBuild();
26
25
  context.restartServer();
27
26
  };
28
27
  return setupWatcher({
29
28
  callback,
29
+ context,
30
30
  watchDotfiles: true,
31
31
  watchPaths: [path.join(context.directories.config, '.env')],
32
32
  });
@@ -13,7 +13,6 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable no-console */
17
16
 
18
17
  import getLowdefyVersion from '../utils/getLowdefyVersion.mjs';
19
18
  import setupWatcher from '../utils/setupWatcher.mjs';
@@ -27,7 +26,7 @@ function lowdefyBuildWatcher(context) {
27
26
  const lowdefyVersion = await getLowdefyVersion(context);
28
27
  if (lowdefyVersion !== context.version && lowdefyVersion !== 'local') {
29
28
  context.shutdownServer();
30
- console.warn('Lowdefy version changed. You should restart your development server.');
29
+ context.logger.warn('Lowdefy version changed. You should restart your development server.');
31
30
  process.exit();
32
31
  }
33
32
  }
@@ -37,7 +36,8 @@ function lowdefyBuildWatcher(context) {
37
36
  };
38
37
  return setupWatcher({
39
38
  callback,
40
- ignorePaths: context.options.watchIgnore,
39
+ context,
40
+ ignorePaths: ['**/node_modules/**', ...context.options.watchIgnore],
41
41
  watchPaths: [context.directories.config, ...context.options.watch],
42
42
  });
43
43
  }
@@ -13,7 +13,6 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */
16
- /* eslint-disable no-console */
17
16
 
18
17
  import crypto from 'crypto';
19
18
  import path from 'path';
@@ -76,6 +75,7 @@ async function nextBuildWatcher(context) {
76
75
  );
77
76
 
78
77
  if (!build) {
78
+ context.logger.info({ print: 'succeed' }, 'Reloaded app.');
79
79
  return;
80
80
  }
81
81
 
@@ -89,6 +89,7 @@ async function nextBuildWatcher(context) {
89
89
 
90
90
  return setupWatcher({
91
91
  callback,
92
+ context,
92
93
  watchDotfiles: true,
93
94
  watchPaths: watchedFiles.map((filePath) => path.join(context.directories.server, filePath)),
94
95
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/server-dev",
3
- "version": "4.0.0-alpha.24",
3
+ "version": "4.0.0-alpha.27",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -39,34 +39,36 @@
39
39
  "next": "next"
40
40
  },
41
41
  "dependencies": {
42
- "@lowdefy/actions-core": "4.0.0-alpha.24",
43
- "@lowdefy/api": "4.0.0-alpha.24",
44
- "@lowdefy/blocks-antd": "4.0.0-alpha.24",
45
- "@lowdefy/blocks-basic": "4.0.0-alpha.24",
46
- "@lowdefy/blocks-color-selectors": "4.0.0-alpha.24",
47
- "@lowdefy/blocks-echarts": "4.0.0-alpha.24",
48
- "@lowdefy/blocks-loaders": "4.0.0-alpha.24",
49
- "@lowdefy/blocks-markdown": "4.0.0-alpha.24",
50
- "@lowdefy/build": "4.0.0-alpha.24",
51
- "@lowdefy/client": "4.0.0-alpha.24",
52
- "@lowdefy/connection-axios-http": "4.0.0-alpha.24",
53
- "@lowdefy/engine": "4.0.0-alpha.24",
54
- "@lowdefy/helpers": "4.0.0-alpha.24",
55
- "@lowdefy/layout": "4.0.0-alpha.24",
56
- "@lowdefy/node-utils": "4.0.0-alpha.24",
57
- "@lowdefy/operators-change-case": "4.0.0-alpha.24",
58
- "@lowdefy/operators-diff": "4.0.0-alpha.24",
59
- "@lowdefy/operators-js": "4.0.0-alpha.24",
60
- "@lowdefy/operators-mql": "4.0.0-alpha.24",
61
- "@lowdefy/operators-nunjucks": "4.0.0-alpha.24",
62
- "@lowdefy/operators-uuid": "4.0.0-alpha.24",
63
- "@lowdefy/operators-yaml": "4.0.0-alpha.24",
64
- "@lowdefy/plugin-next-auth": "4.0.0-alpha.24",
42
+ "@lowdefy/actions-core": "4.0.0-alpha.27",
43
+ "@lowdefy/api": "4.0.0-alpha.27",
44
+ "@lowdefy/blocks-antd": "4.0.0-alpha.27",
45
+ "@lowdefy/blocks-basic": "4.0.0-alpha.27",
46
+ "@lowdefy/blocks-color-selectors": "4.0.0-alpha.27",
47
+ "@lowdefy/blocks-echarts": "4.0.0-alpha.27",
48
+ "@lowdefy/blocks-loaders": "4.0.0-alpha.27",
49
+ "@lowdefy/blocks-markdown": "4.0.0-alpha.27",
50
+ "@lowdefy/blocks-qr": "4.0.0-alpha.27",
51
+ "@lowdefy/build": "4.0.0-alpha.27",
52
+ "@lowdefy/client": "4.0.0-alpha.27",
53
+ "@lowdefy/connection-axios-http": "4.0.0-alpha.27",
54
+ "@lowdefy/engine": "4.0.0-alpha.27",
55
+ "@lowdefy/helpers": "4.0.0-alpha.27",
56
+ "@lowdefy/layout": "4.0.0-alpha.27",
57
+ "@lowdefy/node-utils": "4.0.0-alpha.27",
58
+ "@lowdefy/operators-change-case": "4.0.0-alpha.27",
59
+ "@lowdefy/operators-diff": "4.0.0-alpha.27",
60
+ "@lowdefy/operators-js": "4.0.0-alpha.27",
61
+ "@lowdefy/operators-mql": "4.0.0-alpha.27",
62
+ "@lowdefy/operators-nunjucks": "4.0.0-alpha.27",
63
+ "@lowdefy/operators-uuid": "4.0.0-alpha.27",
64
+ "@lowdefy/operators-yaml": "4.0.0-alpha.27",
65
+ "@lowdefy/plugin-next-auth": "4.0.0-alpha.27",
65
66
  "chokidar": "3.5.3",
66
67
  "dotenv": "16.0.1",
67
68
  "next": "12.1.6",
68
69
  "next-auth": "4.10.3",
69
70
  "opener": "1.5.2",
71
+ "pino": "8.1.0",
70
72
  "process": "0.11.10",
71
73
  "react": "18.1.0",
72
74
  "react-dom": "18.1.0",
@@ -84,5 +86,5 @@
84
86
  "publishConfig": {
85
87
  "access": "public"
86
88
  },
87
- "gitHead": "7ae69eeb9a93964e2fb0bf08b7a21bee2636a630"
89
+ "gitHead": "02010edcce0f218c54cdbd08f28a60a08c36edfa"
88
90
  }
@@ -26,15 +26,11 @@ import providers from '../../../build/plugins/auth/providers.js';
26
26
  export const authOptions = getNextAuthConfig(
27
27
  { logger: console }, // TODO: make createApiContext synchronous
28
28
  { authJson, plugins: { adapters, callbacks, events, providers } }
29
- )
29
+ );
30
30
 
31
- export default async function auth({ req, res }) {
31
+ export default async function auth(req, res) {
32
32
  if (authJson.configured === true) {
33
- return await NextAuth(
34
- req,
35
- res,
36
- authOptions
37
- );
33
+ return await NextAuth(req, res, authOptions);
38
34
  }
39
35
 
40
36
  return res.status(404).json({
@@ -1,44 +0,0 @@
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 '../utils/spawnProcess.mjs';
18
-
19
- function startServerProcess(context) {
20
- context.shutdownServer();
21
-
22
- const nextServer = spawnProcess({
23
- logger: console,
24
- command: 'node',
25
- args: [context.bin.next, 'start'],
26
- silent: false,
27
- processOptions: {
28
- env: {
29
- ...process.env,
30
- PORT: context.options.port,
31
- },
32
- },
33
- });
34
- // console.log(`Started server ${nextServer.pid}.`);
35
- // nextServer.on('exit', (code, signal) => {
36
- // console.log(`nextServer exit ${nextServer.pid}, signal: ${signal}, code: ${code}`);
37
- // });
38
- nextServer.on('error', (error) => {
39
- console.log(error);
40
- });
41
- context.nextServer = nextServer;
42
- }
43
-
44
- export default startServerProcess;
@@ -1,55 +0,0 @@
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 { spawn } from 'child_process';
18
-
19
- function spawnProcess({ logger, command, args, processOptions, silent }) {
20
- const process = spawn(command, args, processOptions);
21
-
22
- process.stdout.on('data', (data) => {
23
- if (!silent) {
24
- data
25
- .toString('utf8')
26
- .split('\n')
27
- .forEach((line) => {
28
- if (line) {
29
- logger.log(line);
30
- }
31
- });
32
- }
33
- });
34
-
35
- process.stderr.on('data', (data) => {
36
- if (!silent) {
37
- data
38
- .toString('utf8')
39
- .split('\n')
40
- .forEach((line) => {
41
- if (line) {
42
- logger.warn(line);
43
- }
44
- });
45
- }
46
- });
47
-
48
- process.on('error', (error) => {
49
- throw error;
50
- });
51
-
52
- return process;
53
- }
54
-
55
- export default spawnProcess;