@unisian/shopify-storefront 0.0.0-stage → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ import { StorefrontDocument, StorefrontOperations } from "./operations.mjs";
2
+ import { StorefrontOperation, StorefrontOperationRegistry } from "./storefront-operation-registry.mjs";
3
+ import { StorefrontQueryFailed } from "./storefront-query-failed.mjs";
4
+ import { ShopifyStorefront, StorefrontCredential, StorefrontError } from "./storefront-api.mjs";
5
+ export { ShopifyStorefront, type StorefrontCredential, type StorefrontDocument, type StorefrontError, type StorefrontOperation, StorefrontOperationRegistry, type StorefrontOperations, StorefrontQueryFailed };
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import { StorefrontOperationRegistry } from "./storefront-operation-registry.mjs";
2
+ import { StorefrontQueryFailed } from "./storefront-query-failed.mjs";
3
+ import { ShopifyStorefront } from "./storefront-api.mjs";
4
+ export { ShopifyStorefront, StorefrontOperationRegistry, StorefrontQueryFailed };
@@ -0,0 +1,4 @@
1
+ //#region src/operations.d.ts
2
+ export interface StorefrontOperations {}
3
+ export type StorefrontDocument = Extract<keyof StorefrontOperations, string>;
4
+ //#endregion
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { StorefrontDocument, StorefrontOperations } from "./operations.mjs";
2
+ import { StorefrontOperationRegistry } from "./storefront-operation-registry.mjs";
3
+ import { StorefrontQueryFailed } from "./storefront-query-failed.mjs";
4
+ import * as Context from "effect/Context";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ import * as Redacted from "effect/Redacted";
8
+ import { HttpClient } from "effect/http";
9
+ import { RefreshError, SessionOwner, ShopifyApp } from "@unisian/shopify-auth";
10
+ import { VariablesArgsFor } from "@unisian/shopify-auth/kernel";
11
+ import "effect/Schema";
12
+ import { ShopDomain } from "@unisian/shopify-sessions";
13
+ //#region src/storefront-api.d.ts
14
+ export interface StorefrontCredential {
15
+ readonly privateToken: Redacted.Redacted;
16
+ readonly shop: ShopDomain;
17
+ readonly buyerIp: string | null;
18
+ }
19
+ export type StorefrontVariablesArgs<Q extends StorefrontDocument> = VariablesArgsFor<StorefrontOperations[Q]["variables"]>;
20
+ export type StorefrontError = StorefrontQueryFailed | RefreshError;
21
+ declare const ShopifyStorefront_base: Context.ServiceClass<ShopifyStorefront, "@unisian/shopify-storefront/ShopifyStorefront", {
22
+ readonly graphql: <const Q extends StorefrontDocument>(document: Q, ...variables: StorefrontVariablesArgs<Q>) => Effect.Effect<StorefrontOperations[Q]["data"], StorefrontError>;
23
+ }>;
24
+ export declare class ShopifyStorefront extends ShopifyStorefront_base {
25
+ static readonly makeForShop: (shop: ShopDomain, buyerIp: string | null) => Effect.Effect<{
26
+ readonly graphql: <const Q extends StorefrontDocument>(document: Q, ...variables: StorefrontVariablesArgs<Q>) => Effect.Effect<StorefrontOperations[Q]["data"], StorefrontError>;
27
+ }, never, HttpClient.HttpClient | SessionOwner | ShopifyApp | StorefrontOperationRegistry>;
28
+ static readonly layerForShop: (shop: ShopDomain, buyerIp: string | null) => Layer.Layer<ShopifyStorefront, never, HttpClient.HttpClient | SessionOwner | ShopifyApp | StorefrontOperationRegistry>;
29
+ }
30
+ //#endregion
@@ -0,0 +1,41 @@
1
+ import { StorefrontOperationRegistry } from "./storefront-operation-registry.mjs";
2
+ import { StorefrontQueryFailed } from "./storefront-query-failed.mjs";
3
+ import * as Context from "effect/Context";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ import * as Redacted from "effect/Redacted";
7
+ import { HttpClient, HttpClientRequest } from "effect/http";
8
+ import { SessionOwner, ShopifyApp, withoutRequest } from "@unisian/shopify-auth";
9
+ import { logRenewal, operationBody, operationData, operationFor } from "@unisian/shopify-auth/kernel";
10
+ //#region src/storefront-api.ts
11
+ const storefrontRequest = (apiVersion, credential, body) => HttpClientRequest.post(`https://${credential.shop}/api/${apiVersion}/graphql.json`).pipe(HttpClientRequest.acceptJson, HttpClientRequest.setHeader("Shopify-Storefront-Private-Token", Redacted.value(credential.privateToken)), credential.buyerIp === null || credential.buyerIp === "" ? (request) => request : HttpClientRequest.setHeader("Shopify-Storefront-Buyer-IP", credential.buyerIp), HttpClientRequest.bodyJsonUnsafe(body));
12
+ const storefrontQuery = (apiVersion, credential, operation, variables) => Effect.gen(function* sendStorefrontQuery() {
13
+ const failed = (cause) => new StorefrontQueryFailed({
14
+ cause: withoutRequest(cause),
15
+ operation: operation.name,
16
+ shop: credential.shop
17
+ });
18
+ const client = yield* HttpClient.HttpClient;
19
+ const body = yield* operationBody(operation, variables, failed);
20
+ const response = yield* client.execute(storefrontRequest(apiVersion, credential, body)).pipe(Effect.mapError(failed));
21
+ return yield* operationData(operation.data, failed)(response);
22
+ }).pipe(Effect.withSpan("storefrontQuery", { attributes: { operation: operation.name } }));
23
+ var ShopifyStorefront = class ShopifyStorefront extends Context.Service()("@unisian/shopify-storefront/ShopifyStorefront") {
24
+ static makeForShop = (shop, buyerIp) => Effect.gen(function* makeForShop() {
25
+ const { apiVersion } = yield* ShopifyApp;
26
+ const registry = yield* StorefrontOperationRegistry;
27
+ const client = yield* HttpClient.HttpClient;
28
+ const owner = yield* SessionOwner;
29
+ const graphql = (document, ...[variables]) => {
30
+ return operationFor(registry, document).pipe(Effect.flatMap((operation) => owner.stored(shop).pipe(Effect.tap(logRenewal), Effect.flatMap(({ session }) => storefrontQuery(apiVersion, {
31
+ buyerIp,
32
+ privateToken: session.accessToken,
33
+ shop
34
+ }, operation, variables ?? {})))), Effect.annotateLogs("shop", shop), Effect.provideService(HttpClient.HttpClient, client));
35
+ };
36
+ return ShopifyStorefront.of({ graphql });
37
+ });
38
+ static layerForShop = (shop, buyerIp) => Layer.effect(ShopifyStorefront, ShopifyStorefront.makeForShop(shop, buyerIp));
39
+ };
40
+ //#endregion
41
+ export { ShopifyStorefront, storefrontQuery };
@@ -0,0 +1,11 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Layer from "effect/Layer";
3
+ import { GraphqlOperation } from "@unisian/shopify-auth/kernel";
4
+ import * as Schema from "effect/Schema";
5
+ //#region src/storefront-operation-registry.d.ts
6
+ export type StorefrontOperation<Data extends Schema.Codec<unknown, unknown> = Schema.Codec<unknown, unknown>, Variables extends Schema.Codec<unknown, unknown> = Schema.Codec<unknown, unknown>> = GraphqlOperation<Data, Variables>;
7
+ declare const StorefrontOperationRegistry_base: Context.ServiceClass<StorefrontOperationRegistry, "@unisian/shopify-storefront/StorefrontOperationRegistry", Readonly<Record<string, StorefrontOperation<Schema.Codec<unknown, unknown, never, never>, Schema.Codec<unknown, unknown, never, never>>>>>;
8
+ export declare class StorefrontOperationRegistry extends StorefrontOperationRegistry_base {
9
+ static readonly layer: (operations: Readonly<Record<string, StorefrontOperation>>) => Layer.Layer<StorefrontOperationRegistry, never, never>;
10
+ }
11
+ //#endregion
@@ -0,0 +1,8 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Layer from "effect/Layer";
3
+ //#region src/storefront-operation-registry.ts
4
+ var StorefrontOperationRegistry = class StorefrontOperationRegistry extends Context.Service()("@unisian/shopify-storefront/StorefrontOperationRegistry") {
5
+ static layer = (operations) => Layer.succeed(StorefrontOperationRegistry, StorefrontOperationRegistry.of(operations));
6
+ };
7
+ //#endregion
8
+ export { StorefrontOperationRegistry };
@@ -0,0 +1,11 @@
1
+ import * as Schema from "effect/Schema";
2
+ //#region src/storefront-query-failed.d.ts
3
+ declare const StorefrontQueryFailed_base: Schema.Class<StorefrontQueryFailed, Schema.TaggedStruct<"StorefrontQueryFailed", {
4
+ readonly cause: Schema.Defect;
5
+ readonly operation: Schema.String;
6
+ readonly shop: Schema.String;
7
+ }>, import("effect/Cause").YieldableError>;
8
+ export declare class StorefrontQueryFailed extends StorefrontQueryFailed_base {
9
+ get message(): string;
10
+ }
11
+ //#endregion
@@ -0,0 +1,13 @@
1
+ import * as Schema from "effect/Schema";
2
+ //#region src/storefront-query-failed.ts
3
+ var StorefrontQueryFailed = class extends Schema.TaggedError()("StorefrontQueryFailed", {
4
+ cause: Schema.Defect(),
5
+ operation: Schema.String,
6
+ shop: Schema.String
7
+ }) {
8
+ get message() {
9
+ return `Storefront API ${this.operation} failed for ${this.shop}`;
10
+ }
11
+ };
12
+ //#endregion
13
+ export { StorefrontQueryFailed };
package/package.json CHANGED
@@ -1,6 +1,33 @@
1
1
  {
2
2
  "name": "@unisian/shopify-storefront",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.7.0",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/baoagency/unisian-next.git",
8
+ "directory": "packages/shopify-storefront"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "type": "module",
14
+ "exports": {
15
+ ".": "./dist/index.mjs",
16
+ "./operations": "./dist/operations.mjs"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "devDependencies": {
22
+ "effect": "4.0.6",
23
+ "@unisian/effect-observability": "0.7.0",
24
+ "@unisian/shopify-auth": "0.7.0",
25
+ "@unisian/shopify-sessions": "0.7.0"
26
+ },
27
+ "peerDependencies": {
28
+ "effect": "^4.0.2",
29
+ "@unisian/shopify-sessions": "0.7.0",
30
+ "@unisian/shopify-auth": "0.7.0"
31
+ },
32
+ "scripts": {}
6
33
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.