feat: Update server package.json if plugin deps change.

Closes #943
This commit is contained in:
Sam Tolmay 2021-11-26 11:44:56 +02:00
parent 9c89ea3c0a
commit 09f7bca3a2
No known key found for this signature in database
GPG Key ID: D004126FCD1A6DF0
15 changed files with 92 additions and 37 deletions

2
.pnp.cjs generated
View File

@ -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"],

View File

@ -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);
}

View File

@ -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;

View File

@ -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']]);

View File

@ -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;

View File

@ -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;

View File

@ -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()),
},
});
}

View File

@ -27,7 +27,9 @@ function testContext({ writeBuildArtifact, configDirectory, readConfigFile, logg
const context = {
id: 'test',
configDirectory: configDirectory || '',
directories: {
config: configDirectory || '',
},
typeCounters: {
actions: createCounter(),
blocks: createCounter(),

View File

@ -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);
}

View File

@ -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')]]);
});

View File

@ -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;
}

View File

@ -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',

View File

@ -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,

View File

@ -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",

View File

@ -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