@grafana/create-plugin 6.5.0-canary.2320.20267963205.0 → 6.5.0-canary.2320.20268376971.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/codemods/additions/scripts/i18n/code-generation.js +8 -8
- package/dist/codemods/additions/scripts/i18n/tooling.js +6 -4
- package/dist/codemods/additions/scripts/i18n/utils.js +8 -2
- package/package.json +2 -2
- package/src/codemods/AGENTS.md +1 -1
- package/src/codemods/additions/scripts/i18n/README.md +1 -1
- package/src/codemods/additions/scripts/i18n/code-generation.ts +12 -10
- package/src/codemods/additions/scripts/i18n/tooling.ts +9 -5
- package/src/codemods/additions/scripts/i18n/utils.ts +11 -2
|
@@ -54,23 +54,23 @@ function addI18nInitialization(context, needsBackwardCompatibility) {
|
|
|
54
54
|
)
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
ast.program.body.splice(
|
|
57
|
+
const lastImportIndex = ast.program.body.findLastIndex((node) => node.type === "ImportDeclaration");
|
|
58
|
+
if (lastImportIndex !== -1) {
|
|
59
|
+
ast.program.body.splice(lastImportIndex + 1, 0, ...imports);
|
|
60
60
|
} else {
|
|
61
61
|
ast.program.body.unshift(...imports);
|
|
62
62
|
}
|
|
63
63
|
const i18nInitCode = needsBackwardCompatibility ? `// Before Grafana version 12.1.0 the plugin is responsible for loading translation resources
|
|
64
64
|
// In Grafana version 12.1.0 and later Grafana is responsible for loading translation resources
|
|
65
|
-
const loaders = semver.lt(config?.buildInfo?.version, '12.1.0') ? [loadResources] : [];
|
|
65
|
+
const loaders = semver.lt(config?.buildInfo?.version || '0.0.0', '12.1.0') ? [loadResources] : [];
|
|
66
66
|
|
|
67
67
|
await initPluginTranslations(pluginJson.id, loaders);` : `await initPluginTranslations(pluginJson.id);`;
|
|
68
68
|
const initAst = recast.parse(i18nInitCode, {
|
|
69
69
|
parser: babelParser
|
|
70
70
|
});
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
ast.program.body.splice(
|
|
71
|
+
const finalLastImportIndex = ast.program.body.findLastIndex((node) => node.type === "ImportDeclaration");
|
|
72
|
+
if (finalLastImportIndex !== -1) {
|
|
73
|
+
ast.program.body.splice(finalLastImportIndex + 1, 0, ...initAst.program.body);
|
|
74
74
|
} else {
|
|
75
75
|
ast.program.body.unshift(...initAst.program.body);
|
|
76
76
|
}
|
|
@@ -100,7 +100,7 @@ function createLoadResourcesFile(context) {
|
|
|
100
100
|
import pluginJson from 'plugin.json';
|
|
101
101
|
|
|
102
102
|
const resources = LANGUAGES.reduce<Record<string, () => Promise<{ default: Resources }>>>((acc, lang) => {
|
|
103
|
-
acc[lang.code] =
|
|
103
|
+
acc[lang.code] = () => import(\`./locales/\${lang.code}/\${pluginJson.id}.json\`);
|
|
104
104
|
return acc;
|
|
105
105
|
}, {});
|
|
106
106
|
|
|
@@ -52,13 +52,15 @@ function updateEslintConfig(context) {
|
|
|
52
52
|
});
|
|
53
53
|
const imports = ast.program.body.filter((node) => node.type === "ImportDeclaration");
|
|
54
54
|
const lastImport = imports[imports.length - 1];
|
|
55
|
+
const pluginImport = builders.importDeclaration(
|
|
56
|
+
[builders.importDefaultSpecifier(builders.identifier("grafanaI18nPlugin"))],
|
|
57
|
+
builders.literal("@grafana/i18n/eslint-plugin")
|
|
58
|
+
);
|
|
55
59
|
if (lastImport) {
|
|
56
|
-
const pluginImport = builders.importDeclaration(
|
|
57
|
-
[builders.importDefaultSpecifier(builders.identifier("grafanaI18nPlugin"))],
|
|
58
|
-
builders.literal("@grafana/i18n/eslint-plugin")
|
|
59
|
-
);
|
|
60
60
|
const lastImportIndex = ast.program.body.indexOf(lastImport);
|
|
61
61
|
ast.program.body.splice(lastImportIndex + 1, 0, pluginImport);
|
|
62
|
+
} else {
|
|
63
|
+
ast.program.body.unshift(pluginImport);
|
|
62
64
|
}
|
|
63
65
|
recast.visit(ast, {
|
|
64
66
|
visitCallExpression(path) {
|
|
@@ -31,11 +31,17 @@ Update your package.json to use "react": "^18.3.0" and "react-dom": "^18.3.0".`
|
|
|
31
31
|
function checkNeedsBackwardCompatibility(context) {
|
|
32
32
|
const pluginJsonRaw = context.getFile("src/plugin.json");
|
|
33
33
|
if (!pluginJsonRaw) {
|
|
34
|
-
return
|
|
34
|
+
return true;
|
|
35
35
|
}
|
|
36
36
|
try {
|
|
37
37
|
const pluginJson = JSON.parse(pluginJsonRaw);
|
|
38
|
-
const currentGrafanaDep = pluginJson.dependencies?.grafanaDependency
|
|
38
|
+
const currentGrafanaDep = pluginJson.dependencies?.grafanaDependency;
|
|
39
|
+
if (!currentGrafanaDep) {
|
|
40
|
+
additionsDebug(
|
|
41
|
+
"Warning: grafanaDependency is missing from plugin.json. Assuming backward compatibility mode is needed."
|
|
42
|
+
);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
39
45
|
const minVersion = coerce("12.1.0");
|
|
40
46
|
const currentVersion = coerce(currentGrafanaDep.replace(/^[><=]+/, ""));
|
|
41
47
|
if (currentVersion && minVersion && gte(currentVersion, minVersion)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/create-plugin",
|
|
3
|
-
"version": "6.5.0-canary.2320.
|
|
3
|
+
"version": "6.5.0-canary.2320.20268376971.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"directory": "packages/create-plugin",
|
|
6
6
|
"url": "https://github.com/grafana/plugin-tools"
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"engines": {
|
|
57
57
|
"node": ">=20"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "47d4c2ff4f55df3a644771982994d0c85ec7d96d"
|
|
60
60
|
}
|
package/src/codemods/AGENTS.md
CHANGED
|
@@ -38,7 +38,7 @@ Additions are optional features that developers choose to add via `create-plugin
|
|
|
38
38
|
### Addition Behavior
|
|
39
39
|
|
|
40
40
|
- Additions add new features or capabilities to a plugin (e.g., i18n support, testing frameworks, etc.)
|
|
41
|
-
-
|
|
41
|
+
- It should be safe to run multiple times
|
|
42
42
|
- Always use defensive programming: check if features already exist before adding them
|
|
43
43
|
- Use `additionsDebug()` for logging to help with troubleshooting
|
|
44
44
|
- If the addition accepts user input, export a `schema` object using `valibot` for input validation
|
|
@@ -10,7 +10,7 @@ npx @grafana/create-plugin add i18n --locales <locales>
|
|
|
10
10
|
|
|
11
11
|
## Requirements
|
|
12
12
|
|
|
13
|
-
- **Grafana >= 11.0.0**: i18n is not supported for Grafana versions prior to 11.0.0. If your plugin's `grafanaDependency` is set to a version < 11.0.0, the script will automatically update it to `>=11.0.0
|
|
13
|
+
- **Grafana >= 11.0.0**: i18n is not supported for Grafana versions prior to 11.0.0. If your plugin's `grafanaDependency` is set to a version < 11.0.0, the script will automatically update it to `>=11.0.0` (it will not exit with an error).
|
|
14
14
|
- **React >= 18**: The `@grafana/i18n` package requires React 18 or higher. If your plugin uses React < 18, the script will exit with an error and prompt you to upgrade.
|
|
15
15
|
|
|
16
16
|
## Required Flags
|
|
@@ -73,10 +73,12 @@ export function addI18nInitialization(context: Context, needsBackwardCompatibili
|
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
//
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
// Find the last import index (use consistent approach for both imports and initialization)
|
|
77
|
+
const lastImportIndex = ast.program.body.findLastIndex((node: any) => node.type === 'ImportDeclaration');
|
|
78
|
+
|
|
79
|
+
// Add imports after the last import statement
|
|
80
|
+
if (lastImportIndex !== -1) {
|
|
81
|
+
ast.program.body.splice(lastImportIndex + 1, 0, ...imports);
|
|
80
82
|
} else {
|
|
81
83
|
ast.program.body.unshift(...imports);
|
|
82
84
|
}
|
|
@@ -85,7 +87,7 @@ export function addI18nInitialization(context: Context, needsBackwardCompatibili
|
|
|
85
87
|
const i18nInitCode = needsBackwardCompatibility
|
|
86
88
|
? `// Before Grafana version 12.1.0 the plugin is responsible for loading translation resources
|
|
87
89
|
// In Grafana version 12.1.0 and later Grafana is responsible for loading translation resources
|
|
88
|
-
const loaders = semver.lt(config?.buildInfo?.version, '12.1.0') ? [loadResources] : [];
|
|
90
|
+
const loaders = semver.lt(config?.buildInfo?.version || '0.0.0', '12.1.0') ? [loadResources] : [];
|
|
89
91
|
|
|
90
92
|
await initPluginTranslations(pluginJson.id, loaders);`
|
|
91
93
|
: `await initPluginTranslations(pluginJson.id);`;
|
|
@@ -95,10 +97,10 @@ await initPluginTranslations(pluginJson.id, loaders);`
|
|
|
95
97
|
parser: babelParser,
|
|
96
98
|
});
|
|
97
99
|
|
|
98
|
-
// Find the last import index
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
-
ast.program.body.splice(
|
|
100
|
+
// Find the last import index again (after adding new imports)
|
|
101
|
+
const finalLastImportIndex = ast.program.body.findLastIndex((node: any) => node.type === 'ImportDeclaration');
|
|
102
|
+
if (finalLastImportIndex !== -1) {
|
|
103
|
+
ast.program.body.splice(finalLastImportIndex + 1, 0, ...initAst.program.body);
|
|
102
104
|
} else {
|
|
103
105
|
ast.program.body.unshift(...initAst.program.body);
|
|
104
106
|
}
|
|
@@ -135,7 +137,7 @@ export function createLoadResourcesFile(context: Context): void {
|
|
|
135
137
|
import pluginJson from 'plugin.json';
|
|
136
138
|
|
|
137
139
|
const resources = LANGUAGES.reduce<Record<string, () => Promise<{ default: Resources }>>>((acc, lang) => {
|
|
138
|
-
acc[lang.code] =
|
|
140
|
+
acc[lang.code] = () => import(\`./locales/\${lang.code}/\${pluginJson.id}.json\`);
|
|
139
141
|
return acc;
|
|
140
142
|
}, {});
|
|
141
143
|
|
|
@@ -73,14 +73,18 @@ export function updateEslintConfig(context: Context): void {
|
|
|
73
73
|
const imports = ast.program.body.filter((node: any) => node.type === 'ImportDeclaration');
|
|
74
74
|
const lastImport = imports[imports.length - 1];
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
// Always create the plugin import
|
|
77
|
+
const pluginImport = builders.importDeclaration(
|
|
78
|
+
[builders.importDefaultSpecifier(builders.identifier('grafanaI18nPlugin'))],
|
|
79
|
+
builders.literal('@grafana/i18n/eslint-plugin')
|
|
80
|
+
);
|
|
81
81
|
|
|
82
|
+
if (lastImport) {
|
|
82
83
|
const lastImportIndex = ast.program.body.indexOf(lastImport);
|
|
83
84
|
ast.program.body.splice(lastImportIndex + 1, 0, pluginImport);
|
|
85
|
+
} else {
|
|
86
|
+
// No imports found, insert at the beginning
|
|
87
|
+
ast.program.body.unshift(pluginImport);
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
// Find the defineConfig array and add the plugin config
|
|
@@ -43,12 +43,21 @@ export function checkReactVersion(context: Context): void {
|
|
|
43
43
|
export function checkNeedsBackwardCompatibility(context: Context): boolean {
|
|
44
44
|
const pluginJsonRaw = context.getFile('src/plugin.json');
|
|
45
45
|
if (!pluginJsonRaw) {
|
|
46
|
-
|
|
46
|
+
// Default to backward compat for safety when plugin.json is missing
|
|
47
|
+
return true;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
try {
|
|
50
51
|
const pluginJson = JSON.parse(pluginJsonRaw);
|
|
51
|
-
const currentGrafanaDep = pluginJson.dependencies?.grafanaDependency
|
|
52
|
+
const currentGrafanaDep = pluginJson.dependencies?.grafanaDependency;
|
|
53
|
+
|
|
54
|
+
if (!currentGrafanaDep) {
|
|
55
|
+
additionsDebug(
|
|
56
|
+
'Warning: grafanaDependency is missing from plugin.json. Assuming backward compatibility mode is needed.'
|
|
57
|
+
);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
const minVersion = coerce('12.1.0');
|
|
53
62
|
const currentVersion = coerce(currentGrafanaDep.replace(/^[><=]+/, ''));
|
|
54
63
|
|