mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-11 14:20:07 +08:00
feat(server-dev): Add .env and lowdefy version watchers.
This commit is contained in:
parent
ad3511cce7
commit
bc522684ab
11
.pnp.cjs
generated
11
.pnp.cjs
generated
@ -5698,6 +5698,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["@lowdefy/operators-yaml", "workspace:packages/plugins/operators/operators-yaml"],
|
||||
["@next/eslint-plugin-next", "npm:12.0.4"],
|
||||
["chokidar", "npm:3.5.2"],
|
||||
["dotenv", "npm:14.2.0"],
|
||||
["js-yaml", "npm:4.1.0"],
|
||||
["less", "npm:4.1.2"],
|
||||
["less-loader", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:10.2.0"],
|
||||
["next", "virtual:003bebd8b7a948d12b44e2c11a621884feb1891eea3645171e827971487f79396db9f7422bc411ccf3f90877e94ec86f5c3da70b96efb5daddb2ee3b35eae5c6#npm:12.0.3"],
|
||||
@ -10534,6 +10536,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["dotenv", [
|
||||
["npm:14.2.0", {
|
||||
"packageLocation": "./.yarn/cache/dotenv-npm-14.2.0-b237345d26-85a0e44918.zip/node_modules/dotenv/",
|
||||
"packageDependencies": [
|
||||
["dotenv", "npm:14.2.0"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["duplexer", [
|
||||
["npm:0.1.2", {
|
||||
"packageLocation": "./.yarn/cache/duplexer-npm-0.1.2-952c810235-62ba61a830.zip/node_modules/duplexer/",
|
||||
|
BIN
.yarn/cache/dotenv-npm-14.2.0-b237345d26-85a0e44918.zip
vendored
Normal file
BIN
.yarn/cache/dotenv-npm-14.2.0-b237345d26-85a0e44918.zip
vendored
Normal file
Binary file not shown.
@ -17,6 +17,7 @@
|
||||
import { spawnProcess } from '@lowdefy/node-utils';
|
||||
|
||||
async function runDevServer({ context }) {
|
||||
// TODO: Pass packageManager as option
|
||||
await spawnProcess({
|
||||
logger: context.print,
|
||||
args: ['run', 'start'],
|
||||
|
@ -62,6 +62,8 @@
|
||||
"@lowdefy/operators-uuid": "4.0.0-alpha.6",
|
||||
"@lowdefy/operators-yaml": "4.0.0-alpha.6",
|
||||
"chokidar": "3.5.2",
|
||||
"dotenv": "14.2.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"next": "12.0.3",
|
||||
"next-auth": "4.0.0-beta.6",
|
||||
"opener": "1.5.2",
|
||||
|
@ -18,13 +18,16 @@
|
||||
import path from 'path';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import { readFile } from '@lowdefy/node-utils';
|
||||
|
||||
import initialBuild from './processes/initialBuild.mjs';
|
||||
import installPlugins from './processes/installPlugins.mjs';
|
||||
import lowdefyBuild from './processes/lowdefyBuild.mjs';
|
||||
import nextBuild from './processes/nextBuild.mjs';
|
||||
import installPlugins from './processes/installPlugins.mjs';
|
||||
import startServerProcess from './processes/startServerProcess.mjs';
|
||||
import readDotEnv from './processes/readDotEnv.mjs';
|
||||
import reloadClients from './processes/reloadClients.mjs';
|
||||
import restartServer from './processes/restartServer.mjs';
|
||||
import shutdownServer from './processes/shutdownServer.mjs';
|
||||
import startWatchers from './processes/startWatchers.mjs';
|
||||
|
||||
const argv = yargs(hideBin(process.argv)).argv;
|
||||
|
||||
@ -39,30 +42,19 @@ async function getContext() {
|
||||
server: process.cwd(),
|
||||
},
|
||||
packageManager,
|
||||
restartServer: () => {
|
||||
if (context.serverProcess) {
|
||||
console.log('Restarting server...');
|
||||
context.serverProcess.kill();
|
||||
startServerProcess(context);
|
||||
}
|
||||
},
|
||||
shutdownServer: () => {
|
||||
if (context.serverProcess) {
|
||||
console.log('Shutting down server...');
|
||||
context.serverProcess.kill();
|
||||
}
|
||||
},
|
||||
verbose,
|
||||
};
|
||||
|
||||
const packageJson = JSON.parse(
|
||||
await readFile(path.join(context.directories.server, 'package.json'))
|
||||
);
|
||||
context.version = packageJson.version;
|
||||
context.version = process.env.npm_package_version;
|
||||
context.initialBuild = initialBuild(context);
|
||||
context.installPlugins = installPlugins(context);
|
||||
context.lowdefyBuild = lowdefyBuild(context);
|
||||
context.nextBuild = nextBuild(context);
|
||||
context.readDotEnv = readDotEnv(context);
|
||||
context.reloadClients = reloadClients(context);
|
||||
context.restartServer = restartServer(context);
|
||||
context.shutdownServer = shutdownServer(context);
|
||||
context.startWatchers = startWatchers(context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -15,10 +15,13 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
async function initialBuild(context) {
|
||||
await context.lowdefyBuild();
|
||||
await context.installPlugins();
|
||||
await context.nextBuild();
|
||||
function initialBuild(context) {
|
||||
return async () => {
|
||||
await context.lowdefyBuild();
|
||||
await context.installPlugins();
|
||||
await context.nextBuild();
|
||||
await context.readDotEnv();
|
||||
};
|
||||
}
|
||||
|
||||
export default initialBuild;
|
||||
|
28
packages/server-dev/src/manager/processes/readDotEnv.mjs
Normal file
28
packages/server-dev/src/manager/processes/readDotEnv.mjs
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import dotenv from 'dotenv';
|
||||
import { readFile } from '@lowdefy/node-utils';
|
||||
|
||||
function readDotEnv(context) {
|
||||
return async () => {
|
||||
const dotEnvPath = path.join(context.directories.config, '.env');
|
||||
context.serverEnv = dotenv.parse(await readFile(dotEnvPath));
|
||||
};
|
||||
}
|
||||
|
||||
export default readDotEnv;
|
29
packages/server-dev/src/manager/processes/restartServer.mjs
Normal file
29
packages/server-dev/src/manager/processes/restartServer.mjs
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import startServerProcess from './startServerProcess.mjs';
|
||||
|
||||
function shutdownServer(context) {
|
||||
return async () => {
|
||||
if (context.serverProcess) {
|
||||
console.log('Restarting server...');
|
||||
context.serverProcess.kill();
|
||||
startServerProcess(context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default shutdownServer;
|
26
packages/server-dev/src/manager/processes/shutdownServer.mjs
Normal file
26
packages/server-dev/src/manager/processes/shutdownServer.mjs
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
function shutdownServer(context) {
|
||||
return async () => {
|
||||
if (context.serverProcess) {
|
||||
console.log('Shutting down server...');
|
||||
context.serverProcess.kill();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default shutdownServer;
|
@ -22,6 +22,12 @@ function startServerProcess(context) {
|
||||
command: context.packageManager,
|
||||
args: ['run', 'next', 'start'],
|
||||
silent: false,
|
||||
processOptions: {
|
||||
env: {
|
||||
...process.env,
|
||||
...context.serverEnv,
|
||||
},
|
||||
},
|
||||
});
|
||||
context.serverProcess.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
|
@ -14,8 +14,8 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import configWatcher from './watchers/configWatcher.mjs';
|
||||
import envWatcher from './watchers/envWatcher.mjs';
|
||||
import configWatcher from '../watchers/configWatcher.mjs';
|
||||
import envWatcher from '../watchers/envWatcher.mjs';
|
||||
|
||||
/*
|
||||
Config change
|
||||
@ -31,7 +31,6 @@ Watch <server>/package.json
|
||||
- No need for Lowdefy build (confirm?)
|
||||
- Trigger hard reload
|
||||
- Restart server.
|
||||
|
||||
----------------------------------------
|
||||
.env change
|
||||
Watch <config-dir>/.env
|
||||
@ -48,7 +47,6 @@ Watch <server-dir>/build/config.json
|
||||
- Next build.
|
||||
- Trigger hard reload
|
||||
- Restart server.
|
||||
|
||||
----------------------------------------
|
||||
New plugin or icon used.
|
||||
Watch <server-dir>/build/plugins/*
|
||||
@ -57,8 +55,10 @@ Watch <server-dir>/build/plugins/*
|
||||
- Restart server.
|
||||
*/
|
||||
|
||||
async function startWatchers(context) {
|
||||
await Promise.all([configWatcher(context), envWatcher(context)]);
|
||||
function startWatchers(context) {
|
||||
return async () => {
|
||||
await Promise.all([configWatcher(context), envWatcher(context)]);
|
||||
};
|
||||
}
|
||||
|
||||
export default startWatchers;
|
@ -18,14 +18,12 @@
|
||||
import { wait } from '@lowdefy/helpers';
|
||||
import opener from 'opener';
|
||||
import getContext from './getContext.mjs';
|
||||
import initialBuild from './processes/initialBuild.mjs';
|
||||
import startServer from './processes/startServer.mjs';
|
||||
import startWatchers from './startWatchers.mjs';
|
||||
|
||||
async function run() {
|
||||
const context = await getContext();
|
||||
await initialBuild(context);
|
||||
await startWatchers(context);
|
||||
await context.initialBuild();
|
||||
await context.startWatchers();
|
||||
try {
|
||||
const serverPromise = startServer(context);
|
||||
await wait(800);
|
||||
|
51
packages/server-dev/src/manager/utils/getLowdefyVersion.mjs
Normal file
51
packages/server-dev/src/manager/utils/getLowdefyVersion.mjs
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2020-2021 Lowdefy, Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import { type } from '@lowdefy/helpers';
|
||||
import { readFile } from '@lowdefy/node-utils';
|
||||
import YAML from 'js-yaml';
|
||||
|
||||
async function getLowdefyVersion(context) {
|
||||
let lowdefyYaml = await readFile(path.join(context.directories.config, 'lowdefy.yaml'));
|
||||
if (!lowdefyYaml) {
|
||||
lowdefyYaml = await readFile(path.join(context.directories.config, 'lowdefy.yml'));
|
||||
}
|
||||
if (!lowdefyYaml) {
|
||||
throw new Error(`Could not find "lowdefy.yaml" file.`);
|
||||
}
|
||||
let lowdefy;
|
||||
try {
|
||||
lowdefy = YAML.load(lowdefyYaml);
|
||||
} catch (error) {
|
||||
throw new Error(`Could not parse "lowdefy.yaml" file. Received error ${error.message}.`);
|
||||
}
|
||||
if (!lowdefy.lowdefy) {
|
||||
throw new Error(
|
||||
`No version specified in "lowdefy.yaml" file. Specify a version in the "lowdefy" field.`
|
||||
);
|
||||
}
|
||||
if (!type.isString(lowdefy.lowdefy)) {
|
||||
throw new Error(
|
||||
`Version number specified in "lowdefy.yaml" file should be a string. Received ${JSON.stringify(
|
||||
lowdefy.lowdefy
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
return lowdefy.lowdefy;
|
||||
}
|
||||
|
||||
export default getLowdefyVersion;
|
@ -17,12 +17,18 @@
|
||||
import chokidar from 'chokidar';
|
||||
import BatchChanges from './BatchChanges.mjs';
|
||||
|
||||
function setupWatcher({ callback, watchDotfiles = false, ignorePaths = [], watchPaths }) {
|
||||
function setupWatcher({
|
||||
callback,
|
||||
watchDotfiles = false,
|
||||
ignorePaths = [],
|
||||
watchPaths,
|
||||
minDelay = 500,
|
||||
}) {
|
||||
return new Promise((resolve) => {
|
||||
// const { watch = [], watchIgnore = [] } = context.options;
|
||||
// const resolvedWatchPaths = watch.map((pathName) => path.resolve(pathName));
|
||||
|
||||
const batchChanges = new BatchChanges({ fn: callback, minDelay: 4000 });
|
||||
const batchChanges = new BatchChanges({ fn: callback, minDelay });
|
||||
const defaultIgnorePaths = watchDotfiles
|
||||
? []
|
||||
: [
|
||||
|
@ -13,12 +13,24 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import getLowdefyVersion from '../utils/getLowdefyVersion.mjs';
|
||||
import setupWatcher from '../utils/setupWatcher.mjs';
|
||||
|
||||
async function configWatcher(context) {
|
||||
const callback = async (...args) => {
|
||||
console.log('args', args);
|
||||
const callback = async (filePaths) => {
|
||||
const lowdefyYamlModified = filePaths
|
||||
.flat()
|
||||
.some((filePath) => filePath.includes('lowdefy.yaml') || filePath.includes('lowdefy.yml'));
|
||||
if (lowdefyYamlModified) {
|
||||
const lowdefyVersion = await getLowdefyVersion(context);
|
||||
if (lowdefyVersion !== context.version) {
|
||||
console.warn('Lowdefy version changed. You should restart your development server.');
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
||||
await context.lowdefyBuild();
|
||||
context.reloadClients();
|
||||
};
|
||||
|
@ -13,8 +13,7 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import dotenv from 'dotenv';
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import path from 'path';
|
||||
import setupWatcher from '../utils/setupWatcher.mjs';
|
||||
@ -22,6 +21,7 @@ import setupWatcher from '../utils/setupWatcher.mjs';
|
||||
async function envWatcher(context) {
|
||||
const callback = async () => {
|
||||
console.warn('.env file changed.');
|
||||
await context.readDotEnv();
|
||||
context.restartServer();
|
||||
};
|
||||
return setupWatcher({
|
||||
|
@ -3917,6 +3917,8 @@ __metadata:
|
||||
"@lowdefy/operators-yaml": 4.0.0-alpha.6
|
||||
"@next/eslint-plugin-next": 12.0.4
|
||||
chokidar: 3.5.2
|
||||
dotenv: 14.2.0
|
||||
js-yaml: 4.1.0
|
||||
less: 4.1.2
|
||||
less-loader: 10.2.0
|
||||
next: 12.0.3
|
||||
@ -7943,6 +7945,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dotenv@npm:14.2.0":
|
||||
version: 14.2.0
|
||||
resolution: "dotenv@npm:14.2.0"
|
||||
checksum: 85a0e44918ef49e64c278f757dab50a156b9a6ca67f708876fd81d265e575e35b67387fc681d910df99368d6c1edca66cd546edeb0f7db3b499cb876c999233e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"duplexer@npm:^0.1.1":
|
||||
version: 0.1.2
|
||||
resolution: "duplexer@npm:0.1.2"
|
||||
|
Loading…
Reference in New Issue
Block a user