From 09f7bca3a29ff186783197692e988cb315ff7483 Mon Sep 17 00:00:00 2001 From: Sam Tolmay Date: Fri, 26 Nov 2021 11:44:56 +0200 Subject: [PATCH] feat: Update server package.json if plugin deps change. Closes #943 --- .pnp.cjs | 2 - .../buildRefs/getUserJavascriptFunction.js | 2 +- .../build/src/build/cleanBuildDirectory.js | 2 +- .../src/build/cleanBuildDirectory.test.js | 4 +- .../src/build/updateServerPackageJson.js | 59 +++++++++++++++++++ packages/build/src/index.js | 14 ++--- packages/build/src/scripts/run.js | 9 +-- packages/build/src/test/testContext.js | 4 +- .../build/src/utils/files/readConfigFile.js | 4 +- .../src/utils/files/readConfigFile.test.js | 12 ++-- .../src/utils/files/writeBuildArtifact.js | 4 +- .../utils/files/writeBuildArtifact.test.js | 6 +- .../cli/src/commands/build/runLowdefyBuild.js | 1 + packages/server/package.json | 4 -- yarn.lock | 2 - 15 files changed, 92 insertions(+), 37 deletions(-) create mode 100644 packages/build/src/build/updateServerPackageJson.js diff --git a/.pnp.cjs b/.pnp.cjs index 809291a86..2b412401d 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -5468,9 +5468,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@lowdefy/api", "workspace:packages/api"], ["@lowdefy/block-utils", "workspace:packages/utils/block-utils"], ["@lowdefy/blocks-antd", "workspace:packages/plugins/blocks/blocks-antd"], - ["@lowdefy/blocks-basic", "workspace:packages/plugins/blocks/blocks-basic"], ["@lowdefy/build", "workspace:packages/build"], - ["@lowdefy/connection-axios-http", "workspace:packages/plugins/connections/connection-axios-http"], ["@lowdefy/engine", "workspace:packages/engine"], ["@lowdefy/helpers", "workspace:packages/utils/helpers"], ["@lowdefy/layout", "workspace:packages/layout"], diff --git a/packages/build/src/build/buildRefs/getUserJavascriptFunction.js b/packages/build/src/build/buildRefs/getUserJavascriptFunction.js index 870663de9..d57eb43b0 100644 --- a/packages/build/src/build/buildRefs/getUserJavascriptFunction.js +++ b/packages/build/src/build/buildRefs/getUserJavascriptFunction.js @@ -17,7 +17,7 @@ import path from 'path'; import { readFile } from '@lowdefy/node-utils'; async function getUserJavascriptFunction({ context, filePath }) { - const jsFile = await readFile(path.resolve(context.configDirectory, filePath)); + const jsFile = await readFile(path.resolve(context.directories.config, filePath)); return eval(jsFile); } diff --git a/packages/build/src/build/cleanBuildDirectory.js b/packages/build/src/build/cleanBuildDirectory.js index 45f01f45d..25ca99136 100644 --- a/packages/build/src/build/cleanBuildDirectory.js +++ b/packages/build/src/build/cleanBuildDirectory.js @@ -17,7 +17,7 @@ import { cleanDirectory } from '@lowdefy/node-utils'; async function cleanBuildDirectory({ context }) { - return cleanDirectory(context.buildDirectory); + return cleanDirectory(context.directories.build); } export default cleanBuildDirectory; diff --git a/packages/build/src/build/cleanBuildDirectory.test.js b/packages/build/src/build/cleanBuildDirectory.test.js index 4132cb8bc..0f4495977 100644 --- a/packages/build/src/build/cleanBuildDirectory.test.js +++ b/packages/build/src/build/cleanBuildDirectory.test.js @@ -24,7 +24,9 @@ test('cleanOutputDirectory calls cleanDirectory', async () => { const nodeUtils = await import('@lowdefy/node-utils'); const cleanBuildDirectory = await import('./cleanBuildDirectory.js'); const context = { - buildDirectory: 'buildDirectory', + directories: { + build: 'buildDirectory', + }, }; await cleanBuildDirectory.default({ context }); expect(nodeUtils.cleanDirectory.mock.calls).toEqual([['buildDirectory']]); diff --git a/packages/build/src/build/updateServerPackageJson.js b/packages/build/src/build/updateServerPackageJson.js new file mode 100644 index 000000000..d33f7d708 --- /dev/null +++ b/packages/build/src/build/updateServerPackageJson.js @@ -0,0 +1,59 @@ +/* + 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 { readFile, writeFile } from '@lowdefy/node-utils'; + +async function updateServerPackageJson({ components, context }) { + const filePath = path.join(context.directories.server, 'package.json'); + const packageJsonContent = await readFile(filePath); + const packageJson = JSON.parse(packageJsonContent); + + const dependencies = packageJson.dependencies; + function getPackages(types) { + Object.values(types).forEach((type) => { + dependencies[type.package] = type.version; + }); + } + getPackages(components.types.actions); + getPackages(components.types.blocks); + getPackages(components.types.connections); + getPackages(components.types.requests); + getPackages(components.types.operators.client); + getPackages(components.types.operators.server); + + // Sort dependencies + packageJson.dependencies = {}; + Object.keys(dependencies) + .sort() + .forEach((name) => { + packageJson.dependencies[name] = dependencies[name]; + }); + + const newPackageJsonContent = JSON.stringify(packageJson, null, 2); + + // Only write package.json if it has changed since dev server will + // be watching the file to trigger reinstalls + if (newPackageJsonContent !== packageJsonContent) { + context.logger.warn('Plugin dependencies have changed. Updating "package.json".'); + await writeFile({ + filePath, + content: newPackageJsonContent, + }); + } +} + +export default updateServerPackageJson; diff --git a/packages/build/src/index.js b/packages/build/src/index.js index ae261034c..f0a3b1bd8 100644 --- a/packages/build/src/index.js +++ b/packages/build/src/index.js @@ -35,6 +35,7 @@ import cleanBuildDirectory from './build/cleanBuildDirectory.js'; import testSchema from './build/testSchema.js'; import validateApp from './build/validateApp.js'; import validateConfig from './build/validateConfig.js'; +import updateServerPackageJson from './build/updateServerPackageJson.js'; import writeApp from './build/writeApp.js'; import writeBlockImports from './build/writePluginImports/writeBlockImports.js'; import writeConfig from './build/writeConfig.js'; @@ -49,8 +50,7 @@ import writeStyleImports from './build/writePluginImports/writeStyleImports.js'; import writeTypes from './build/writeTypes.js'; async function createContext(options) { - const { blocksServerUrl, buildDirectory, cacheDirectory, configDirectory, logger, refResolver } = - options; + const { blocksServerUrl, directories, logger, refResolver } = options; const defaultTypes = JSON.parse( await readFile(new URL('./defaultTypes.json', import.meta.url).pathname) @@ -60,9 +60,7 @@ async function createContext(options) { const context = { blocksServerUrl, - buildDirectory, - cacheDirectory, - configDirectory, + directories, typeCounters: { actions: createCounter(), blocks: createCounter(), @@ -74,10 +72,10 @@ async function createContext(options) { }, }, logger, - readConfigFile: createReadConfigFile({ configDirectory }), + readConfigFile: createReadConfigFile({ directories }), refResolver, types: defaultTypes, - writeBuildArtifact: createWriteBuildArtifact({ buildDirectory }), + writeBuildArtifact: createWriteBuildArtifact({ directories }), }; return context; } @@ -110,7 +108,7 @@ async function build(options) { await writeConnectionImports({ components, context }); await writeStyleImports({ components, context }); await writeIconImports({ components, context }); - // TODO: add plugins to package.json + await updateServerPackageJson({ components, context }); } catch (error) { context.logger.error(error); throw error; diff --git a/packages/build/src/scripts/run.js b/packages/build/src/scripts/run.js index 6020c3fd0..b11d0cb95 100644 --- a/packages/build/src/scripts/run.js +++ b/packages/build/src/scripts/run.js @@ -21,10 +21,11 @@ import build from '../index.js'; async function run() { await build({ logger: console, - buildDirectory: path.resolve( - process.env.LOWDEFY_BUILD_DIRECTORY || path.join(process.cwd(), 'build') - ), - configDirectory: path.resolve(process.env.LOWDEFY_CONFIG_DIRECTORY || process.cwd()), + directories: { + build: path.resolve(process.env.LOWDEFY_BUILD_DIRECTORY || path.join(process.cwd(), 'build')), + config: path.resolve(process.env.LOWDEFY_CONFIG_DIRECTORY || process.cwd()), + server: path.resolve(process.env.LOWDEFY_SERVER_DIRECTORY || process.cwd()), + }, }); } diff --git a/packages/build/src/test/testContext.js b/packages/build/src/test/testContext.js index f1121e7c9..5fcee687c 100644 --- a/packages/build/src/test/testContext.js +++ b/packages/build/src/test/testContext.js @@ -27,7 +27,9 @@ function testContext({ writeBuildArtifact, configDirectory, readConfigFile, logg const context = { id: 'test', - configDirectory: configDirectory || '', + directories: { + config: configDirectory || '', + }, typeCounters: { actions: createCounter(), blocks: createCounter(), diff --git a/packages/build/src/utils/files/readConfigFile.js b/packages/build/src/utils/files/readConfigFile.js index f0ff95641..e3bb5f048 100644 --- a/packages/build/src/utils/files/readConfigFile.js +++ b/packages/build/src/utils/files/readConfigFile.js @@ -18,9 +18,9 @@ import path from 'path'; import { cachedPromises } from '@lowdefy/helpers'; import { readFile } from '@lowdefy/node-utils'; -function createReadConfigFile({ configDirectory }) { +function createReadConfigFile({ directories }) { async function readConfigFile(filePath) { - return readFile(path.resolve(configDirectory, filePath)); + return readFile(path.resolve(directories.config, filePath)); } return cachedPromises(readConfigFile); } diff --git a/packages/build/src/utils/files/readConfigFile.test.js b/packages/build/src/utils/files/readConfigFile.test.js index e5a45fc07..e427d5391 100644 --- a/packages/build/src/utils/files/readConfigFile.test.js +++ b/packages/build/src/utils/files/readConfigFile.test.js @@ -22,27 +22,27 @@ jest.mock('@lowdefy/node-utils', () => { }; }); -const configDirectory = './config'; +const directories = { config: './config' }; test('readConfigFile reads a file from the correct dir', async () => { const nodeUtils = await import('@lowdefy/node-utils'); const createReadConfigFile = await import('./readConfigFile.js'); - const readConfigFile = createReadConfigFile.default({ configDirectory }); + const readConfigFile = createReadConfigFile.default({ directories }); nodeUtils.readFile.mockImplementation(() => 'Text file content'); const res = await readConfigFile('file.txt'); expect(res).toEqual('Text file content'); - expect(nodeUtils.readFile.mock.calls).toEqual([[path.resolve(configDirectory, 'file.txt')]]); + expect(nodeUtils.readFile.mock.calls).toEqual([[path.resolve(directories.config, 'file.txt')]]); }); test('readConfigFile memoizes results', async () => { const nodeUtils = await import('@lowdefy/node-utils'); const createReadConfigFile = await import('./readConfigFile.js'); - const readConfigFile = createReadConfigFile.default({ configDirectory }); + const readConfigFile = createReadConfigFile.default({ directories }); nodeUtils.readFile.mockImplementation(() => 'Text file content'); const res1 = await readConfigFile('file.txt'); expect(res1).toEqual('Text file content'); - expect(nodeUtils.readFile.mock.calls).toEqual([[path.resolve(configDirectory, 'file.txt')]]); + expect(nodeUtils.readFile.mock.calls).toEqual([[path.resolve(directories.config, 'file.txt')]]); const res2 = await readConfigFile('file.txt'); expect(res2).toEqual('Text file content'); - expect(nodeUtils.readFile.mock.calls).toEqual([[path.resolve(configDirectory, 'file.txt')]]); + expect(nodeUtils.readFile.mock.calls).toEqual([[path.resolve(directories.config, 'file.txt')]]); }); diff --git a/packages/build/src/utils/files/writeBuildArtifact.js b/packages/build/src/utils/files/writeBuildArtifact.js index a577bfb77..05ccd83f0 100644 --- a/packages/build/src/utils/files/writeBuildArtifact.js +++ b/packages/build/src/utils/files/writeBuildArtifact.js @@ -17,9 +17,9 @@ import path from 'path'; import { writeFile } from '@lowdefy/node-utils'; -function createWriteBuildArtifact({ buildDirectory }) { +function createWriteBuildArtifact({ directories }) { async function writeBuildArtifact({ filePath, content }) { - return writeFile({ filePath: path.resolve(buildDirectory, filePath), content }); + return writeFile({ filePath: path.resolve(directories.build, filePath), content }); } return writeBuildArtifact; } diff --git a/packages/build/src/utils/files/writeBuildArtifact.test.js b/packages/build/src/utils/files/writeBuildArtifact.test.js index c7c5bc738..5f52c26cf 100644 --- a/packages/build/src/utils/files/writeBuildArtifact.test.js +++ b/packages/build/src/utils/files/writeBuildArtifact.test.js @@ -15,17 +15,17 @@ import fs from 'fs'; import path from 'path'; import createWriteBuildArtifact from './writeBuildArtifact.js'; -const buildDirectory = path.resolve(process.cwd(), 'src/test/fileSetter'); +const directories = { build: path.resolve(process.cwd(), 'src/test/fileSetter') }; test('writeFile', async () => { - const filePath = path.resolve(buildDirectory, 'writeFile.txt'); + const filePath = path.resolve(directories.build, 'writeFile.txt'); try { fs.unlinkSync(filePath); } catch (error) { //pass } expect(fs.existsSync(filePath)).toBe(false); - const writeBuildArtifact = createWriteBuildArtifact({ buildDirectory }); + const writeBuildArtifact = createWriteBuildArtifact({ directories }); await writeBuildArtifact({ filePath: 'writeFile.txt', diff --git a/packages/cli/src/commands/build/runLowdefyBuild.js b/packages/cli/src/commands/build/runLowdefyBuild.js index c797c650c..b53774417 100644 --- a/packages/cli/src/commands/build/runLowdefyBuild.js +++ b/packages/cli/src/commands/build/runLowdefyBuild.js @@ -29,6 +29,7 @@ async function runLowdefyBuild({ context }) { ...process.env, LOWDEFY_BUILD_DIRECTORY: context.directories.build, LOWDEFY_CONFIG_DIRECTORY: context.directories.base, + LOWDEFY_SERVER_DIRECTORY: context.directories.server, }, }, silent: false, diff --git a/packages/server/package.json b/packages/server/package.json index 910130a39..befd81817 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -31,7 +31,6 @@ ".eslintrc.yaml" ], "scripts": { - "build": "lowdefy-build && next build", "build:lowdefy": "lowdefy-build", "build:next": "next build", "dev": "next dev", @@ -42,9 +41,6 @@ "dependencies": { "@lowdefy/api": "4.0.0-alpha.4", "@lowdefy/block-utils": "4.0.0-alpha.4", - "@lowdefy/blocks-antd": "4.0.0-alpha.4", - "@lowdefy/blocks-basic": "4.0.0-alpha.4", - "@lowdefy/connection-axios-http": "4.0.0-alpha.4", "@lowdefy/engine": "4.0.0-alpha.4", "@lowdefy/helpers": "4.0.0-alpha.4", "@lowdefy/layout": "4.0.0-alpha.4", diff --git a/yarn.lock b/yarn.lock index 30e99d800..8f545cf84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3774,9 +3774,7 @@ __metadata: "@lowdefy/api": 4.0.0-alpha.4 "@lowdefy/block-utils": 4.0.0-alpha.4 "@lowdefy/blocks-antd": 4.0.0-alpha.4 - "@lowdefy/blocks-basic": 4.0.0-alpha.4 "@lowdefy/build": 4.0.0-alpha.4 - "@lowdefy/connection-axios-http": 4.0.0-alpha.4 "@lowdefy/engine": 4.0.0-alpha.4 "@lowdefy/helpers": 4.0.0-alpha.4 "@lowdefy/layout": 4.0.0-alpha.4