Skip to content

Upgrade to @figma/plugin-api 1.71 via a series of other changes (Original PR: react-figma#66) #1

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

Merged
merged 4 commits into from
Aug 18, 2023
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
6,746 changes: 6,746 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

17 changes: 8 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"build:clean": "rimraf dist",
"build:lib": "cross-env BABEL_ENV=production tsc -p tsconfig.build.json",
"prepublishOnly": "npm run build",
"test": "jest"
"test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js"
},
"jest": {
"preset": "ts-jest/presets/js-with-babel"
"preset": "ts-jest/presets/default-esm"
},
"pre-commit": [
"prettify",
Expand All @@ -35,18 +35,17 @@
},
"homepage": "https://github.com/react-figma/figma-api-stub#readme",
"devDependencies": {
"@figma/plugin-typings": "^1.42.1",
"@types/jest": "^24.0.23",
"@figma/plugin-typings": "~1.71.1",
"@types/jest": "^29.5.3",
"cross-env": "^6.0.3",
"jest": "^24.9.0",
"jest": "^29.6.1",
"pre-commit": "^1.2.2",
"prettier": "^1.18.2",
"rimraf": "^3.0.0",
"ts-jest": "^24.2.0",
"typescript": "3.5.3"
"ts-jest": "^29.1.1",
"typescript": "^5.0.0"
},
"dependencies": {
"nanoid": "^3.1.20",
"rxjs": "^6.5.3"
"nanoid": "^4.0.2"
}
}
5 changes: 4 additions & 1 deletion src/__tests__/page.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ describe("page ", () => {
page.backgrounds = [
{
type: "GRADIENT_LINEAR",
gradientTransform: [[0, 0, 0], [0, 0, 0]],
gradientTransform: [
[0, 0, 0],
[0, 0, 0]
],
gradientStops: []
}
];
Expand Down
59 changes: 30 additions & 29 deletions src/__tests__/postmessage.test.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
import { createParentPostMessage, createFigma } from "../stubs";
import { Subject } from "rxjs";
import { take } from "rxjs/operators";
import { createFigma, createParentPostMessage } from "../stubs";
import { jest } from "@jest/globals";

describe("postMessage", () => {
beforeEach(() => {
// @ts-ignore
global.figma = createFigma({});
// @ts-ignore
global.parent.postMessage = createParentPostMessage(global.figma);
global.parent = { postMessage: createParentPostMessage(global.figma) };
});

it("UI sends message and plugin receives it", async () => {
const waiting = new Subject();
let resolveWaiting;
const waiting = new Promise<void>(resolve => {
resolveWaiting = resolve;
});
// @ts-ignore
figma.ui.onmessage = jest.fn().mockImplementation(() => waiting.next());
figma.ui.onmessage = jest.fn().mockImplementation(() => {
resolveWaiting();
});
parent.postMessage({ pluginMessage: "abc" }, "*");

return new Promise(resolve => {
waiting.pipe(take(1)).subscribe(() => {
// @ts-ignore
expect(figma.ui.onmessage).toHaveBeenCalledTimes(1);
// @ts-ignore
expect(figma.ui.onmessage).toHaveBeenCalledWith(
"abc",
expect.any(Object)
);
resolve();
});
});
// Wait for post message to fire.
await waiting;

// @ts-ignore
expect(figma.ui.onmessage).toHaveBeenCalledTimes(1);
// @ts-ignore
expect(figma.ui.onmessage).toHaveBeenCalledWith("abc", expect.any(Object));
});

it("Plugin sends message and UI receives it", () => {
const waiting = new Subject();
it("Plugin sends message and UI receives it", async () => {
let resolveWaiting;
const waiting = new Promise<void>(resolve => {
resolveWaiting = resolve;
});

//@ts-ignore
global.onmessage = jest.fn().mockImplementation(() => waiting.next());
// @ts-ignore
global.onmessage = jest.fn().mockImplementation(() => {
resolveWaiting();
});
// @ts-ignore
figma.ui.postMessage("abc");

return new Promise(resolve => {
waiting.pipe(take(1)).subscribe(() => {
//@ts-ignore
expect(global.onmessage).toHaveBeenCalledTimes(1);
resolve();
});
});
await waiting;

//@ts-ignore
expect(global.onmessage).toHaveBeenCalledTimes(1);
});
});

Expand Down
11 changes: 7 additions & 4 deletions src/applyMixins.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
export function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
for (const baseCtor of baseCtors) {
for (const name of Object.getOwnPropertyNames(baseCtor.prototype)) {
if (name === "constructor") {
continue;
}
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name)
);
});
});
}
}
}
5 changes: 2 additions & 3 deletions src/componentStubs.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { TConfig } from "./config";
import { Fonts } from "./fonts";
import { nanoid } from "nanoid";
import { Subject } from "rxjs";

