@grafana/create-plugin 4.0.1 → 4.0.2-canary.754.d15fa36.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/dist/commands/generate.command.js +3 -3
- package/dist/constants.js +4 -0
- package/dist/utils/tests/utils.config.test.js +94 -0
- package/dist/utils/utils.config.js +21 -43
- package/dist/utils/utils.templates.js +3 -3
- package/package.json +2 -2
- package/src/commands/generate.command.ts +3 -3
- package/src/constants.ts +5 -0
- package/src/utils/tests/utils.config.test.ts +119 -0
- package/src/utils/utils.config.ts +26 -55
- package/src/utils/utils.templates.ts +9 -3
|
@@ -2,7 +2,7 @@ import glob from 'glob';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { mkdir, readdir, writeFile } from 'node:fs/promises';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { EXTRA_TEMPLATE_VARIABLES, IS_DEV, PLUGIN_TYPES, TEMPLATE_PATHS } from '../constants.js';
|
|
5
|
+
import { DEFAULT_FEATURE_FLAGS, EXTRA_TEMPLATE_VARIABLES, IS_DEV, PLUGIN_TYPES, TEMPLATE_PATHS } from '../constants.js';
|
|
6
6
|
import { getConfig } from '../utils/utils.config.js';
|
|
7
7
|
import { printError } from '../utils/utils.console.js';
|
|
8
8
|
import { directoryExists, getExportFileName, isFile } from '../utils/utils.files.js';
|
|
@@ -47,7 +47,7 @@ function getTemplateData(answers) {
|
|
|
47
47
|
const { packageManagerName, packageManagerVersion } = getPackageManagerFromUserAgent();
|
|
48
48
|
const packageManagerInstallCmd = getPackageManagerInstallCmd(packageManagerName);
|
|
49
49
|
const isAppType = pluginType === PLUGIN_TYPES.app || pluginType === PLUGIN_TYPES.scenes;
|
|
50
|
-
const useReactRouterV6 = features.useReactRouterV6 && pluginType === PLUGIN_TYPES.app;
|
|
50
|
+
const useReactRouterV6 = features.useReactRouterV6 === true && pluginType === PLUGIN_TYPES.app;
|
|
51
51
|
const templateData = {
|
|
52
52
|
...answers,
|
|
53
53
|
pluginId,
|
|
@@ -57,7 +57,7 @@ function getTemplateData(answers) {
|
|
|
57
57
|
isAppType,
|
|
58
58
|
isNPM: packageManagerName === 'npm',
|
|
59
59
|
version: currentVersion,
|
|
60
|
-
bundleGrafanaUI: features.bundleGrafanaUI,
|
|
60
|
+
bundleGrafanaUI: features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI,
|
|
61
61
|
useReactRouterV6,
|
|
62
62
|
reactRouterVersion: useReactRouterV6 ? '6.22.0' : '5.2.0',
|
|
63
63
|
};
|
package/dist/constants.js
CHANGED
|
@@ -31,6 +31,10 @@ export const EXTRA_TEMPLATE_VARIABLES = {
|
|
|
31
31
|
grafanaVersion: '10.0.3',
|
|
32
32
|
grafanaImage: 'grafana-enterprise',
|
|
33
33
|
};
|
|
34
|
+
export const DEFAULT_FEATURE_FLAGS = {
|
|
35
|
+
useReactRouterV6: true,
|
|
36
|
+
bundleGrafanaUI: false,
|
|
37
|
+
};
|
|
34
38
|
export const GRAFANA_FE_PACKAGES = [
|
|
35
39
|
'@grafana/data',
|
|
36
40
|
'@grafana/e2e-selectors',
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { vi } from 'vitest';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { getVersion } from '../utils.version.js';
|
|
6
|
+
import { getConfig } from '../utils.config.js';
|
|
7
|
+
import { DEFAULT_FEATURE_FLAGS } from '../../constants.js';
|
|
8
|
+
const mocks = vi.hoisted(() => {
|
|
9
|
+
return {
|
|
10
|
+
commandName: 'generate',
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
vi.mock('../utils.cli.js', async () => mocks);
|
|
14
|
+
const tmpDir = path.join(os.tmpdir(), 'cp-test-config');
|
|
15
|
+
describe('getConfig', () => {
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
await fs.mkdir(tmpDir, { recursive: true });
|
|
18
|
+
});
|
|
19
|
+
afterEach(async () => {
|
|
20
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
21
|
+
});
|
|
22
|
+
describe('Command: Generate', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
mocks.commandName = 'generate';
|
|
25
|
+
});
|
|
26
|
+
it('should give back a default config', async () => {
|
|
27
|
+
const config = getConfig(tmpDir);
|
|
28
|
+
expect(config).toEqual({
|
|
29
|
+
version: getVersion(),
|
|
30
|
+
features: DEFAULT_FEATURE_FLAGS,
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('Command: Update', () => {
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
mocks.commandName = 'update';
|
|
37
|
+
});
|
|
38
|
+
it('should give back the correct config when there are no config files at all', async () => {
|
|
39
|
+
const config = getConfig();
|
|
40
|
+
expect(config).toEqual({
|
|
41
|
+
version: getVersion(),
|
|
42
|
+
features: {},
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
it('should give back the correct config when there is no user config', async () => {
|
|
46
|
+
const rootConfigPath = path.join(tmpDir, '.config', '.cprc.json');
|
|
47
|
+
const rootConfig = {
|
|
48
|
+
version: '1.0.0',
|
|
49
|
+
features: {},
|
|
50
|
+
};
|
|
51
|
+
await fs.mkdir(path.dirname(rootConfigPath), { recursive: true });
|
|
52
|
+
await fs.writeFile(rootConfigPath, JSON.stringify(rootConfig));
|
|
53
|
+
const config = getConfig(tmpDir);
|
|
54
|
+
expect(config).toEqual({
|
|
55
|
+
version: rootConfig.version,
|
|
56
|
+
features: {},
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
it('should give back the correct config when there is no root config', async () => {
|
|
60
|
+
const userConfigPath = path.join(tmpDir, '.cprc.json');
|
|
61
|
+
const userConfig = {
|
|
62
|
+
features: {
|
|
63
|
+
useReactRouterV6: true,
|
|
64
|
+
bundleGrafanaUI: true,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
await fs.writeFile(userConfigPath, JSON.stringify(userConfig));
|
|
68
|
+
const config = getConfig(tmpDir);
|
|
69
|
+
expect(config).toEqual({
|
|
70
|
+
version: getVersion(),
|
|
71
|
+
features: userConfig.features,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('should give back the correct config when config files exist', async () => {
|
|
75
|
+
const rootConfigPath = path.join(tmpDir, '.config', '.cprc.json');
|
|
76
|
+
const userConfigPath = path.join(tmpDir, '.cprc.json');
|
|
77
|
+
const rootConfig = {
|
|
78
|
+
version: '1.0.0',
|
|
79
|
+
features: {},
|
|
80
|
+
};
|
|
81
|
+
const userConfig = {
|
|
82
|
+
features: {
|
|
83
|
+
useReactRouterV6: false,
|
|
84
|
+
bundleGrafanaUI: false,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
await fs.mkdir(path.dirname(rootConfigPath), { recursive: true });
|
|
88
|
+
await fs.writeFile(rootConfigPath, JSON.stringify(rootConfig));
|
|
89
|
+
await fs.writeFile(userConfigPath, JSON.stringify(userConfig));
|
|
90
|
+
const config = getConfig(tmpDir);
|
|
91
|
+
expect(config).toEqual({ ...rootConfig, ...userConfig });
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -2,64 +2,49 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { getVersion } from './utils.version.js';
|
|
4
4
|
import { commandName } from './utils.cli.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
5
|
+
import { DEFAULT_FEATURE_FLAGS } from '../constants.js';
|
|
6
|
+
export function getConfig(workDir = process.cwd()) {
|
|
7
|
+
const rootConfig = getRootConfig(workDir);
|
|
8
|
+
const userConfig = getUserConfig(workDir);
|
|
8
9
|
return {
|
|
9
10
|
...rootConfig,
|
|
10
11
|
...userConfig,
|
|
11
12
|
version: rootConfig.version,
|
|
12
13
|
features: createFeatureFlags({
|
|
13
|
-
...rootConfig.features,
|
|
14
|
-
...userConfig.features,
|
|
14
|
+
...(rootConfig.features ?? {}),
|
|
15
|
+
...(userConfig.features ?? {}),
|
|
15
16
|
}),
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
|
-
function getRootConfig() {
|
|
19
|
-
const defaultConfig = {
|
|
20
|
-
version: getVersion(),
|
|
21
|
-
features: createFeatureFlags(),
|
|
22
|
-
};
|
|
19
|
+
function getRootConfig(workDir = process.cwd()) {
|
|
23
20
|
try {
|
|
24
|
-
const rootPath = path.resolve(
|
|
21
|
+
const rootPath = path.resolve(workDir, '.config/.cprc.json');
|
|
25
22
|
const rootConfig = readRCFileSync(rootPath);
|
|
26
23
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
...rootConfig.features,
|
|
31
|
-
},
|
|
24
|
+
version: getVersion(),
|
|
25
|
+
...rootConfig,
|
|
26
|
+
features: rootConfig.features ?? {},
|
|
32
27
|
};
|
|
33
28
|
}
|
|
34
29
|
catch (error) {
|
|
35
|
-
if (commandName === 'generate') {
|
|
36
|
-
return defaultConfig;
|
|
37
|
-
}
|
|
38
30
|
return {
|
|
39
|
-
|
|
40
|
-
features:
|
|
31
|
+
version: getVersion(),
|
|
32
|
+
features: {},
|
|
41
33
|
};
|
|
42
34
|
}
|
|
43
35
|
}
|
|
44
|
-
function getUserConfig() {
|
|
36
|
+
function getUserConfig(workDir = process.cwd()) {
|
|
45
37
|
try {
|
|
46
|
-
const userPath = path.resolve(
|
|
38
|
+
const userPath = path.resolve(workDir, '.cprc.json');
|
|
47
39
|
const userConfig = readRCFileSync(userPath);
|
|
48
40
|
return {
|
|
49
41
|
...userConfig,
|
|
50
|
-
features:
|
|
51
|
-
...userConfig.features,
|
|
52
|
-
}),
|
|
42
|
+
features: userConfig.features ?? {},
|
|
53
43
|
};
|
|
54
44
|
}
|
|
55
45
|
catch (error) {
|
|
56
|
-
if (commandName === 'generate') {
|
|
57
|
-
return {
|
|
58
|
-
features: createFeatureFlags(),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
46
|
return {
|
|
62
|
-
features:
|
|
47
|
+
features: {},
|
|
63
48
|
};
|
|
64
49
|
}
|
|
65
50
|
}
|
|
@@ -73,15 +58,8 @@ function readRCFileSync(path) {
|
|
|
73
58
|
}
|
|
74
59
|
}
|
|
75
60
|
function createFeatureFlags(flags) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function createDisabledFeatureFlags() {
|
|
83
|
-
return {
|
|
84
|
-
useReactRouterV6: false,
|
|
85
|
-
bundleGrafanaUI: false,
|
|
86
|
-
};
|
|
61
|
+
if (commandName === 'generate') {
|
|
62
|
+
return DEFAULT_FEATURE_FLAGS;
|
|
63
|
+
}
|
|
64
|
+
return flags ?? {};
|
|
87
65
|
}
|
|
@@ -6,7 +6,7 @@ import createDebug from 'debug';
|
|
|
6
6
|
import { filterOutCommonFiles, isFile, isFileStartingWith } from './utils.files.js';
|
|
7
7
|
import { renderHandlebarsTemplate } from './utils.handlebars.js';
|
|
8
8
|
import { getPluginJson } from './utils.plugin.js';
|
|
9
|
-
import { TEMPLATE_PATHS, EXPORT_PATH_PREFIX, EXTRA_TEMPLATE_VARIABLES, PLUGIN_TYPES } from '../constants.js';
|
|
9
|
+
import { TEMPLATE_PATHS, EXPORT_PATH_PREFIX, EXTRA_TEMPLATE_VARIABLES, PLUGIN_TYPES, DEFAULT_FEATURE_FLAGS, } from '../constants.js';
|
|
10
10
|
import { getPackageManagerInstallCmd, getPackageManagerWithFallback } from './utils.packageManager.js';
|
|
11
11
|
import { getExportFileName } from '../utils/utils.files.js';
|
|
12
12
|
import { getVersion } from './utils.version.js';
|
|
@@ -58,7 +58,7 @@ export function getTemplateData() {
|
|
|
58
58
|
const pluginJson = getPluginJson();
|
|
59
59
|
const { features } = getConfig();
|
|
60
60
|
const currentVersion = getVersion();
|
|
61
|
-
const useReactRouterV6 = features.useReactRouterV6 && pluginJson.type === PLUGIN_TYPES.app;
|
|
61
|
+
const useReactRouterV6 = features.useReactRouterV6 === true && pluginJson.type === PLUGIN_TYPES.app;
|
|
62
62
|
const { packageManagerName, packageManagerVersion } = getPackageManagerWithFallback();
|
|
63
63
|
const packageManagerInstallCmd = getPackageManagerInstallCmd(packageManagerName);
|
|
64
64
|
const templateData = {
|
|
@@ -75,7 +75,7 @@ export function getTemplateData() {
|
|
|
75
75
|
packageManagerVersion,
|
|
76
76
|
packageManagerInstallCmd,
|
|
77
77
|
version: currentVersion,
|
|
78
|
-
bundleGrafanaUI: features.bundleGrafanaUI,
|
|
78
|
+
bundleGrafanaUI: features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI,
|
|
79
79
|
useReactRouterV6: useReactRouterV6,
|
|
80
80
|
reactRouterVersion: useReactRouterV6 ? '6.22.0' : '5.2.0',
|
|
81
81
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/create-plugin",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2-canary.754.d15fa36.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"directory": "packages/create-plugin",
|
|
6
6
|
"url": "https://github.com/grafana/plugin-tools"
|
|
@@ -87,5 +87,5 @@
|
|
|
87
87
|
"engines": {
|
|
88
88
|
"node": ">=20"
|
|
89
89
|
},
|
|
90
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "d15fa36c7d1ea6e13a4700ef9f127d7f1c346b16"
|
|
91
91
|
}
|
|
@@ -3,7 +3,7 @@ import minimist from 'minimist';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { mkdir, readdir, writeFile } from 'node:fs/promises';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
import { EXTRA_TEMPLATE_VARIABLES, IS_DEV, PLUGIN_TYPES, TEMPLATE_PATHS } from '../constants.js';
|
|
6
|
+
import { DEFAULT_FEATURE_FLAGS, EXTRA_TEMPLATE_VARIABLES, IS_DEV, PLUGIN_TYPES, TEMPLATE_PATHS } from '../constants.js';
|
|
7
7
|
import { getConfig } from '../utils/utils.config.js';
|
|
8
8
|
import { printError } from '../utils/utils.console.js';
|
|
9
9
|
import { directoryExists, getExportFileName, isFile } from '../utils/utils.files.js';
|
|
@@ -59,7 +59,7 @@ function getTemplateData(answers: CliArgs) {
|
|
|
59
59
|
const { packageManagerName, packageManagerVersion } = getPackageManagerFromUserAgent();
|
|
60
60
|
const packageManagerInstallCmd = getPackageManagerInstallCmd(packageManagerName);
|
|
61
61
|
const isAppType = pluginType === PLUGIN_TYPES.app || pluginType === PLUGIN_TYPES.scenes;
|
|
62
|
-
const useReactRouterV6 = features.useReactRouterV6 && pluginType === PLUGIN_TYPES.app; // We don't enable this by default yet for new scenes plugins.
|
|
62
|
+
const useReactRouterV6 = features.useReactRouterV6 === true && pluginType === PLUGIN_TYPES.app; // We don't enable this by default yet for new scenes plugins.
|
|
63
63
|
const templateData: TemplateData = {
|
|
64
64
|
...answers,
|
|
65
65
|
pluginId,
|
|
@@ -69,7 +69,7 @@ function getTemplateData(answers: CliArgs) {
|
|
|
69
69
|
isAppType,
|
|
70
70
|
isNPM: packageManagerName === 'npm',
|
|
71
71
|
version: currentVersion,
|
|
72
|
-
bundleGrafanaUI: features.bundleGrafanaUI,
|
|
72
|
+
bundleGrafanaUI: features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI,
|
|
73
73
|
useReactRouterV6,
|
|
74
74
|
reactRouterVersion: useReactRouterV6 ? '6.22.0' : '5.2.0',
|
|
75
75
|
};
|
package/src/constants.ts
CHANGED
|
@@ -47,6 +47,11 @@ export const EXTRA_TEMPLATE_VARIABLES = {
|
|
|
47
47
|
grafanaImage: 'grafana-enterprise',
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
export const DEFAULT_FEATURE_FLAGS = {
|
|
51
|
+
useReactRouterV6: true,
|
|
52
|
+
bundleGrafanaUI: false,
|
|
53
|
+
};
|
|
54
|
+
|
|
50
55
|
export const GRAFANA_FE_PACKAGES = [
|
|
51
56
|
'@grafana/data',
|
|
52
57
|
'@grafana/e2e-selectors',
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { vi } from 'vitest';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { getVersion } from '../utils.version.js';
|
|
6
|
+
import { getConfig, UserConfig, CreatePluginConfig } from '../utils.config.js';
|
|
7
|
+
import { DEFAULT_FEATURE_FLAGS } from '../../constants.js';
|
|
8
|
+
|
|
9
|
+
const mocks = vi.hoisted(() => {
|
|
10
|
+
return {
|
|
11
|
+
commandName: 'generate',
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
vi.mock('../utils.cli.js', async () => mocks);
|
|
16
|
+
|
|
17
|
+
const tmpDir = path.join(os.tmpdir(), 'cp-test-config');
|
|
18
|
+
|
|
19
|
+
describe('getConfig', () => {
|
|
20
|
+
beforeEach(async () => {
|
|
21
|
+
// Create temporary directory for testing
|
|
22
|
+
await fs.mkdir(tmpDir, { recursive: true });
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
// Clean up temporary directory
|
|
27
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('Command: Generate', () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
mocks.commandName = 'generate';
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should give back a default config', async () => {
|
|
36
|
+
const config = getConfig(tmpDir);
|
|
37
|
+
|
|
38
|
+
expect(config).toEqual({
|
|
39
|
+
version: getVersion(),
|
|
40
|
+
features: DEFAULT_FEATURE_FLAGS,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('Command: Update', () => {
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
mocks.commandName = 'update';
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should give back the correct config when there are no config files at all', async () => {
|
|
51
|
+
const config = getConfig();
|
|
52
|
+
|
|
53
|
+
expect(config).toEqual({
|
|
54
|
+
version: getVersion(),
|
|
55
|
+
features: {},
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should give back the correct config when there is no user config', async () => {
|
|
60
|
+
const rootConfigPath = path.join(tmpDir, '.config', '.cprc.json');
|
|
61
|
+
const rootConfig: CreatePluginConfig = {
|
|
62
|
+
version: '1.0.0',
|
|
63
|
+
features: {},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
await fs.mkdir(path.dirname(rootConfigPath), { recursive: true });
|
|
67
|
+
await fs.writeFile(rootConfigPath, JSON.stringify(rootConfig));
|
|
68
|
+
|
|
69
|
+
const config = getConfig(tmpDir);
|
|
70
|
+
|
|
71
|
+
expect(config).toEqual({
|
|
72
|
+
version: rootConfig.version,
|
|
73
|
+
features: {},
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should give back the correct config when there is no root config', async () => {
|
|
78
|
+
const userConfigPath = path.join(tmpDir, '.cprc.json');
|
|
79
|
+
const userConfig: UserConfig = {
|
|
80
|
+
features: {
|
|
81
|
+
useReactRouterV6: true,
|
|
82
|
+
bundleGrafanaUI: true,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
await fs.writeFile(userConfigPath, JSON.stringify(userConfig));
|
|
87
|
+
|
|
88
|
+
const config = getConfig(tmpDir);
|
|
89
|
+
|
|
90
|
+
expect(config).toEqual({
|
|
91
|
+
version: getVersion(),
|
|
92
|
+
features: userConfig.features,
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should give back the correct config when config files exist', async () => {
|
|
97
|
+
const rootConfigPath = path.join(tmpDir, '.config', '.cprc.json');
|
|
98
|
+
const userConfigPath = path.join(tmpDir, '.cprc.json');
|
|
99
|
+
const rootConfig: CreatePluginConfig = {
|
|
100
|
+
version: '1.0.0',
|
|
101
|
+
features: {},
|
|
102
|
+
};
|
|
103
|
+
const userConfig: UserConfig = {
|
|
104
|
+
features: {
|
|
105
|
+
useReactRouterV6: false,
|
|
106
|
+
bundleGrafanaUI: false,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
await fs.mkdir(path.dirname(rootConfigPath), { recursive: true });
|
|
111
|
+
await fs.writeFile(rootConfigPath, JSON.stringify(rootConfig));
|
|
112
|
+
await fs.writeFile(userConfigPath, JSON.stringify(userConfig));
|
|
113
|
+
|
|
114
|
+
const config = getConfig(tmpDir);
|
|
115
|
+
|
|
116
|
+
expect(config).toEqual({ ...rootConfig, ...userConfig });
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -2,95 +2,73 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { getVersion } from './utils.version.js';
|
|
4
4
|
import { commandName } from './utils.cli.js';
|
|
5
|
+
import { DEFAULT_FEATURE_FLAGS } from '../constants.js';
|
|
5
6
|
|
|
6
|
-
type FeatureFlags = {
|
|
7
|
-
bundleGrafanaUI
|
|
7
|
+
export type FeatureFlags = {
|
|
8
|
+
bundleGrafanaUI?: boolean;
|
|
8
9
|
|
|
9
10
|
// If set to true, the plugin will be scaffolded with React Router v6. Defaults to true.
|
|
10
11
|
// (Attention! We always scaffold new projects with React Router v6, so if you are changing this to `false` manually you will need to make changes to the React code as well.)
|
|
11
|
-
useReactRouterV6
|
|
12
|
+
useReactRouterV6?: boolean;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
type CreatePluginConfig = UserConfig & {
|
|
15
|
+
export type CreatePluginConfig = UserConfig & {
|
|
15
16
|
version: string;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
type UserConfig = {
|
|
19
|
+
export type UserConfig = {
|
|
19
20
|
features: FeatureFlags;
|
|
20
21
|
};
|
|
21
22
|
|
|
22
|
-
export function getConfig(): CreatePluginConfig {
|
|
23
|
-
const rootConfig = getRootConfig();
|
|
24
|
-
const userConfig = getUserConfig();
|
|
23
|
+
export function getConfig(workDir = process.cwd()): CreatePluginConfig {
|
|
24
|
+
const rootConfig = getRootConfig(workDir);
|
|
25
|
+
const userConfig = getUserConfig(workDir);
|
|
25
26
|
|
|
26
27
|
return {
|
|
27
28
|
...rootConfig,
|
|
28
29
|
...userConfig,
|
|
29
30
|
version: rootConfig!.version,
|
|
30
31
|
features: createFeatureFlags({
|
|
31
|
-
...rootConfig!.features,
|
|
32
|
-
...userConfig!.features,
|
|
32
|
+
...(rootConfig!.features ?? {}),
|
|
33
|
+
...(userConfig!.features ?? {}),
|
|
33
34
|
}),
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
function getRootConfig(): CreatePluginConfig {
|
|
38
|
-
const defaultConfig = {
|
|
39
|
-
version: getVersion(),
|
|
40
|
-
features: createFeatureFlags(),
|
|
41
|
-
};
|
|
42
|
-
|
|
38
|
+
function getRootConfig(workDir = process.cwd()): CreatePluginConfig {
|
|
43
39
|
try {
|
|
44
|
-
const rootPath = path.resolve(
|
|
40
|
+
const rootPath = path.resolve(workDir, '.config/.cprc.json');
|
|
45
41
|
const rootConfig = readRCFileSync(rootPath);
|
|
46
42
|
|
|
47
43
|
return {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
...rootConfig!.features,
|
|
52
|
-
},
|
|
44
|
+
version: getVersion(),
|
|
45
|
+
...rootConfig,
|
|
46
|
+
features: rootConfig!.features ?? {},
|
|
53
47
|
};
|
|
54
48
|
// Most likely this happens because of no ".config/.cprc.json" (root configuration) file.
|
|
55
49
|
// (This can both happen for new scaffolds and for existing plugins that have not been updated yet.)
|
|
56
50
|
} catch (error) {
|
|
57
|
-
// Scaffolding a new plugin
|
|
58
|
-
if (commandName === 'generate') {
|
|
59
|
-
return defaultConfig;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Most probably updating an existing plugin
|
|
63
51
|
return {
|
|
64
|
-
|
|
65
|
-
features:
|
|
52
|
+
version: getVersion(),
|
|
53
|
+
features: {},
|
|
66
54
|
};
|
|
67
55
|
}
|
|
68
56
|
}
|
|
69
57
|
|
|
70
|
-
function getUserConfig(): UserConfig | undefined {
|
|
58
|
+
function getUserConfig(workDir = process.cwd()): UserConfig | undefined {
|
|
71
59
|
try {
|
|
72
|
-
const userPath = path.resolve(
|
|
60
|
+
const userPath = path.resolve(workDir, '.cprc.json');
|
|
73
61
|
const userConfig = readRCFileSync(userPath);
|
|
74
62
|
|
|
75
63
|
return {
|
|
76
64
|
...userConfig,
|
|
77
|
-
features:
|
|
78
|
-
...userConfig!.features,
|
|
79
|
-
}),
|
|
65
|
+
features: userConfig!.features ?? {},
|
|
80
66
|
};
|
|
81
67
|
// Most likely this happens because of no ".cprc.json" (user configuration) file.
|
|
82
68
|
// (This can both happen for new scaffolds and for existing plugins that have not been updated yet.)
|
|
83
69
|
} catch (error) {
|
|
84
|
-
// Scaffolding a new plugin
|
|
85
|
-
if (commandName === 'generate') {
|
|
86
|
-
return {
|
|
87
|
-
features: createFeatureFlags(),
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Most probably updating an existing plugin
|
|
92
70
|
return {
|
|
93
|
-
features:
|
|
71
|
+
features: {},
|
|
94
72
|
};
|
|
95
73
|
}
|
|
96
74
|
}
|
|
@@ -106,16 +84,9 @@ function readRCFileSync(path: string): CreatePluginConfig | undefined {
|
|
|
106
84
|
|
|
107
85
|
function createFeatureFlags(flags?: FeatureFlags): FeatureFlags {
|
|
108
86
|
// Default values for new scaffoldings
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
...flags,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
87
|
+
if (commandName === 'generate') {
|
|
88
|
+
return DEFAULT_FEATURE_FLAGS;
|
|
89
|
+
}
|
|
115
90
|
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
useReactRouterV6: false,
|
|
119
|
-
bundleGrafanaUI: false,
|
|
120
|
-
};
|
|
91
|
+
return flags ?? {};
|
|
121
92
|
}
|
|
@@ -6,7 +6,13 @@ import createDebug from 'debug';
|
|
|
6
6
|
import { filterOutCommonFiles, isFile, isFileStartingWith } from './utils.files.js';
|
|
7
7
|
import { renderHandlebarsTemplate } from './utils.handlebars.js';
|
|
8
8
|
import { getPluginJson } from './utils.plugin.js';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
TEMPLATE_PATHS,
|
|
11
|
+
EXPORT_PATH_PREFIX,
|
|
12
|
+
EXTRA_TEMPLATE_VARIABLES,
|
|
13
|
+
PLUGIN_TYPES,
|
|
14
|
+
DEFAULT_FEATURE_FLAGS,
|
|
15
|
+
} from '../constants.js';
|
|
10
16
|
import { TemplateData } from '../types.js';
|
|
11
17
|
import { getPackageManagerInstallCmd, getPackageManagerWithFallback } from './utils.packageManager.js';
|
|
12
18
|
import { getExportFileName } from '../utils/utils.files.js';
|
|
@@ -86,7 +92,7 @@ export function getTemplateData(): TemplateData {
|
|
|
86
92
|
const pluginJson = getPluginJson();
|
|
87
93
|
const { features } = getConfig();
|
|
88
94
|
const currentVersion = getVersion();
|
|
89
|
-
const useReactRouterV6 = features.useReactRouterV6 && pluginJson.type === PLUGIN_TYPES.app;
|
|
95
|
+
const useReactRouterV6 = features.useReactRouterV6 === true && pluginJson.type === PLUGIN_TYPES.app;
|
|
90
96
|
const { packageManagerName, packageManagerVersion } = getPackageManagerWithFallback();
|
|
91
97
|
const packageManagerInstallCmd = getPackageManagerInstallCmd(packageManagerName);
|
|
92
98
|
|
|
@@ -104,7 +110,7 @@ export function getTemplateData(): TemplateData {
|
|
|
104
110
|
packageManagerVersion,
|
|
105
111
|
packageManagerInstallCmd,
|
|
106
112
|
version: currentVersion,
|
|
107
|
-
bundleGrafanaUI: features.bundleGrafanaUI,
|
|
113
|
+
bundleGrafanaUI: features.bundleGrafanaUI ?? DEFAULT_FEATURE_FLAGS.bundleGrafanaUI,
|
|
108
114
|
useReactRouterV6: useReactRouterV6,
|
|
109
115
|
reactRouterVersion: useReactRouterV6 ? '6.22.0' : '5.2.0',
|
|
110
116
|
};
|