Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions packages/create-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,45 @@ For more information see our [documentation](https://grafana.com/developers/plug

---

## Add optional features to your existing plugin

You can add optional features to your plugin using the `add` command. This allows you to enhance your plugin with additional capabilities without starting from scratch.

### Add internationalization (i18n) support

Add translation support to make your plugin available in multiple languages:

```bash
# Run this command from the root of your plugin
cd ./my-plugin

npx @grafana/create-plugin@latest add i18n
```

This will:

- Update your `plugin.json` with the selected languages
- Create locale folders and translation files
- Add the necessary dependencies to `package.json`
- Configure your docker-compose.yaml with the required feature toggle
- Add i18n imports to your module file
- Set up the i18n extraction script

The command will prompt you to select which locales you want to support. You can choose from common locales like:

- English (US) - `en-US`
- Spanish (Spain) - `es-ES`
- French (France) - `fr-FR`
- German (Germany) - `de-DE`
- Swedish (Sweden) - `sv-SE`
- And more...

You can also add custom locale codes during the interactive prompt.

For more information about plugin internationalization, see our [documentation](https://grafana.com/developers/plugin-tools/how-to-guides/plugin-internationalization).

---

## Contributing

We are always grateful for contributions! See [CONTRIBUTING.md](../../CONTRIBUTING.md) for more information.
19 changes: 19 additions & 0 deletions packages/create-plugin/src/additions/additions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export type AdditionMeta = {
name: string;
description: string;
scriptPath: string;
};

type Additions = {
additions: Record<string, AdditionMeta>;
};

export default {
additions: {
i18n: {
name: 'i18n',
description: 'Add internationalization (i18n) support to your plugin',
scriptPath: './scripts/add-i18n.js',
},
},
} as Additions;
77 changes: 77 additions & 0 deletions packages/create-plugin/src/additions/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { additionsDebug, flushChanges, formatFiles, installNPMDependencies, printChanges } from './utils.js';
import defaultAdditions, { AdditionMeta } from './additions.js';

import { Context } from '../migrations/context.js';
import { gitCommitNoVerify } from '../utils/utils.git.js';
import { output } from '../utils/utils.console.js';

export type AdditionFn = (context: Context, options?: AdditionOptions) => Context | Promise<Context>;

export type AdditionOptions = Record<string, any>;

type RunAdditionOptions = {
commitChanges?: boolean;
};

export function getAvailableAdditions(
additions: Record<string, AdditionMeta> = defaultAdditions.additions
): Record<string, AdditionMeta> {
return additions;
}

export function getAdditionByName(
name: string,
additions: Record<string, AdditionMeta> = defaultAdditions.additions
): AdditionMeta | undefined {
return additions[name];
}

export async function runAddition(
addition: AdditionMeta,
additionOptions: AdditionOptions = {},
runOptions: RunAdditionOptions = {}
): Promise<void> {
const basePath = process.cwd();

output.log({
title: `Running addition: ${addition.name}`,
body: [addition.description],
});

try {
const context = new Context(basePath);
const updatedContext = await executeAddition(addition, context, additionOptions);
const shouldCommit = runOptions.commitChanges && updatedContext.hasChanges();

additionsDebug(`context for "${addition.name} (${addition.scriptPath})":`);
additionsDebug('%O', updatedContext.listChanges());

await formatFiles(updatedContext);
flushChanges(updatedContext);
printChanges(updatedContext, addition.name, addition);

installNPMDependencies(updatedContext);

if (shouldCommit) {
await gitCommitNoVerify(`chore: add ${addition.name} support via create-plugin`);
}

output.success({
title: `Successfully added ${addition.name} to your plugin.`,
});
} catch (error) {
if (error instanceof Error) {
throw new Error(`Error running addition "${addition.name} (${addition.scriptPath})": ${error.message}`);
}
throw error;
}
}

export async function executeAddition(
addition: AdditionMeta,
context: Context,
options: AdditionOptions = {}
): Promise<Context> {
const module: { default: AdditionFn } = await import(addition.scriptPath);
return module.default(context, options);
}
Loading
Loading