export const selectionChangeSubject = new Subject();
export const selectionChangeEventTarget = new EventTarget();

export class RectangleNodeStub {
constructor(private config: TConfig) {}
Expand Down Expand Up @@ -323,7 +322,7 @@ export class PageNodeStub {

set selection(value) {
this._selection = value;
selectionChangeSubject.next();
selectionChangeEventTarget.dispatchEvent(new Event("selectionchange"));
}

get backgrounds() {
Expand Down
49 changes: 48 additions & 1 deletion src/mixins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ export const getChildrenMixinStub = (config: TConfig) =>
}
return this.children.filter(callback);
}

findWidgetNodesByWidgetId(widgetId: string): WidgetNode[] {
return [];
}
};

export const getBaseNodeMixinStub = (config: TConfig) =>
Expand All @@ -129,6 +133,13 @@ export const getBaseNodeMixinStub = (config: TConfig) =>
pluginData: { [key: string]: string };
sharedPluginData: { [namespace: string]: { [key: string]: string } };

readonly isAsset: boolean;
async getCSSAsync(): Promise<{
[key: string]: string;
}> {
return {};
}

// instance nodes that are cloned from components will have `_orig` set to
// the value of the original node. This is used internally for inheriting
// things like plugin data and relaunch data
Expand Down Expand Up @@ -250,6 +261,25 @@ export const getBaseNodeMixinStub = (config: TConfig) =>
);
}
}

async getDevResourcesAsync(options?: {
includeChildren?: boolean;
}): Promise<DevResourceWithNodeId[]> {
return [];
}
async addDevResourceAsync(url: string, name?: string): Promise<void> {}
async editDevResourceAsync(
currentUrl: string,
newValue: {
name?: string;
url?: string;
}
): Promise<void> {}
async deleteDevResourceAsync(url: string): Promise<void> {}
async setDevResourcePreviewAsync(
url: string,
preview: PlainTextElement
): Promise<void> {}
};

export const getLayoutMixinStub = (config: TConfig) =>
Expand All @@ -269,14 +299,22 @@ export const getLayoutMixinStub = (config: TConfig) =>
x: number;
y: number;
rotation: number;
layoutSizingHorizontal: "FIXED" | "HUG" | "FILL";
layoutSizingVertical: "FIXED" | "HUG" | "FILL";

width: number;
height: number;
minWidth: number | null;
maxWidth: number | null;
minHeight: number | null;
maxHeight: number | null;

constrainProportions: boolean;
layoutAlign: LayoutMixin["layoutAlign"];
layoutPositioning: AutoLayoutChildrenMixin["layoutPositioning"];

absoluteRenderBounds: Rect | null;
absoluteBoundingBox: Rect | null;

resize(width, height) {
if (config.simulateErrors && isInsideInstance(this)) {
Expand Down Expand Up @@ -305,7 +343,16 @@ export const getLayoutMixinStub = (config: TConfig) =>
export class ExportMixinStub implements ExportMixin {
exportSettings: ReadonlyArray<ExportSettings>;

exportAsync(settings?: ExportSettings) {
exportAsync(settings: ExportSettingsSVGString): Promise<string>;
exportAsync(settings: ExportSettingsREST): Promise<Object>;
exportAsync(settings?: ExportSettings): Promise<Uint8Array>;
exportAsync(
settings:
| ExportSettingsSVGString
| ExportSettingsREST
| ExportSettings
| undefined
): Promise<string | Object | Uint8Array> {
// "exportAsync" is not implemented in stubs
return Promise.resolve(new Uint8Array());
}
Expand Down
Loading