Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for importing SVG, PNG, and JPEG files directly #2284

Merged
merged 6 commits into from
Mar 18, 2024
Merged
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
2 changes: 1 addition & 1 deletion packages/examples/packages/images/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/snaps.git"
},
"source": {
"shasum": "UKBWUM+VMGi3YPuP2zhT3fpfB5MgN7muuU2MBaW5964=",
"shasum": "6hmcWrwBG05b5UlKIzJppBhfqqi+C/YxFSQgJrFjh64=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/examples/packages/images/src/images/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 62 additions & 6 deletions packages/examples/packages/images/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('onRpcRequest', () => {

describe('getQrCode', () => {
it('generates a QR code for the given data', async () => {
const { request, close } = await installSnap();
const { request } = await installSnap();

const response = request({
method: 'getQrCode',
Expand All @@ -46,16 +46,14 @@ describe('onRpcRequest', () => {
await ui.ok();

expect(await response).toRespondWith(null);

await close();
});
});

describe('getCat', () => {
// This test is flaky so we disable it for now
// This test is flaky, so we disable it for now.
// eslint-disable-next-line jest/no-disabled-tests
it.skip('shows a cat', async () => {
Mrtenz marked this conversation as resolved.
Show resolved Hide resolved
const { request, close } = await installSnap();
const { request } = await installSnap();

const response = request({
method: 'getCat',
Expand Down Expand Up @@ -84,8 +82,66 @@ describe('onRpcRequest', () => {
await ui.ok();

expect(await response).toRespondWith(null);
});
});

describe('getSvgIcon', () => {
it('shows an SVG icon', async () => {
const { request } = await installSnap();

const response = request({
method: 'getSvgIcon',
});

const ui = await response.getInterface();
// eslint-disable-next-line jest/prefer-strict-equal
expect(ui.content).toEqual({
type: 'panel',
children: [
{
type: 'text',
value: 'Here is an SVG icon:',
},
{
type: 'image',
value: expect.stringContaining('<svg'),
},
],
});

await ui.ok();

expect(await response).toRespondWith(null);
});
});

describe('getPngIcon', () => {
it('shows a PNG icon', async () => {
const { request } = await installSnap();

await close();
const response = request({
method: 'getPngIcon',
});

const ui = await response.getInterface();
// eslint-disable-next-line jest/prefer-strict-equal
expect(ui.content).toEqual({
type: 'panel',
children: [
{
type: 'text',
value: 'Here is a PNG icon:',
},
{
type: 'image',
value: expect.stringContaining('data:image/png;base64'),
},
],
});

await ui.ok();

expect(await response).toRespondWith(null);
});
});
});
29 changes: 29 additions & 0 deletions packages/examples/packages/images/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {
} from '@metamask/snaps-sdk';
import { renderSVG } from 'uqr';

import pngIcon from './images/icon.png';
import svgIcon from './images/icon.svg';

/**
* The parameters for the `getQrCode` method.
*
Expand Down Expand Up @@ -74,6 +77,32 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
});
}

case 'getSvgIcon': {
return await snap.request({
method: 'snap_dialog',
params: {
type: DialogType.Alert,

// `.svg` files are imported as strings, so they can be used directly
// with the `image` component.
content: panel([text('Here is an SVG icon:'), image(svgIcon)]),
},
});
}

case 'getPngIcon': {
return await snap.request({
method: 'snap_dialog',
params: {
type: DialogType.Alert,

// `.png` files are imported as SVGs containing an `<image>` tag,
// so they can be used directly with the `image` component.
content: panel([text('Here is a PNG icon:'), image(pngIcon)]),
},
});
}

default:
throw new MethodNotFoundError({ method: request.method });
}
Expand Down
30 changes: 29 additions & 1 deletion packages/snaps-cli/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { dim } from 'chalk';
import { readFile } from 'fs/promises';
import Module from 'module';
import { basename, dirname, resolve } from 'path';
import type { Infer } from 'superstruct';
import {
array,
boolean,
Expand All @@ -30,6 +29,7 @@ import {
unknown,
empty,
} from 'superstruct';
import type { Infer } from 'superstruct';
import type { Configuration as WebpackConfiguration } from 'webpack';

import { TranspilationModes } from './builders';
Expand Down Expand Up @@ -415,6 +415,27 @@ export type SnapWebpackConfig = {
zlib?: boolean;
};

/**
* Optional features to enable in the CLI.
*
* @example
* {
* features: {
* images: true,
* }
* }
*/
features?: {
/**
* Whether to enable support for images. If `true`, the Webpack
* configuration will be modified to support images. If `false`, the
* Webpack configuration will not be modified.
*
* @default true
*/
images?: boolean;
};

/**
* A function to customize the Webpack configuration used to build the snap.
* This function will be called with the default Webpack configuration, and
Expand Down Expand Up @@ -618,6 +639,13 @@ export const SnapsWebpackConfigStruct = object({
false,
),

features: defaulted(
object({
images: defaulted(boolean(), true),
}),
{},
),

customizeWebpackConfig: optional(
SnapsWebpackCustomizeWebpackConfigFunctionStruct,
),
Expand Down
2 changes: 1 addition & 1 deletion packages/snaps-cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ export type {
} from './webpack';

// Re-exported from `snaps-cli` for convenience.
export { merge } from 'webpack-merge';
export { merge, mergeWithCustomize, mergeWithRules } from 'webpack-merge';
Loading
Loading