Skip to content
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
5 changes: 5 additions & 0 deletions .changeset/yellow-bees-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@saleor/app-sdk": patch
---

Added new API for communication around forms (TODO)
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,5 @@ dist

.idea/
.vscode/

coverage.json
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Supports Saleor version 3.20+
- Create a legacy release branch (e.g. `v1.x` branch)
- Mark changeset to `main` with `major` change, which will start counting next `main` releases as `2.x.x`
- Do not merge release PR until it's ready to be merged

### Deploying test snapshots

PRs can be pushed to NPM by adding label to PR `release dev tag`. Workflow will run and print version that has been released.
Expand Down
4 changes: 2 additions & 2 deletions src/APL/redis/redis-apl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe("RedisAPL", () => {
await defaultApl.get(mockAuthData.saleorApiUrl);
expect(mockRedisClient.hGet).toHaveBeenCalledWith(
"saleor_app_auth",
mockAuthData.saleorApiUrl
mockAuthData.saleorApiUrl,
);
});
});
Expand Down Expand Up @@ -117,7 +117,7 @@ describe("RedisAPL", () => {
expect(mockHSet).toHaveBeenCalledWith(
mockHashKey,
mockAuthData.saleorApiUrl,
JSON.stringify(mockAuthData)
JSON.stringify(mockAuthData),
);
});

Expand Down
10 changes: 5 additions & 5 deletions src/APL/redis/redis-apl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class RedisAPL implements APL {

throw e;
}
}
},
);
}

Expand All @@ -136,7 +136,7 @@ export class RedisAPL implements APL {
await this.client.hSet(
this.hashCollectionKey,
authData.saleorApiUrl,
JSON.stringify(authData)
JSON.stringify(authData),
);

this.debug("Successfully set auth data in Redis");
Expand All @@ -155,7 +155,7 @@ export class RedisAPL implements APL {

throw e;
}
}
},
);
}

Expand Down Expand Up @@ -193,7 +193,7 @@ export class RedisAPL implements APL {

throw e;
}
}
},
);
}

Expand Down Expand Up @@ -232,7 +232,7 @@ export class RedisAPL implements APL {

throw e;
}
}
},
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/APL/saleor-cloud/paginator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class Paginator<ResultType> {
constructor(
private readonly url: string,
private readonly fetchOptions: RequestInit,
private readonly fetchFn = fetch
private readonly fetchFn = fetch,
) {}

public async fetchAll() {
Expand Down
5 changes: 4 additions & 1 deletion src/APL/saleor-cloud/saleor-cloud-apl-errors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export class SaleorCloudAplError extends Error {
constructor(public code: string, message: string) {
constructor(
public code: string,
message: string,
) {
super(message);
this.name = "SaleorCloudAplError";
}
Expand Down
6 changes: 3 additions & 3 deletions src/APL/vercel-kv/vercel-kv-apl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class VercelKvApl implements APL {

throw e;
}
}
},
);
}

Expand Down Expand Up @@ -118,7 +118,7 @@ export class VercelKvApl implements APL {

throw e;
}
}
},
);
}

Expand Down Expand Up @@ -157,7 +157,7 @@ export class VercelKvApl implements APL {

throw e;
}
}
},
);
}

Expand Down
36 changes: 36 additions & 0 deletions src/app-bridge/actions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,42 @@ describe("actions.ts", () => {
});
});

describe("actions.FormPayloadUpdate", () => {
it("Constructs action with \"formPayloadUpdate\" type, random id and payload for product translation", () => {
const payload = {
form: "product-translate" as const,
fields: {
productName: { value: "Updated Product Name" },
productDescription: { value: "Updated Description" },
seoName: { value: "Updated SEO Name" },
},
};

const action = actions.FormPayloadUpdate(payload);

expect(action.type).toBe("formPayloadUpdate");
expect(action.payload.actionId).toEqual(expect.any(String));
expect(action.payload).toEqual(expect.objectContaining(payload));
});

it("Constructs action with field value results", () => {
const payload = {
form: "product-translate" as const,
fields: {
productName: { value: "New Name" },
productDescription: { value: "New Description" },
seoName: { value: "New SEO" },
seoDescription: { value: "New SEO Description" },
},
};

const action = actions.FormPayloadUpdate(payload);

expect(action.payload.fields.productName).toEqual({ value: "New Name" });
expect(action.payload.fields.productDescription).toEqual({ value: "New Description" });
});
});

it("Throws custom error if crypto is not available", () => {
vi.stubGlobal("crypto", {
...globalThis.crypto,
Expand Down
26 changes: 26 additions & 0 deletions src/app-bridge/actions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {
AllFormPayloadUpdatePayloads,
formPayloadUpdateActionName,
} from "@/app-bridge/form-payload";

import { AppPermission } from "../types";
import { Values } from "./helpers";

Expand Down Expand Up @@ -25,6 +30,12 @@ export const ActionType = {
* Available from 3.15
*/
requestPermission: "requestPermissions",
/**
* Apply form fields in active context.
*
* EXPERIMENTAL
*/
formPayloadUpdate: formPayloadUpdateActionName,
} as const;

export type ActionType = Values<typeof ActionType>;
Expand Down Expand Up @@ -127,6 +138,11 @@ export type RequestPermissions = ActionWithId<
}
>;

export type FormPayloadUpdate = ActionWithId<
typeof formPayloadUpdateActionName,
AllFormPayloadUpdatePayloads
>;

function createRequestPermissionsAction(
permissions: AppPermission[],
redirectPath: string,
Expand All @@ -140,11 +156,20 @@ function createRequestPermissionsAction(
});
}

function createFormPayloadUpdateAction(payload: AllFormPayloadUpdatePayloads): FormPayloadUpdate {
return withActionId({
type: formPayloadUpdateActionName,
// @ts-ignore - TODO: For some reason TS is failing here, but this is internal implementation so it doesn't change the public API
payload,
});
}

export type Actions =
| RedirectAction
| NotificationAction
| UpdateRouting
| NotifyReady
| FormPayloadUpdate
| RequestPermissions;

export const actions = {
Expand All @@ -153,4 +178,5 @@ export const actions = {
UpdateRouting: createUpdateRoutingAction,
NotifyReady: createNotifyReadyAction,
RequestPermissions: createRequestPermissionsAction,
FormPayloadUpdate: createFormPayloadUpdateAction,
};
4 changes: 2 additions & 2 deletions src/app-bridge/app-bridge-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function AppBridgeProvider({ appBridgeInstance, ...props }: React.PropsWi
appBridge,
mounted: true,
}),
[appBridge]
[appBridge],
);

return <AppContext.Provider value={contextValue} {...props} />;
Expand All @@ -51,7 +51,7 @@ export function AppBridgeProvider({ appBridgeInstance, ...props }: React.PropsWi
export const useAppBridge = () => {
const { appBridge, mounted } = useContext(AppContext);
const [appBridgeState, setAppBridgeState] = useState<AppBridgeState | null>(() =>
appBridge ? appBridge.getState() : null
appBridge ? appBridge.getState() : null,
);

if (typeof window !== "undefined" && !mounted) {
Expand Down
3 changes: 3 additions & 0 deletions src/app-bridge/app-bridge-state.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AllFormPayloads } from "@/app-bridge/form-payload";

import { LocaleCode } from "../locales";
import { AppPermission, Permission } from "../types";
import { ThemeType } from "./events";
Expand All @@ -24,6 +26,7 @@ export type AppBridgeState = {
email: string;
};
appPermissions?: AppPermission[];
formContext?: AllFormPayloads;
};

type Options = {
Expand Down
Loading
Loading