@grafana/create-plugin 7.8.0 → 7.9.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/CHANGELOG.md +19 -0
- package/dist/codemods/migrations/migrations.js +6 -0
- package/dist/codemods/migrations/scripts/012-terser-license-file.js +60 -0
- package/dist/libs/find-up/src/index.js +22 -0
- package/dist/libs/version/src/index.js +1 -1
- package/dist/utils/utils.packageManager.js +1 -1
- package/package.json +3 -3
- package/src/codemods/migrations/migrations.ts +6 -0
- package/src/codemods/migrations/scripts/012-terser-license-file.test.ts +170 -0
- package/src/codemods/migrations/scripts/012-terser-license-file.ts +75 -0
- package/src/utils/utils.packageManager.ts +1 -1
- package/templates/common/.config/docker-compose-base.yaml +1 -1
- package/templates/common/.config/rspack/rspack.config.ts +5 -0
- package/templates/common/.config/webpack/webpack.config.ts +5 -0
- package/templates/common/_package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [7.9.0](https://github.com/grafana/plugin-tools/compare/@grafana/create-plugin@7.8.1...@grafana/create-plugin@7.9.0) (2026-07-14)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **deps:** bump grafana libs to 13.1.0 in templates ([#2750](https://github.com/grafana/plugin-tools/issues/2750)) ([dab0f70](https://github.com/grafana/plugin-tools/commit/dab0f70ec9816b56d6fe73230fd24d0e2b76b03e))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* output single license file when building plugin ([#2770](https://github.com/grafana/plugin-tools/issues/2770)) ([fd20ced](https://github.com/grafana/plugin-tools/commit/fd20cedfffc053e69898081740038544db2c7470))
|
|
14
|
+
|
|
15
|
+
## [7.8.1](https://github.com/grafana/plugin-tools/compare/@grafana/create-plugin@7.8.0...@grafana/create-plugin@7.8.1) (2026-07-09)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* replace find-up dependency with native @libs/find-up helper ([#2722](https://github.com/grafana/plugin-tools/issues/2722)) ([d20ff77](https://github.com/grafana/plugin-tools/commit/d20ff7714de762a2d7ce96cf33a37d615e78e77c))
|
|
21
|
+
|
|
3
22
|
## [7.8.0](https://github.com/grafana/plugin-tools/compare/@grafana/create-plugin@7.7.1...@grafana/create-plugin@7.8.0) (2026-06-11)
|
|
4
23
|
|
|
5
24
|
|
|
@@ -66,6 +66,12 @@ var defaultMigrations = [
|
|
|
66
66
|
version: "7.6.3",
|
|
67
67
|
description: "Security: replace insecure inline `npx --yes @grafana/sign-plugin@latest` sign script with a locked @grafana/sign-plugin devDependency to prevent arbitrary code execution from a compromised @latest publish.",
|
|
68
68
|
scriptPath: import.meta.resolve("./scripts/011-secure-sign-script.js")
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "012-terser-license-file",
|
|
72
|
+
version: "7.8.2",
|
|
73
|
+
description: "Emit a single LICENSE.txt file for all licenses in bundled code.",
|
|
74
|
+
scriptPath: import.meta.resolve("./scripts/012-terser-license-file.js")
|
|
69
75
|
}
|
|
70
76
|
// Do not use LEGACY_UPDATE_CUTOFF_VERSION for new migrations. It is only used above to force migrations to run
|
|
71
77
|
// for those written before the switch to updates as migrations.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import * as recast from 'recast';
|
|
3
|
+
import { migrationsDebug } from '../../utils.js';
|
|
4
|
+
import { parseAsTypescript, findObjectProperty, printAST } from '../../utils.ast.js';
|
|
5
|
+
|
|
6
|
+
const { builders } = recast.types;
|
|
7
|
+
const BUNDLER_CONFIG_PATHS = [
|
|
8
|
+
join(".config", "webpack", "webpack.config.ts"),
|
|
9
|
+
join(".config", "rspack", "rspack.config.ts")
|
|
10
|
+
];
|
|
11
|
+
function migrate(context) {
|
|
12
|
+
for (const configPath of BUNDLER_CONFIG_PATHS) {
|
|
13
|
+
migrateBundlerConfig(context, configPath);
|
|
14
|
+
}
|
|
15
|
+
return context;
|
|
16
|
+
}
|
|
17
|
+
function migrateBundlerConfig(context, configPath) {
|
|
18
|
+
if (!context.doesFileExist(configPath)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const source = context.getFile(configPath);
|
|
22
|
+
if (!source) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (source.includes("extractComments")) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const parsed = parseAsTypescript(source);
|
|
29
|
+
if (!parsed.success) {
|
|
30
|
+
migrationsDebug(`Failed to parse ${configPath}. Error: ${parsed.error.message}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let hasChanges = false;
|
|
34
|
+
recast.visit(parsed.ast, {
|
|
35
|
+
visitNewExpression(path) {
|
|
36
|
+
const { node } = path;
|
|
37
|
+
if (node.callee.type === "Identifier" && node.callee.name === "TerserPlugin" && node.arguments.length > 0) {
|
|
38
|
+
const optionsArg = node.arguments[0];
|
|
39
|
+
if (optionsArg.type === "ObjectExpression" && !findObjectProperty(optionsArg, "extractComments")) {
|
|
40
|
+
const extractCommentsProperty = builders.property(
|
|
41
|
+
"init",
|
|
42
|
+
builders.identifier("extractComments"),
|
|
43
|
+
builders.objectExpression([
|
|
44
|
+
builders.property("init", builders.identifier("banner"), builders.literal(false)),
|
|
45
|
+
builders.property("init", builders.identifier("filename"), builders.literal("LICENSE.txt"))
|
|
46
|
+
])
|
|
47
|
+
);
|
|
48
|
+
optionsArg.properties.unshift(extractCommentsProperty);
|
|
49
|
+
hasChanges = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return this.traverse(path);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (hasChanges) {
|
|
56
|
+
context.updateFile(configPath, printAST(parsed.ast));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { migrate as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { statSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
function findUpSync(name, options = {}) {
|
|
5
|
+
const names = Array.isArray(name) ? name : [name];
|
|
6
|
+
let currentDir = path.resolve(options.cwd ?? process.cwd());
|
|
7
|
+
let previousDir;
|
|
8
|
+
while (currentDir !== previousDir) {
|
|
9
|
+
for (const candidateName of names) {
|
|
10
|
+
const candidatePath = path.join(currentDir, candidateName);
|
|
11
|
+
const stat = statSync(candidatePath, { throwIfNoEntry: false });
|
|
12
|
+
if (stat?.isFile()) {
|
|
13
|
+
return candidatePath;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
previousDir = currentDir;
|
|
17
|
+
currentDir = path.dirname(currentDir);
|
|
18
|
+
}
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { findUpSync };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { gte, lt } from 'semver';
|
|
2
2
|
import { basename } from 'node:path';
|
|
3
|
-
import { findUpSync } from 'find-up';
|
|
3
|
+
import { findUpSync } from '../libs/find-up/src/index.js';
|
|
4
4
|
import { getPackageJson } from './utils.packagejson.js';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/create-plugin",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.9.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"directory": "packages/create-plugin",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"change-case": "5.4.4",
|
|
32
32
|
"debug": "4.4.3",
|
|
33
33
|
"enquirer": "2.4.1",
|
|
34
|
-
"find-up": "8.0.0",
|
|
35
34
|
"glob": "13.0.6",
|
|
36
35
|
"handlebars": "4.7.9",
|
|
37
36
|
"jsonc-parser": "3.3.1",
|
|
@@ -44,6 +43,7 @@
|
|
|
44
43
|
"yaml": "2.9.0"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
46
|
+
"@libs/find-up": "1.0.0",
|
|
47
47
|
"@libs/output": "1.0.3",
|
|
48
48
|
"@libs/version": "1.0.2",
|
|
49
49
|
"@types/glob": "9.0.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@types/semver": "7.7.1",
|
|
52
52
|
"@types/tmp": "0.2.6",
|
|
53
53
|
"@types/which": "3.0.4",
|
|
54
|
-
"tmp": "0.2.
|
|
54
|
+
"tmp": "0.2.7"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": ">=20"
|
|
@@ -78,6 +78,12 @@ export default [
|
|
|
78
78
|
'Security: replace insecure inline `npx --yes @grafana/sign-plugin@latest` sign script with a locked @grafana/sign-plugin devDependency to prevent arbitrary code execution from a compromised @latest publish.',
|
|
79
79
|
scriptPath: import.meta.resolve('./scripts/011-secure-sign-script.js'),
|
|
80
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: '012-terser-license-file',
|
|
83
|
+
version: '7.8.2',
|
|
84
|
+
description: 'Emit a single LICENSE.txt file for all licenses in bundled code.',
|
|
85
|
+
scriptPath: import.meta.resolve('./scripts/012-terser-license-file.js'),
|
|
86
|
+
},
|
|
81
87
|
// Do not use LEGACY_UPDATE_CUTOFF_VERSION for new migrations. It is only used above to force migrations to run
|
|
82
88
|
// for those written before the switch to updates as migrations.
|
|
83
89
|
] satisfies Migration[];
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import migrate from './012-terser-license-file.js';
|
|
3
|
+
import { Context } from '../../context.js';
|
|
4
|
+
|
|
5
|
+
const WEBPACK_CONFIG_PATH = '.config/webpack/webpack.config.ts';
|
|
6
|
+
const RSPACK_CONFIG_PATH = '.config/rspack/rspack.config.ts';
|
|
7
|
+
|
|
8
|
+
const BUNDLER_CONFIG = `/*
|
|
9
|
+
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY \`@grafana/create-plugin\`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
|
10
|
+
*
|
|
11
|
+
* In order to extend the configuration follow the steps in
|
|
12
|
+
* https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-webpack-config
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import TerserPlugin from 'terser-webpack-plugin';
|
|
16
|
+
import { type Configuration } from 'webpack';
|
|
17
|
+
|
|
18
|
+
const config = async (env: Record<string, unknown>): Promise<Configuration> => ({
|
|
19
|
+
optimization: {
|
|
20
|
+
minimize: Boolean(env.production),
|
|
21
|
+
minimizer: [
|
|
22
|
+
new TerserPlugin({
|
|
23
|
+
terserOptions: {
|
|
24
|
+
format: {
|
|
25
|
+
comments: (_, { type, value }) => type === 'comment2' && value.trim().startsWith('[create-plugin]'),
|
|
26
|
+
},
|
|
27
|
+
compress: {
|
|
28
|
+
drop_console: ['log', 'info'],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export default config;
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const MIGRATED_BUNDLER_CONFIG = `/*
|
|
40
|
+
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY \`@grafana/create-plugin\`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
|
|
41
|
+
*
|
|
42
|
+
* In order to extend the configuration follow the steps in
|
|
43
|
+
* https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-webpack-config
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
import TerserPlugin from 'terser-webpack-plugin';
|
|
47
|
+
import { type Configuration } from 'webpack';
|
|
48
|
+
|
|
49
|
+
const config = async (env: Record<string, unknown>): Promise<Configuration> => ({
|
|
50
|
+
optimization: {
|
|
51
|
+
minimize: Boolean(env.production),
|
|
52
|
+
minimizer: [
|
|
53
|
+
new TerserPlugin({
|
|
54
|
+
extractComments: {
|
|
55
|
+
banner: false,
|
|
56
|
+
filename: 'LICENSE.txt',
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
terserOptions: {
|
|
60
|
+
format: {
|
|
61
|
+
comments: (_, { type, value }) => type === 'comment2' && value.trim().startsWith('[create-plugin]'),
|
|
62
|
+
},
|
|
63
|
+
compress: {
|
|
64
|
+
drop_console: ['log', 'info'],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export default config;
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
const NO_TERSER_CONFIG = `import { type Configuration } from 'webpack';
|
|
76
|
+
|
|
77
|
+
const config = async (): Promise<Configuration> => ({
|
|
78
|
+
optimization: {
|
|
79
|
+
minimize: true,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export default config;
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
describe('012-terser-license-file', () => {
|
|
87
|
+
it('should add extractComments before terserOptions in the webpack config', () => {
|
|
88
|
+
const context = new Context('/virtual');
|
|
89
|
+
context.addFile(WEBPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
90
|
+
|
|
91
|
+
const result = migrate(context);
|
|
92
|
+
const updated = result.getFile(WEBPACK_CONFIG_PATH) ?? '';
|
|
93
|
+
|
|
94
|
+
expect(updated).toContain('extractComments');
|
|
95
|
+
expect(updated).toContain('banner: false');
|
|
96
|
+
expect(updated).toContain("filename: 'LICENSE.txt'");
|
|
97
|
+
expect(updated.indexOf('extractComments')).toBeLessThan(updated.indexOf('terserOptions'));
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should add extractComments before terserOptions in the rspack config', () => {
|
|
101
|
+
const context = new Context('/virtual');
|
|
102
|
+
context.addFile(RSPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
103
|
+
|
|
104
|
+
const result = migrate(context);
|
|
105
|
+
const updated = result.getFile(RSPACK_CONFIG_PATH) ?? '';
|
|
106
|
+
|
|
107
|
+
expect(updated).toContain('extractComments');
|
|
108
|
+
expect(updated).toContain('banner: false');
|
|
109
|
+
expect(updated).toContain("filename: 'LICENSE.txt'");
|
|
110
|
+
expect(updated.indexOf('extractComments')).toBeLessThan(updated.indexOf('terserOptions'));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('should migrate both bundler configs when both exist', () => {
|
|
114
|
+
const context = new Context('/virtual');
|
|
115
|
+
context.addFile(WEBPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
116
|
+
context.addFile(RSPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
117
|
+
|
|
118
|
+
const result = migrate(context);
|
|
119
|
+
|
|
120
|
+
expect(result.getFile(WEBPACK_CONFIG_PATH)).toContain('extractComments');
|
|
121
|
+
expect(result.getFile(RSPACK_CONFIG_PATH)).toContain('extractComments');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should print the extractComments block with matching formatting', () => {
|
|
125
|
+
const context = new Context('/virtual');
|
|
126
|
+
context.addFile(WEBPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
127
|
+
|
|
128
|
+
const result = migrate(context);
|
|
129
|
+
|
|
130
|
+
expect(result.getFile(WEBPACK_CONFIG_PATH)).toBe(MIGRATED_BUNDLER_CONFIG);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should be idempotent', async () => {
|
|
134
|
+
const context = new Context('/virtual');
|
|
135
|
+
context.addFile(WEBPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
136
|
+
context.addFile(RSPACK_CONFIG_PATH, BUNDLER_CONFIG);
|
|
137
|
+
|
|
138
|
+
await expect(migrate).toBeIdempotent(context);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should not modify a config with a pre-existing extractComments setting', () => {
|
|
142
|
+
const customizedConfig = BUNDLER_CONFIG.replace(
|
|
143
|
+
'terserOptions: {',
|
|
144
|
+
'extractComments: false,\n terserOptions: {'
|
|
145
|
+
);
|
|
146
|
+
const context = new Context('/virtual');
|
|
147
|
+
context.addFile(WEBPACK_CONFIG_PATH, customizedConfig);
|
|
148
|
+
|
|
149
|
+
const result = migrate(context);
|
|
150
|
+
|
|
151
|
+
expect(result.getFile(WEBPACK_CONFIG_PATH)).toBe(customizedConfig);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should do nothing when no bundler config exists', () => {
|
|
155
|
+
const context = new Context('/virtual');
|
|
156
|
+
|
|
157
|
+
const result = migrate(context);
|
|
158
|
+
|
|
159
|
+
expect(result.hasChanges()).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should not modify a config without a TerserPlugin', () => {
|
|
163
|
+
const context = new Context('/virtual');
|
|
164
|
+
context.addFile(WEBPACK_CONFIG_PATH, NO_TERSER_CONFIG);
|
|
165
|
+
|
|
166
|
+
const result = migrate(context);
|
|
167
|
+
|
|
168
|
+
expect(result.getFile(WEBPACK_CONFIG_PATH)).toBe(NO_TERSER_CONFIG);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import * as recast from 'recast';
|
|
3
|
+
import type { Context } from '../../context.js';
|
|
4
|
+
import { migrationsDebug } from '../../utils.js';
|
|
5
|
+
import { findObjectProperty, parseAsTypescript, printAST } from '../../utils.ast.js';
|
|
6
|
+
|
|
7
|
+
const { builders } = recast.types;
|
|
8
|
+
|
|
9
|
+
const BUNDLER_CONFIG_PATHS = [
|
|
10
|
+
join('.config', 'webpack', 'webpack.config.ts'),
|
|
11
|
+
join('.config', 'rspack', 'rspack.config.ts'),
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export default function migrate(context: Context): Context {
|
|
15
|
+
for (const configPath of BUNDLER_CONFIG_PATHS) {
|
|
16
|
+
migrateBundlerConfig(context, configPath);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function migrateBundlerConfig(context: Context, configPath: string): void {
|
|
23
|
+
if (!context.doesFileExist(configPath)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const source = context.getFile(configPath);
|
|
28
|
+
if (!source) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Any existing mention of extractComments (including user-supplied values
|
|
33
|
+
// like `extractComments: false`) means we leave the file untouched.
|
|
34
|
+
if (source.includes('extractComments')) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const parsed = parseAsTypescript(source);
|
|
39
|
+
if (!parsed.success) {
|
|
40
|
+
migrationsDebug(`Failed to parse ${configPath}. Error: ${parsed.error.message}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let hasChanges = false;
|
|
45
|
+
|
|
46
|
+
recast.visit(parsed.ast, {
|
|
47
|
+
visitNewExpression(path) {
|
|
48
|
+
const { node } = path;
|
|
49
|
+
|
|
50
|
+
if (node.callee.type === 'Identifier' && node.callee.name === 'TerserPlugin' && node.arguments.length > 0) {
|
|
51
|
+
const optionsArg = node.arguments[0];
|
|
52
|
+
|
|
53
|
+
if (optionsArg.type === 'ObjectExpression' && !findObjectProperty(optionsArg, 'extractComments')) {
|
|
54
|
+
const extractCommentsProperty = builders.property(
|
|
55
|
+
'init',
|
|
56
|
+
builders.identifier('extractComments'),
|
|
57
|
+
builders.objectExpression([
|
|
58
|
+
builders.property('init', builders.identifier('banner'), builders.literal(false)),
|
|
59
|
+
builders.property('init', builders.identifier('filename'), builders.literal('LICENSE.txt')),
|
|
60
|
+
])
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
optionsArg.properties.unshift(extractCommentsProperty);
|
|
64
|
+
hasChanges = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return this.traverse(path);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (hasChanges) {
|
|
73
|
+
context.updateFile(configPath, printAST(parsed.ast));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { gte, lt } from 'semver';
|
|
2
2
|
|
|
3
3
|
import { basename } from 'node:path';
|
|
4
|
-
import { findUpSync } from 'find-up';
|
|
4
|
+
import { findUpSync } from '@libs/find-up';
|
|
5
5
|
import { getPackageJson } from './utils.packagejson.js';
|
|
6
6
|
import { spawnSync } from 'node:child_process';
|
|
7
7
|
|
|
@@ -7,7 +7,7 @@ services:
|
|
|
7
7
|
context: .
|
|
8
8
|
args:
|
|
9
9
|
grafana_image: ${GRAFANA_IMAGE:-{{~grafanaImage~}} }
|
|
10
|
-
grafana_version: ${GRAFANA_VERSION:-13.0
|
|
10
|
+
grafana_version: ${GRAFANA_VERSION:-13.1.0}
|
|
11
11
|
development: ${DEVELOPMENT:-false}
|
|
12
12
|
anonymous_auth_enabled: ${ANONYMOUS_AUTH_ENABLED:-true}
|
|
13
13
|
ports:
|
|
@@ -118,6 +118,11 @@ const config = async (env): Promise<Configuration> => {
|
|
|
118
118
|
minimize: Boolean(env.production),
|
|
119
119
|
minimizer: [
|
|
120
120
|
new TerserPlugin({
|
|
121
|
+
// Emit a single LICENSE.txt file for all comments.
|
|
122
|
+
extractComments: {
|
|
123
|
+
banner: false,
|
|
124
|
+
filename: 'LICENSE.txt',
|
|
125
|
+
},
|
|
121
126
|
terserOptions: {
|
|
122
127
|
format: {
|
|
123
128
|
comments: (_, { type, value }) => type === 'comment2' && value.trim().startsWith('[create-plugin]'),
|
|
@@ -130,6 +130,11 @@ const config = async (env: Env): Promise<Configuration> => {
|
|
|
130
130
|
minimize: Boolean(env.production),
|
|
131
131
|
minimizer: [
|
|
132
132
|
new TerserPlugin({
|
|
133
|
+
// Emit a single LICENSE.txt file for all comments.
|
|
134
|
+
extractComments: {
|
|
135
|
+
banner: false,
|
|
136
|
+
filename: 'LICENSE.txt',
|
|
137
|
+
},
|
|
133
138
|
terserOptions: {
|
|
134
139
|
format: {
|
|
135
140
|
comments: (_, { type, value }) => type === 'comment2' && value.trim().startsWith('[create-plugin]'),
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@emotion/css": "11.10.6",
|
|
77
|
-
"@grafana/data": "13.0
|
|
78
|
-
"@grafana/i18n": "13.0
|
|
79
|
-
"@grafana/runtime": "13.0
|
|
80
|
-
"@grafana/ui": "13.0
|
|
81
|
-
"@grafana/schema": "13.0
|
|
77
|
+
"@grafana/data": "13.1.0",
|
|
78
|
+
"@grafana/i18n": "13.1.0",
|
|
79
|
+
"@grafana/runtime": "13.1.0",
|
|
80
|
+
"@grafana/ui": "13.1.0",
|
|
81
|
+
"@grafana/schema": "13.1.0",{{#if_eq pluginType "scenesapp" }}
|
|
82
82
|
"@grafana/scenes": "{{ scenesVersion }}",{{/if_eq}}
|
|
83
83
|
"react": "^18.3.0",
|
|
84
84
|
"react-dom": "^18.3.0"{{#if isAppType}},
|