}
+ icon={
}
name="Data Importer"
author="By Saleor Commerce"
rightColumnContent={
diff --git a/apps/data-importer/src/setup-tests.ts b/apps/data-importer/src/setup-tests.ts
index 5046278..5f1e198 100644
--- a/apps/data-importer/src/setup-tests.ts
+++ b/apps/data-importer/src/setup-tests.ts
@@ -3,4 +3,4 @@
*
* https://vitest.dev/config/#setupfiles
*/
-export {}
+export {};
diff --git a/apps/invoices/README.md b/apps/invoices/README.md
index 880b7dc..5c24636 100644
--- a/apps/invoices/README.md
+++ b/apps/invoices/README.md
@@ -71,28 +71,31 @@ pnpm dev
### Without CLI
1. Install the dependencies by running:
+
```
pnpm install
```
2. Start the local server with:
+
```
pnpm dev
```
3. Expose local environment using tunnel:
-Use tunneling tools like [localtunnel](https://github.com/localtunnel/localtunnel) or [ngrok](https://ngrok.com/).
+ Use tunneling tools like [localtunnel](https://github.com/localtunnel/localtunnel) or [ngrok](https://ngrok.com/).
4. Install aplication at your dashboard:
If you use Saleor Cloud or your local server is exposed, you can install your app by following this link:
+
```
[YOUR_SALEOR_DASHBOARD_URL]/apps/install?manifestUrl=[YOUR_APP_TUNNEL_MANIFEST_URL]
```
+
This template host manifest at `/api/manifest`
-
-You can also install application using GQL or command line. Follow the guide [how to install your app](https://docs.saleor.io/docs/3.x/developer/extending/apps/installing-apps#installation-using-graphql-api) to learn more.
+You can also install application using GQL or command line. Follow the guide [how to install your app](https://docs.saleor.io/docs/3.x/developer/extending/apps/installing-apps#installation-using-graphql-api) to learn more.
### Generated schema and typings
diff --git a/apps/invoices/src/modules/app-configuration/app-config-input-schema.test.ts b/apps/invoices/src/modules/app-configuration/app-config-input-schema.test.ts
index 5f880cb..ab839f3 100644
--- a/apps/invoices/src/modules/app-configuration/app-config-input-schema.test.ts
+++ b/apps/invoices/src/modules/app-configuration/app-config-input-schema.test.ts
@@ -1,49 +1,49 @@
-import {describe, it, expect} from "vitest";
-import {appConfigInputSchema} from "./app-config-input-schema";
-import {AppConfig, SellerShopConfig} from "./app-config";
-import {getMockAddress} from "../../fixtures/mock-address";
+import { describe, it, expect } from "vitest";
+import { appConfigInputSchema } from "./app-config-input-schema";
+import { AppConfig, SellerShopConfig } from "./app-config";
+import { getMockAddress } from "../../fixtures/mock-address";
describe("appConfigInputSchema", () => {
- it('Passes with no channels at all', () => {
- expect(() =>
- appConfigInputSchema.parse({
- shopConfigPerChannel: {}
- } satisfies AppConfig)
- ).not.to.throw()
- })
+ it("Passes with no channels at all", () => {
+ expect(() =>
+ appConfigInputSchema.parse({
+ shopConfigPerChannel: {},
+ } satisfies AppConfig)
+ ).not.to.throw();
+ });
- it('Passes with all address fields empty', () => {
- expect(() =>
- appConfigInputSchema.parse({
- shopConfigPerChannel: {
- channel: {
- address: {
- city: "",
- cityArea: "",
- companyName: "",
- country: "",
- countryArea: "",
- firstName: "",
- lastName: "",
- postalCode: "",
- streetAddress1: "",
- streetAddress2: ""
+ it("Passes with all address fields empty", () => {
+ expect(() =>
+ appConfigInputSchema.parse({
+ shopConfigPerChannel: {
+ channel: {
+ address: {
+ city: "",
+ cityArea: "",
+ companyName: "",
+ country: "",
+ countryArea: "",
+ firstName: "",
+ lastName: "",
+ postalCode: "",
+ streetAddress1: "",
+ streetAddress2: "",
+ },
+ },
+ },
+ } satisfies AppConfig)
+ ).not.to.throw();
+ });
- }
- }
- }
- } satisfies AppConfig)
- ).not.to.throw()
- })
-
- it('Passes with partial address', () => {
- expect(() =>
- appConfigInputSchema.parse({
- shopConfigPerChannel: {
- channel: {
- address: getMockAddress() }
- }
- } satisfies AppConfig)
- ).not.to.throw()
- })
-})
\ No newline at end of file
+ it("Passes with partial address", () => {
+ expect(() =>
+ appConfigInputSchema.parse({
+ shopConfigPerChannel: {
+ channel: {
+ address: getMockAddress(),
+ },
+ },
+ } satisfies AppConfig)
+ ).not.to.throw();
+ });
+});
diff --git a/apps/invoices/src/modules/invoice-number-generator/invoice-number-generator.ts b/apps/invoices/src/modules/invoice-number-generator/invoice-number-generator.ts
index ab84cff..25de828 100644
--- a/apps/invoices/src/modules/invoice-number-generator/invoice-number-generator.ts
+++ b/apps/invoices/src/modules/invoice-number-generator/invoice-number-generator.ts
@@ -1,19 +1,22 @@
-import {OrderPayloadFragment} from "../../../generated/graphql";
+import { OrderPayloadFragment } from "../../../generated/graphql";
interface IInvoiceNumberGenerationStrategy {
- (order: OrderPayloadFragment): string;
+ (order: OrderPayloadFragment): string;
}
export const InvoiceNumberGenerationStrategy = {
- localizedDate: (locale: string) => (order: Pick
) => {
- const orderCreatedDate = new Date(order.created);
+ localizedDate: (locale: string) => (order: Pick) => {
+ const orderCreatedDate = new Date(order.created);
- return Intl.DateTimeFormat(locale,).format(orderCreatedDate)
- }
-} satisfies Record IInvoiceNumberGenerationStrategy>
+ return Intl.DateTimeFormat(locale).format(orderCreatedDate);
+ },
+} satisfies Record IInvoiceNumberGenerationStrategy>;
export class InvoiceNumberGenerator {
- generateFromOrder(order: OrderPayloadFragment, strategy: IInvoiceNumberGenerationStrategy): string {
- return strategy(order)
- }
-}
\ No newline at end of file
+ generateFromOrder(
+ order: OrderPayloadFragment,
+ strategy: IInvoiceNumberGenerationStrategy
+ ): string {
+ return strategy(order);
+ }
+}
diff --git a/apps/search/saleor-app.ts b/apps/search/saleor-app.ts
index 755d573..59689fc 100644
--- a/apps/search/saleor-app.ts
+++ b/apps/search/saleor-app.ts
@@ -39,7 +39,7 @@ switch (aplType) {
if (!process.env.SECRET_KEY && process.env.NODE_ENV === "production") {
throw new Error(
- "For production deployment SECRET_KEY is mandatory to use EncryptedSettingsManager.",
+ "For production deployment SECRET_KEY is mandatory to use EncryptedSettingsManager."
);
}
diff --git a/apps/search/src/components/AlgoliaConfigurationCard.tsx b/apps/search/src/components/AlgoliaConfigurationCard.tsx
index 7449ff6..04f39b4 100644
--- a/apps/search/src/components/AlgoliaConfigurationCard.tsx
+++ b/apps/search/src/components/AlgoliaConfigurationCard.tsx
@@ -80,7 +80,7 @@ export const AlgoliaConfigurationCard = () => {
},
});
},
- },
+ }
);
const onFormSubmit = handleSubmit(async (conf) => mutate(conf));
diff --git a/apps/search/src/components/ConfigurationView.tsx b/apps/search/src/components/ConfigurationView.tsx
index 0f53ff1..d376666 100644
--- a/apps/search/src/components/ConfigurationView.tsx
+++ b/apps/search/src/components/ConfigurationView.tsx
@@ -1,4 +1,4 @@
-import {Card, CardContent, CardHeader} from "@material-ui/core";
+import { Card, CardContent, CardHeader } from "@material-ui/core";
import { ImportProductsToAlgolia } from "./ImportProductsToAlgolia";
import AlgoliaConfigurationCard from "./AlgoliaConfigurationCard";
import { makeStyles, PageTab, PageTabs } from "@saleor/macaw-ui";
diff --git a/apps/search/src/components/ImportProductsToAlgolia.tsx b/apps/search/src/components/ImportProductsToAlgolia.tsx
index a82b260..bd03fb6 100644
--- a/apps/search/src/components/ImportProductsToAlgolia.tsx
+++ b/apps/search/src/components/ImportProductsToAlgolia.tsx
@@ -19,7 +19,7 @@ export const ImportProductsToAlgolia = () => {
const { appBridgeState } = useAppBridge();
const algoliaConfiguration = useConfiguration(
appBridgeState?.saleorApiUrl,
- appBridgeState?.token,
+ appBridgeState?.token
);
const searchProvider = useMemo(() => {
diff --git a/apps/search/src/components/SearchBox.tsx b/apps/search/src/components/SearchBox.tsx
index febaf28..2bba1c6 100644
--- a/apps/search/src/components/SearchBox.tsx
+++ b/apps/search/src/components/SearchBox.tsx
@@ -5,28 +5,28 @@ import { useSearchBox } from "react-instantsearch-hooks-web";
import styles from "../styles/search.module.css";
export function SearchBox() {
- const { query, refine } = useSearchBox();
-
- const handleChange = (e: ChangeEvent) => {
- refine(e.target.value);
- };
- return (
-
-
-
-
- ),
- }}
- value={query}
- onChange={handleChange}
- placeholder={"Search products..."}
- inputProps={{ style: { padding: "16px" } }}
- className={styles.textField}
- />
-
- );
- }
\ No newline at end of file
+ const { query, refine } = useSearchBox();
+
+ const handleChange = (e: ChangeEvent) => {
+ refine(e.target.value);
+ };
+ return (
+
+
+
+
+ ),
+ }}
+ value={query}
+ onChange={handleChange}
+ placeholder={"Search products..."}
+ inputProps={{ style: { padding: "16px" } }}
+ className={styles.textField}
+ />
+
+ );
+}
diff --git a/apps/search/src/lib/algolia/algoliaSearchProvider.ts b/apps/search/src/lib/algolia/algoliaSearchProvider.ts
index bd9f308..f4daad0 100644
--- a/apps/search/src/lib/algolia/algoliaSearchProvider.ts
+++ b/apps/search/src/lib/algolia/algoliaSearchProvider.ts
@@ -35,7 +35,7 @@ export class AlgoliaSearchProvider implements SearchProvider {
Object.entries(groupedByIndex).map(([indexName, objects]) => {
const index = this.#algolia.initIndex(indexName);
return index.saveObjects(objects);
- }),
+ })
);
}
@@ -46,7 +46,7 @@ export class AlgoliaSearchProvider implements SearchProvider {
Object.entries(groupedByIndex).map(([indexName, objects]) => {
const index = this.#algolia.initIndex(indexName);
return index.deleteObjects(objects.map((o) => o.objectID));
- }),
+ })
);
}
@@ -141,7 +141,7 @@ const groupVariantByIndexName = (
{
visibleInListings,
indexNamePrefix,
- }: { visibleInListings: true | false | null; indexNamePrefix: string | undefined },
+ }: { visibleInListings: true | false | null; indexNamePrefix: string | undefined }
) => {
if (!productVariant.product.channelListings) {
return null;
@@ -150,7 +150,7 @@ const groupVariantByIndexName = (
const objectsToSaveByIndexName = productVariant.product.channelListings
.filter((channelListing) =>
// don't filter if `visibleInListings` is null
- visibleInListings === null ? true : channelListing.visibleInListings === visibleInListings,
+ visibleInListings === null ? true : channelListing.visibleInListings === visibleInListings
)
.map((channelListing) => {
const object = productAndVariantToAlgolia({
@@ -176,7 +176,7 @@ const groupProductsByIndexName = (
{
visibleInListings,
indexNamePrefix,
- }: { visibleInListings: true | false | null; indexNamePrefix: string | undefined },
+ }: { visibleInListings: true | false | null; indexNamePrefix: string | undefined }
) => {
debug(`groupProductsByIndexName called`);
const batchesAndIndices = productsBatch
diff --git a/apps/search/src/lib/algolia/algoliaUtils.ts b/apps/search/src/lib/algolia/algoliaUtils.ts
index 8a77445..2a49b10 100644
--- a/apps/search/src/lib/algolia/algoliaUtils.ts
+++ b/apps/search/src/lib/algolia/algoliaUtils.ts
@@ -10,7 +10,7 @@ type PartialChannelListing = {
export function channelListingToAlgoliaIndexId(
channelListing: PartialChannelListing,
- indexNamePrefix: string | undefined,
+ indexNamePrefix: string | undefined
) {
const nameSegments = [
indexNamePrefix,
diff --git a/apps/search/src/lib/graphql.ts b/apps/search/src/lib/graphql.ts
index 8711480..4eee5c4 100644
--- a/apps/search/src/lib/graphql.ts
+++ b/apps/search/src/lib/graphql.ts
@@ -51,7 +51,7 @@ export const nextClient = (url: string, getAuth: AuthConfig["getAuth
url,
exchanges: getExchanges(getAuth),
},
- false,
+ false
);
};
diff --git a/apps/search/src/lib/metadata.ts b/apps/search/src/lib/metadata.ts
index 3ce4db6..ee78a65 100644
--- a/apps/search/src/lib/metadata.ts
+++ b/apps/search/src/lib/metadata.ts
@@ -37,7 +37,7 @@ export async function mutateMetadata(client: Client, metadata: MetadataEntry[])
if (idQueryError) {
console.debug("Could not fetch the app id: ", idQueryError);
throw new Error(
- "Could not fetch the app id. Please check if auth data for the client are valid.",
+ "Could not fetch the app id. Please check if auth data for the client are valid."
);
}
diff --git a/apps/search/src/pages/api/configuration.ts b/apps/search/src/pages/api/configuration.ts
index 93ec5fd..9caa881 100644
--- a/apps/search/src/pages/api/configuration.ts
+++ b/apps/search/src/pages/api/configuration.ts
@@ -20,7 +20,7 @@ const sendResponse = async (
res: NextApiResponse,
statusCode: number,
settings: SettingsManager,
- domain: string,
+ domain: string
) => {
res.status(statusCode).json({
success: statusCode === 200,
@@ -36,7 +36,7 @@ const sendResponse = async (
export const handler = async (
req: NextApiRequest,
res: NextApiResponse,
- ctx: ProtectedHandlerContext,
+ ctx: ProtectedHandlerContext
) => {
debug("Configuration handler received request");
@@ -54,7 +54,7 @@ export const handler = async (
} else if (req.method === "POST") {
debug("Updating the configuration");
const { appId, searchKey, secretKey, indexNamePrefix } = JSON.parse(
- req.body,
+ req.body
) as AlgoliaConfigurationFields;
await settings.set([
{ key: "secretKey", value: secretKey || "", domain },
diff --git a/apps/search/src/pages/api/webhooks/saleor/_index.ts b/apps/search/src/pages/api/webhooks/saleor/_index.ts
index 85b1658..6b2d323 100644
--- a/apps/search/src/pages/api/webhooks/saleor/_index.ts
+++ b/apps/search/src/pages/api/webhooks/saleor/_index.ts
@@ -11,15 +11,15 @@ const debug = createDebug("Webhooks handler");
export const handler: NextWebhookApiHandler = async (
req,
res,
- context,
+ context
) => {
const { event, authData } = context;
debug(
- `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!`,
+ `New event ${event} (${context.payload?.__typename}) from the ${authData.domain} domain has been received!`
);
const client = createClient(authData.saleorApiUrl, async () =>
- Promise.resolve({ token: authData.token }),
+ Promise.resolve({ token: authData.token })
);
const settings = createSettingsManager(client);
diff --git a/apps/search/src/pages/search/index.tsx b/apps/search/src/pages/search/index.tsx
index f773be0..1ef0e52 100644
--- a/apps/search/src/pages/search/index.tsx
+++ b/apps/search/src/pages/search/index.tsx
@@ -37,7 +37,7 @@ function Search() {
const [indexName, setIndexName] = useState();
const algoliaConfiguration = useConfiguration(
appBridgeState?.saleorApiUrl,
- appBridgeState?.token,
+ appBridgeState?.token
);
const searchClient = useMemo(() => {
diff --git a/apps/search/src/providers/GraphQLProvider.tsx b/apps/search/src/providers/GraphQLProvider.tsx
index e217484..4767d19 100644
--- a/apps/search/src/providers/GraphQLProvider.tsx
+++ b/apps/search/src/providers/GraphQLProvider.tsx
@@ -13,7 +13,7 @@ function GraphQLProvider(props: PropsWithChildren<{}>) {
}
const client = createClient(saleorApiUrl, async () =>
- Promise.resolve({ token: appBridgeState?.token! }),
+ Promise.resolve({ token: appBridgeState?.token! })
);
return ;
diff --git a/package.json b/package.json
index a9deba8..dafb877 100644
--- a/package.json
+++ b/package.json
@@ -14,17 +14,23 @@
"test": "turbo run test",
"test:ci": "turbo run test:ci",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
- "generate": "turbo run generate"
+ "generate": "turbo run generate",
+ "prepare": "husky install"
},
"devDependencies": {
"@changesets/cli": "^2.26.0",
"eslint-config-saleor": "workspace:*",
"prettier": "^2.8.3",
"turbo": "^1.7.4",
- "eslint": "^8.33.0"
+ "eslint": "^8.33.0",
+ "husky": "^8.0.3"
},
"engines": {
"node": ">=18.0.0"
},
- "packageManager": "pnpm@7.26.2"
+ "packageManager": "pnpm@7.26.2",
+ "lint-staged": {
+ "*.{js,ts,tsx}": "eslint --cache --fix",
+ "*.{ts,tsx,md}": "prettier --write"
+ }
}
\ No newline at end of file
diff --git a/packages/shared/src/is-in-iframe.ts b/packages/shared/src/is-in-iframe.ts
index 9299619..e1f481c 100644
--- a/packages/shared/src/is-in-iframe.ts
+++ b/packages/shared/src/is-in-iframe.ts
@@ -4,4 +4,4 @@ export function isInIframe() {
} catch (e) {
return true;
}
-}
\ No newline at end of file
+}
diff --git a/packages/shared/src/title-bar/title-bar.tsx b/packages/shared/src/title-bar/title-bar.tsx
index ab7842c..0c3efb0 100644
--- a/packages/shared/src/title-bar/title-bar.tsx
+++ b/packages/shared/src/title-bar/title-bar.tsx
@@ -80,4 +80,4 @@ export function TitleBar({
);
}
-TitleBar.height = height;
\ No newline at end of file
+TitleBar.height = height;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dfd6af8..36cd901 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,12 +7,14 @@ importers:
'@changesets/cli': ^2.26.0
eslint: ^8.33.0
eslint-config-saleor: workspace:*
+ husky: ^8.0.3
prettier: ^2.8.3
turbo: ^1.7.4
devDependencies:
'@changesets/cli': 2.26.0
eslint: 8.33.0
eslint-config-saleor: link:packages/eslint-config-saleor
+ husky: 8.0.3
prettier: 2.8.3
turbo: 1.7.4