@shopify/shopify-app-remix 3.8.4 → 4.0.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.
Files changed (154) hide show
  1. package/README.md +2 -3
  2. package/dist/cjs/server/adapters/node/index.js +0 -2
  3. package/dist/cjs/server/adapters/node/index.js.map +1 -1
  4. package/dist/cjs/server/authenticate/admin/authenticate.js.map +1 -1
  5. package/dist/cjs/server/authenticate/admin/helpers/create-admin-api-context.js.map +1 -1
  6. package/dist/cjs/server/authenticate/admin/helpers/trigger-after-auth-hook.js.map +1 -1
  7. package/dist/cjs/server/authenticate/admin/scope/client/fetch-scopes-details.js.map +1 -1
  8. package/dist/cjs/server/authenticate/admin/scope/client/revoke-scopes.js.map +1 -1
  9. package/dist/cjs/server/authenticate/admin/scope/factory.js.map +1 -1
  10. package/dist/cjs/server/authenticate/admin/scope/query.js.map +1 -1
  11. package/dist/cjs/server/authenticate/admin/scope/request.js.map +1 -1
  12. package/dist/cjs/server/authenticate/admin/scope/revoke.js.map +1 -1
  13. package/dist/cjs/server/authenticate/admin/strategies/auth-code-flow.js.map +1 -1
  14. package/dist/cjs/server/authenticate/admin/strategies/merchant-custom-app.js.map +1 -1
  15. package/dist/cjs/server/authenticate/admin/strategies/token-exchange.js.map +1 -1
  16. package/dist/cjs/server/authenticate/flow/authenticate.js.map +1 -1
  17. package/dist/cjs/server/authenticate/fulfillment-service/authenticate.js.map +1 -1
  18. package/dist/cjs/server/authenticate/public/appProxy/authenticate.js.map +1 -1
  19. package/dist/cjs/server/authenticate/public/factory.js.map +1 -1
  20. package/dist/cjs/server/authenticate/webhooks/authenticate.js.map +1 -1
  21. package/dist/cjs/server/clients/admin/factory.js +0 -11
  22. package/dist/cjs/server/clients/admin/factory.js.map +1 -1
  23. package/dist/cjs/server/clients/admin/graphql.js +1 -2
  24. package/dist/cjs/server/clients/admin/graphql.js.map +1 -1
  25. package/dist/cjs/server/future/flags.js.map +1 -1
  26. package/dist/cjs/server/index.js +0 -8
  27. package/dist/cjs/server/index.js.map +1 -1
  28. package/dist/cjs/server/override-logger.js +2 -2
  29. package/dist/cjs/server/override-logger.js.map +1 -1
  30. package/dist/cjs/server/shopify-app.js +1 -2
  31. package/dist/cjs/server/shopify-app.js.map +1 -1
  32. package/dist/cjs/server/test-helpers/test-config.js.map +1 -1
  33. package/dist/cjs/server/types.js.map +1 -1
  34. package/dist/cjs/server/unauthenticated/admin/factory.js.map +1 -1
  35. package/dist/cjs/server/version.js +1 -1
  36. package/dist/cjs/server/version.js.map +1 -1
  37. package/dist/esm/server/adapters/node/index.mjs +1 -3
  38. package/dist/esm/server/adapters/node/index.mjs.map +1 -1
  39. package/dist/esm/server/authenticate/admin/authenticate.mjs.map +1 -1
  40. package/dist/esm/server/authenticate/admin/helpers/create-admin-api-context.mjs.map +1 -1
  41. package/dist/esm/server/authenticate/admin/helpers/trigger-after-auth-hook.mjs.map +1 -1
  42. package/dist/esm/server/authenticate/admin/scope/client/fetch-scopes-details.mjs.map +1 -1
  43. package/dist/esm/server/authenticate/admin/scope/client/revoke-scopes.mjs.map +1 -1
  44. package/dist/esm/server/authenticate/admin/scope/factory.mjs.map +1 -1
  45. package/dist/esm/server/authenticate/admin/scope/query.mjs.map +1 -1
  46. package/dist/esm/server/authenticate/admin/scope/request.mjs.map +1 -1
  47. package/dist/esm/server/authenticate/admin/scope/revoke.mjs.map +1 -1
  48. package/dist/esm/server/authenticate/admin/strategies/auth-code-flow.mjs.map +1 -1
  49. package/dist/esm/server/authenticate/admin/strategies/merchant-custom-app.mjs.map +1 -1
  50. package/dist/esm/server/authenticate/admin/strategies/token-exchange.mjs.map +1 -1
  51. package/dist/esm/server/authenticate/flow/authenticate.mjs.map +1 -1
  52. package/dist/esm/server/authenticate/fulfillment-service/authenticate.mjs.map +1 -1
  53. package/dist/esm/server/authenticate/public/appProxy/authenticate.mjs.map +1 -1
  54. package/dist/esm/server/authenticate/public/factory.mjs.map +1 -1
  55. package/dist/esm/server/authenticate/webhooks/authenticate.mjs.map +1 -1
  56. package/dist/esm/server/clients/admin/factory.mjs +0 -11
  57. package/dist/esm/server/clients/admin/factory.mjs.map +1 -1
  58. package/dist/esm/server/clients/admin/graphql.mjs +1 -2
  59. package/dist/esm/server/clients/admin/graphql.mjs.map +1 -1
  60. package/dist/esm/server/future/flags.mjs.map +1 -1
  61. package/dist/esm/server/index.mjs +1 -1
  62. package/dist/esm/server/index.mjs.map +1 -1
  63. package/dist/esm/server/override-logger.mjs +2 -2
  64. package/dist/esm/server/override-logger.mjs.map +1 -1
  65. package/dist/esm/server/shopify-app.mjs +2 -3
  66. package/dist/esm/server/shopify-app.mjs.map +1 -1
  67. package/dist/esm/server/test-helpers/test-config.mjs.map +1 -1
  68. package/dist/esm/server/types.mjs.map +1 -1
  69. package/dist/esm/server/unauthenticated/admin/factory.mjs.map +1 -1
  70. package/dist/esm/server/version.mjs +1 -1
  71. package/dist/esm/server/version.mjs.map +1 -1
  72. package/dist/ts/server/authenticate/admin/authenticate.admin.doc.d.ts.map +1 -1
  73. package/dist/ts/server/authenticate/admin/authenticate.d.ts +2 -2
  74. package/dist/ts/server/authenticate/admin/authenticate.d.ts.map +1 -1
  75. package/dist/ts/server/authenticate/admin/billing/types.d.ts +1 -2
  76. package/dist/ts/server/authenticate/admin/billing/types.d.ts.map +1 -1
  77. package/dist/ts/server/authenticate/admin/helpers/create-admin-api-context.d.ts +2 -3
  78. package/dist/ts/server/authenticate/admin/helpers/create-admin-api-context.d.ts.map +1 -1
  79. package/dist/ts/server/authenticate/admin/helpers/trigger-after-auth-hook.d.ts +2 -3
  80. package/dist/ts/server/authenticate/admin/helpers/trigger-after-auth-hook.d.ts.map +1 -1
  81. package/dist/ts/server/authenticate/admin/scope/client/fetch-scopes-details.d.ts +1 -2
  82. package/dist/ts/server/authenticate/admin/scope/client/fetch-scopes-details.d.ts.map +1 -1
  83. package/dist/ts/server/authenticate/admin/scope/client/revoke-scopes.d.ts +1 -2
  84. package/dist/ts/server/authenticate/admin/scope/client/revoke-scopes.d.ts.map +1 -1
  85. package/dist/ts/server/authenticate/admin/scope/factory.d.ts +1 -2
  86. package/dist/ts/server/authenticate/admin/scope/factory.d.ts.map +1 -1
  87. package/dist/ts/server/authenticate/admin/scope/query.d.ts +1 -2
  88. package/dist/ts/server/authenticate/admin/scope/query.d.ts.map +1 -1
  89. package/dist/ts/server/authenticate/admin/scope/request.d.ts +1 -2
  90. package/dist/ts/server/authenticate/admin/scope/request.d.ts.map +1 -1
  91. package/dist/ts/server/authenticate/admin/scope/revoke.d.ts +1 -2
  92. package/dist/ts/server/authenticate/admin/scope/revoke.d.ts.map +1 -1
  93. package/dist/ts/server/authenticate/admin/strategies/auth-code-flow.d.ts +3 -3
  94. package/dist/ts/server/authenticate/admin/strategies/auth-code-flow.d.ts.map +1 -1
  95. package/dist/ts/server/authenticate/admin/strategies/merchant-custom-app.d.ts +2 -2
  96. package/dist/ts/server/authenticate/admin/strategies/merchant-custom-app.d.ts.map +1 -1
  97. package/dist/ts/server/authenticate/admin/strategies/token-exchange.d.ts +2 -2
  98. package/dist/ts/server/authenticate/admin/strategies/token-exchange.d.ts.map +1 -1
  99. package/dist/ts/server/authenticate/admin/types.d.ts +9 -9
  100. package/dist/ts/server/authenticate/admin/types.d.ts.map +1 -1
  101. package/dist/ts/server/authenticate/flow/authenticate.d.ts +1 -3
  102. package/dist/ts/server/authenticate/flow/authenticate.d.ts.map +1 -1
  103. package/dist/ts/server/authenticate/flow/types.d.ts +4 -5
  104. package/dist/ts/server/authenticate/flow/types.d.ts.map +1 -1
  105. package/dist/ts/server/authenticate/fulfillment-service/authenticate.d.ts +1 -3
  106. package/dist/ts/server/authenticate/fulfillment-service/authenticate.d.ts.map +1 -1
  107. package/dist/ts/server/authenticate/fulfillment-service/types.d.ts +4 -5
  108. package/dist/ts/server/authenticate/fulfillment-service/types.d.ts.map +1 -1
  109. package/dist/ts/server/authenticate/public/appProxy/authenticate.d.ts +1 -3
  110. package/dist/ts/server/authenticate/public/appProxy/authenticate.d.ts.map +1 -1
  111. package/dist/ts/server/authenticate/public/appProxy/types.d.ts +6 -7
  112. package/dist/ts/server/authenticate/public/appProxy/types.d.ts.map +1 -1
  113. package/dist/ts/server/authenticate/public/factory.d.ts +1 -3
  114. package/dist/ts/server/authenticate/public/factory.d.ts.map +1 -1
  115. package/dist/ts/server/authenticate/public/types.d.ts +2 -3
  116. package/dist/ts/server/authenticate/public/types.d.ts.map +1 -1
  117. package/dist/ts/server/authenticate/webhooks/authenticate.d.ts +1 -3
  118. package/dist/ts/server/authenticate/webhooks/authenticate.d.ts.map +1 -1
  119. package/dist/ts/server/authenticate/webhooks/types.d.ts +5 -6
  120. package/dist/ts/server/authenticate/webhooks/types.d.ts.map +1 -1
  121. package/dist/ts/server/clients/admin/factory.d.ts +3 -4
  122. package/dist/ts/server/clients/admin/factory.d.ts.map +1 -1
  123. package/dist/ts/server/clients/admin/graphql.d.ts.map +1 -1
  124. package/dist/ts/server/clients/admin/types.d.ts +2 -134
  125. package/dist/ts/server/clients/admin/types.d.ts.map +1 -1
  126. package/dist/ts/server/config-types.d.ts +14 -16
  127. package/dist/ts/server/config-types.d.ts.map +1 -1
  128. package/dist/ts/server/future/flags.d.ts +2 -22
  129. package/dist/ts/server/future/flags.d.ts.map +1 -1
  130. package/dist/ts/server/index.d.ts +1 -1
  131. package/dist/ts/server/index.d.ts.map +1 -1
  132. package/dist/ts/server/shopify-app.d.ts +1 -2
  133. package/dist/ts/server/shopify-app.d.ts.map +1 -1
  134. package/dist/ts/server/test-helpers/test-config.d.ts +2 -2
  135. package/dist/ts/server/test-helpers/test-config.d.ts.map +1 -1
  136. package/dist/ts/server/types-contexts.d.ts +17 -31
  137. package/dist/ts/server/types-contexts.d.ts.map +1 -1
  138. package/dist/ts/server/types.d.ts +13 -14
  139. package/dist/ts/server/types.d.ts.map +1 -1
  140. package/dist/ts/server/unauthenticated/admin/factory.d.ts +1 -3
  141. package/dist/ts/server/unauthenticated/admin/factory.d.ts.map +1 -1
  142. package/dist/ts/server/unauthenticated/admin/types.d.ts +5 -6
  143. package/dist/ts/server/unauthenticated/admin/types.d.ts.map +1 -1
  144. package/dist/ts/server/unauthenticated/types.d.ts +3 -5
  145. package/dist/ts/server/unauthenticated/types.d.ts.map +1 -1
  146. package/dist/ts/server/version.d.ts +1 -1
  147. package/dist/tsconfig.build.tsbuildinfo +1 -1
  148. package/package.json +13 -16
  149. package/dist/cjs/server/clients/admin/rest.js +0 -132
  150. package/dist/cjs/server/clients/admin/rest.js.map +0 -1
  151. package/dist/esm/server/clients/admin/rest.mjs +0 -130
  152. package/dist/esm/server/clients/admin/rest.mjs.map +0 -1
  153. package/dist/ts/server/clients/admin/rest.d.ts +0 -39
  154. package/dist/ts/server/clients/admin/rest.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"merchant-custom-app.mjs","sources":["../../../../../../../src/server/authenticate/admin/strategies/merchant-custom-app.ts"],"sourcesContent":["import {\n Session,\n Shopify,\n ShopifyError,\n ShopifyRestResources,\n} from '@shopify/shopify-api';\n\nimport {AppConfig, AppConfigArg} from '../../../config-types';\nimport {BasicParams} from '../../../types';\nimport {ApiConfigWithFutureFlags, ApiFutureFlags} from '../../../future/flags';\nimport {HandleAdminClientError} from '../../../clients';\nimport {handleClientErrorFactory} from '../helpers';\nimport {getShopFromRequest} from '../../helpers';\n\nimport {AuthorizationStrategy, OnErrorOptions, SessionContext} from './types';\n\nexport class MerchantCustomAuth<Config extends AppConfigArg>\n implements AuthorizationStrategy\n{\n protected api: Shopify<\n ApiConfigWithFutureFlags<Config['future']>,\n ShopifyRestResources,\n ApiFutureFlags<Config['future']>\n >;\n\n protected config: AppConfig;\n protected logger: Shopify['logger'];\n\n public constructor({api, config, logger}: BasicParams<Config['future']>) {\n this.api = api;\n this.config = config;\n this.logger = logger;\n }\n\n public async respondToOAuthRequests(request: Request): Promise<void> {\n this.logger.debug('Skipping OAuth request for merchant custom app', {\n shop: getShopFromRequest(request),\n });\n }\n\n public async authenticate(\n _request: Request,\n sessionContext: SessionContext,\n ): Promise<Session | never> {\n const {shop} = sessionContext;\n\n this.logger.debug(\n 'Building session from configured access token for merchant custom app',\n {shop},\n );\n const session = this.api.session.customAppSession(shop);\n\n return session;\n }\n\n public handleClientError(request: Request): HandleAdminClientError {\n return handleClientErrorFactory({\n request,\n onError: async ({error}: OnErrorOptions) => {\n if (error.response.code === 401) {\n this.logger.info(\n 'Request failed with 401. Review your API credentials or generate new tokens. https://shopify.dev/docs/apps/build/authentication-authorization/access-token-types/generate-app-access-tokens-admin#rotating-api-credentials-for-admin-created-apps ',\n );\n throw new ShopifyError(\n 'Unauthorized: Access token has been revoked.',\n );\n }\n },\n });\n }\n}\n"],"names":[],"mappings":";;;;;;;MAgBa,kBAAkB,CAAA;AAGnB,IAAA,GAAG;AAMH,IAAA,MAAM;AACN,IAAA,MAAM;AAEhB,IAAA,WAAA,CAAmB,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAgC,EAAA;AACrE,QAAA,IAAI,CAAC,GAAG,GAAG,GAAG;AACd,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;IACtB;IAEO,MAAM,sBAAsB,CAAC,OAAgB,EAAA;AAClD,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,EAAE;AAClE,YAAA,IAAI,EAAE,kBAAkB,CAAC,OAAO,CAAC;AAClC,SAAA,CAAC;IACJ;AAEO,IAAA,MAAM,YAAY,CACvB,QAAiB,EACjB,cAA8B,EAAA;AAE9B,QAAA,MAAM,EAAC,IAAI,EAAC,GAAG,cAAc;QAE7B,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,uEAAuE,EACvE,EAAC,IAAI,EAAC,CACP;AACD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC;AAEvD,QAAA,OAAO,OAAO;IAChB;AAEO,IAAA,iBAAiB,CAAC,OAAgB,EAAA;AACvC,QAAA,OAAO,wBAAwB,CAAC;YAC9B,OAAO;AACP,YAAA,OAAO,EAAE,OAAO,EAAC,KAAK,EAAiB,KAAI;gBACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AAC/B,oBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,oPAAoP,CACrP;AACD,oBAAA,MAAM,IAAI,YAAY,CACpB,8CAA8C,CAC/C;gBACH;YACF,CAAC;AACF,SAAA,CAAC;IACJ;AACD;;;;"}
1
+ {"version":3,"file":"merchant-custom-app.mjs","sources":["../../../../../../../src/server/authenticate/admin/strategies/merchant-custom-app.ts"],"sourcesContent":["import {Session, Shopify, ShopifyError} from '@shopify/shopify-api';\n\nimport {AppConfig, AppConfigArg} from '../../../config-types';\nimport {BasicParams} from '../../../types';\nimport {ApiConfigWithFutureFlags, ApiFutureFlags} from '../../../future/flags';\nimport {HandleAdminClientError} from '../../../clients';\nimport {handleClientErrorFactory} from '../helpers';\nimport {getShopFromRequest} from '../../helpers';\n\nimport {AuthorizationStrategy, OnErrorOptions, SessionContext} from './types';\n\nexport class MerchantCustomAuth<Config extends AppConfigArg>\n implements AuthorizationStrategy\n{\n protected api: Shopify<\n ApiConfigWithFutureFlags<Config['future']>,\n ApiFutureFlags<Config['future']>\n >;\n\n protected config: AppConfig;\n protected logger: Shopify['logger'];\n\n public constructor({api, config, logger}: BasicParams<Config['future']>) {\n this.api = api;\n this.config = config;\n this.logger = logger;\n }\n\n public async respondToOAuthRequests(request: Request): Promise<void> {\n this.logger.debug('Skipping OAuth request for merchant custom app', {\n shop: getShopFromRequest(request),\n });\n }\n\n public async authenticate(\n _request: Request,\n sessionContext: SessionContext,\n ): Promise<Session | never> {\n const {shop} = sessionContext;\n\n this.logger.debug(\n 'Building session from configured access token for merchant custom app',\n {shop},\n );\n const session = this.api.session.customAppSession(shop);\n\n return session;\n }\n\n public handleClientError(request: Request): HandleAdminClientError {\n return handleClientErrorFactory({\n request,\n onError: async ({error}: OnErrorOptions) => {\n if (error.response.code === 401) {\n this.logger.info(\n 'Request failed with 401. Review your API credentials or generate new tokens. https://shopify.dev/docs/apps/build/authentication-authorization/access-token-types/generate-app-access-tokens-admin#rotating-api-credentials-for-admin-created-apps ',\n );\n throw new ShopifyError(\n 'Unauthorized: Access token has been revoked.',\n );\n }\n },\n });\n }\n}\n"],"names":[],"mappings":";;;;;;;MAWa,kBAAkB,CAAA;AAGnB,IAAA,GAAG;AAKH,IAAA,MAAM;AACN,IAAA,MAAM;AAEhB,IAAA,WAAA,CAAmB,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAgC,EAAA;AACrE,QAAA,IAAI,CAAC,GAAG,GAAG,GAAG;AACd,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;IACtB;IAEO,MAAM,sBAAsB,CAAC,OAAgB,EAAA;AAClD,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,EAAE;AAClE,YAAA,IAAI,EAAE,kBAAkB,CAAC,OAAO,CAAC;AAClC,SAAA,CAAC;IACJ;AAEO,IAAA,MAAM,YAAY,CACvB,QAAiB,EACjB,cAA8B,EAAA;AAE9B,QAAA,MAAM,EAAC,IAAI,EAAC,GAAG,cAAc;QAE7B,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,uEAAuE,EACvE,EAAC,IAAI,EAAC,CACP;AACD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC;AAEvD,QAAA,OAAO,OAAO;IAChB;AAEO,IAAA,iBAAiB,CAAC,OAAgB,EAAA;AACvC,QAAA,OAAO,wBAAwB,CAAC;YAC9B,OAAO;AACP,YAAA,OAAO,EAAE,OAAO,EAAC,KAAK,EAAiB,KAAI;gBACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,EAAE;AAC/B,oBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,oPAAoP,CACrP;AACD,oBAAA,MAAM,IAAI,YAAY,CACpB,8CAA8C,CAC/C;gBACH;YACF,CAAC;AACF,SAAA,CAAC;IACJ;AACD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"token-exchange.mjs","sources":["../../../../../../../src/server/authenticate/admin/strategies/token-exchange.ts"],"sourcesContent":["import {\n HttpResponseError,\n InvalidJwtError,\n RequestedTokenType,\n Session,\n Shopify,\n ShopifyRestResources,\n} from '@shopify/shopify-api';\n\nimport {AppConfig, AppConfigArg} from '../../../config-types';\nimport {BasicParams} from '../../../types';\nimport {\n respondToInvalidSessionToken,\n invalidateAccessToken,\n getShopFromRequest,\n} from '../../helpers';\nimport {handleClientErrorFactory, triggerAfterAuthHook} from '../helpers';\nimport {HandleAdminClientError} from '../../../clients';\nimport type {\n ApiConfigWithFutureFlags,\n ApiFutureFlags,\n} from '../../../future/flags';\n\nimport {AuthorizationStrategy, SessionContext, OnErrorOptions} from './types';\n\nexport class TokenExchangeStrategy<Config extends AppConfigArg>\n implements AuthorizationStrategy\n{\n protected api: Shopify<\n ApiConfigWithFutureFlags<Config['future']>,\n ShopifyRestResources,\n ApiFutureFlags<Config['future']>\n >;\n\n protected config: AppConfig;\n protected logger: Shopify['logger'];\n\n public constructor({api, config, logger}: BasicParams<Config['future']>) {\n this.api = api;\n this.config = config;\n this.logger = logger;\n }\n\n public async respondToOAuthRequests(_request: Request): Promise<void> {}\n\n public async authenticate(\n request: Request,\n sessionContext: SessionContext,\n ): Promise<Session> {\n const {api, config, logger} = this;\n const {shop, session, sessionToken} = sessionContext;\n\n if (!sessionToken) throw new InvalidJwtError();\n\n if (!session || !session.isActive(undefined)) {\n logger.info('No valid session found', {shop});\n logger.info('Requesting offline access token', {shop});\n const {session: offlineSession} = await this.exchangeToken({\n request,\n sessionToken,\n shop,\n requestedTokenType: RequestedTokenType.OfflineAccessToken,\n });\n\n await config.sessionStorage!.storeSession(offlineSession);\n\n let newSession = offlineSession;\n\n if (config.useOnlineTokens) {\n logger.info('Requesting online access token', {shop});\n const {session: onlineSession} = await this.exchangeToken({\n request,\n sessionToken,\n shop,\n requestedTokenType: RequestedTokenType.OnlineAccessToken,\n });\n\n await config.sessionStorage!.storeSession(onlineSession);\n newSession = onlineSession;\n }\n\n logger.debug('Request is valid, loaded session from session token', {\n shop: newSession.shop,\n isOnline: newSession.isOnline,\n });\n\n try {\n await this.handleAfterAuthHook(\n {api, config, logger},\n newSession,\n request,\n sessionToken,\n );\n } catch (errorOrResponse) {\n if (errorOrResponse instanceof Response) {\n throw errorOrResponse;\n }\n\n throw new Response(undefined, {\n status: 500,\n statusText: 'Internal Server Error',\n });\n }\n\n return newSession;\n }\n\n return session!;\n }\n\n public handleClientError(request: Request): HandleAdminClientError {\n const {api, config, logger} = this;\n return handleClientErrorFactory({\n request,\n onError: async ({session, error}: OnErrorOptions) => {\n if (error.response.code === 401) {\n logger.debug('Responding to invalid access token', {\n shop: getShopFromRequest(request),\n });\n await invalidateAccessToken({config, api, logger}, session);\n\n respondToInvalidSessionToken({\n params: {config, api, logger},\n request,\n });\n }\n },\n });\n }\n\n private async exchangeToken({\n request,\n shop,\n sessionToken,\n requestedTokenType,\n }: {\n request: Request;\n shop: string;\n sessionToken: string;\n requestedTokenType: RequestedTokenType;\n }): Promise<{session: Session}> {\n const {api, config, logger} = this;\n\n try {\n return await api.auth.tokenExchange({\n sessionToken,\n shop,\n requestedTokenType,\n });\n } catch (error) {\n if (\n error instanceof InvalidJwtError ||\n (error instanceof HttpResponseError &&\n error.response.code === 400 &&\n error.response.body?.error === 'invalid_subject_token')\n ) {\n throw respondToInvalidSessionToken({\n params: {api, config, logger},\n request,\n retryRequest: true,\n });\n }\n\n throw new Response(undefined, {\n status: 500,\n statusText: 'Internal Server Error',\n });\n }\n }\n\n private async handleAfterAuthHook(\n params: BasicParams,\n session: Session,\n request: Request,\n sessionToken: string,\n ) {\n const {config} = params;\n await config.idempotentPromiseHandler.handlePromise({\n promiseFunction: () => {\n return triggerAfterAuthHook(params, session, request, this);\n },\n identifier: sessionToken,\n });\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token-exchange.mjs","sources":["../../../../../../../src/server/authenticate/admin/strategies/token-exchange.ts"],"sourcesContent":["import {\n HttpResponseError,\n InvalidJwtError,\n RequestedTokenType,\n Session,\n Shopify,\n} from '@shopify/shopify-api';\n\nimport {AppConfig, AppConfigArg} from '../../../config-types';\nimport {BasicParams} from '../../../types';\nimport {\n respondToInvalidSessionToken,\n invalidateAccessToken,\n getShopFromRequest,\n} from '../../helpers';\nimport {handleClientErrorFactory, triggerAfterAuthHook} from '../helpers';\nimport {HandleAdminClientError} from '../../../clients';\nimport type {\n ApiConfigWithFutureFlags,\n ApiFutureFlags,\n} from '../../../future/flags';\n\nimport {AuthorizationStrategy, SessionContext, OnErrorOptions} from './types';\n\nexport class TokenExchangeStrategy<Config extends AppConfigArg>\n implements AuthorizationStrategy\n{\n protected api: Shopify<\n ApiConfigWithFutureFlags<Config['future']>,\n ApiFutureFlags<Config['future']>\n >;\n\n protected config: AppConfig;\n protected logger: Shopify['logger'];\n\n public constructor({api, config, logger}: BasicParams<Config['future']>) {\n this.api = api;\n this.config = config;\n this.logger = logger;\n }\n\n public async respondToOAuthRequests(_request: Request): Promise<void> {}\n\n public async authenticate(\n request: Request,\n sessionContext: SessionContext,\n ): Promise<Session> {\n const {api, config, logger} = this;\n const {shop, session, sessionToken} = sessionContext;\n\n if (!sessionToken) throw new InvalidJwtError();\n\n if (!session || !session.isActive(undefined)) {\n logger.info('No valid session found', {shop});\n logger.info('Requesting offline access token', {shop});\n const {session: offlineSession} = await this.exchangeToken({\n request,\n sessionToken,\n shop,\n requestedTokenType: RequestedTokenType.OfflineAccessToken,\n });\n\n await config.sessionStorage!.storeSession(offlineSession);\n\n let newSession = offlineSession;\n\n if (config.useOnlineTokens) {\n logger.info('Requesting online access token', {shop});\n const {session: onlineSession} = await this.exchangeToken({\n request,\n sessionToken,\n shop,\n requestedTokenType: RequestedTokenType.OnlineAccessToken,\n });\n\n await config.sessionStorage!.storeSession(onlineSession);\n newSession = onlineSession;\n }\n\n logger.debug('Request is valid, loaded session from session token', {\n shop: newSession.shop,\n isOnline: newSession.isOnline,\n });\n\n try {\n await this.handleAfterAuthHook(\n {api, config, logger},\n newSession,\n request,\n sessionToken,\n );\n } catch (errorOrResponse) {\n if (errorOrResponse instanceof Response) {\n throw errorOrResponse;\n }\n\n throw new Response(undefined, {\n status: 500,\n statusText: 'Internal Server Error',\n });\n }\n\n return newSession;\n }\n\n return session!;\n }\n\n public handleClientError(request: Request): HandleAdminClientError {\n const {api, config, logger} = this;\n return handleClientErrorFactory({\n request,\n onError: async ({session, error}: OnErrorOptions) => {\n if (error.response.code === 401) {\n logger.debug('Responding to invalid access token', {\n shop: getShopFromRequest(request),\n });\n await invalidateAccessToken({config, api, logger}, session);\n\n respondToInvalidSessionToken({\n params: {config, api, logger},\n request,\n });\n }\n },\n });\n }\n\n private async exchangeToken({\n request,\n shop,\n sessionToken,\n requestedTokenType,\n }: {\n request: Request;\n shop: string;\n sessionToken: string;\n requestedTokenType: RequestedTokenType;\n }): Promise<{session: Session}> {\n const {api, config, logger} = this;\n\n try {\n return await api.auth.tokenExchange({\n sessionToken,\n shop,\n requestedTokenType,\n });\n } catch (error) {\n if (\n error instanceof InvalidJwtError ||\n (error instanceof HttpResponseError &&\n error.response.code === 400 &&\n error.response.body?.error === 'invalid_subject_token')\n ) {\n throw respondToInvalidSessionToken({\n params: {api, config, logger},\n request,\n retryRequest: true,\n });\n }\n\n throw new Response(undefined, {\n status: 500,\n statusText: 'Internal Server Error',\n });\n }\n }\n\n private async handleAfterAuthHook(\n params: BasicParams,\n session: Session,\n request: Request,\n sessionToken: string,\n ) {\n const {config} = params;\n await config.idempotentPromiseHandler.handlePromise({\n promiseFunction: () => {\n return triggerAfterAuthHook(params, session, request, this);\n },\n identifier: sessionToken,\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/flow/authenticate.ts"],"sourcesContent":["import {ShopifyRestResources} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../config-types';\nimport {adminClientFactory} from '../../clients/admin';\nimport {BasicParams} from '../../types';\n\nimport type {AuthenticateFlow, FlowContext} from './types';\n\nexport function authenticateFlowFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources = ShopifyRestResources,\n>(params: BasicParams): AuthenticateFlow<ConfigArg, Resources> {\n const {api, config, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<FlowContext<ConfigArg, Resources>> {\n logger.info('Authenticating flow request');\n\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for flow. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n const result = await api.flow.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!result.valid) {\n logger.error('Received an invalid flow request', {reason: result.reason});\n\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const payload = JSON.parse(rawBody);\n\n logger.debug('Flow request is valid, looking for an offline session', {\n shop: payload.shopify_domain,\n });\n\n const sessionId = api.session.getOfflineId(payload.shopify_domain);\n const session = await config.sessionStorage!.loadSession(sessionId);\n\n if (!session) {\n logger.info('Flow request could not find session', {\n shop: payload.shopify_domain,\n });\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n logger.debug('Found a session for the flow request', {shop: session.shop});\n\n return {\n session,\n payload,\n admin: adminClientFactory<ConfigArg, Resources>({params, session}),\n };\n };\n}\n"],"names":[],"mappings":";;AAQM,SAAU,uBAAuB,CAGrC,MAAmB,EAAA;IACnB,MAAM,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAC,GAAG,MAAM;AAEpC,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;AAEhB,QAAA,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC;AAE1C,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,uEAAuE,EACvE,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;YACrC,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACjB,YAAA,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAC,CAAC;AAEzE,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;QAEA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAEnC,QAAA,MAAM,CAAC,KAAK,CAAC,uDAAuD,EAAE;YACpE,IAAI,EAAE,OAAO,CAAC,cAAc;AAC7B,SAAA,CAAC;AAEF,QAAA,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC;QAClE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAe,CAAC,WAAW,CAAC,SAAS,CAAC;QAEnE,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE;gBACjD,IAAI,EAAE,OAAO,CAAC,cAAc;AAC7B,aAAA,CAAC;AACF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAC,CAAC;QAE1E,OAAO;YACL,OAAO;YACP,OAAO;YACP,KAAK,EAAE,kBAAkB,CAAuB,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SACnE;AACH,IAAA,CAAC;AACH;;;;"}
1
+ {"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/flow/authenticate.ts"],"sourcesContent":["import {adminClientFactory} from '../../clients/admin';\nimport {BasicParams} from '../../types';\n\nimport type {AuthenticateFlow, FlowContext} from './types';\n\nexport function authenticateFlowFactory(params: BasicParams): AuthenticateFlow {\n const {api, config, logger} = params;\n\n return async function authenticate(request: Request): Promise<FlowContext> {\n logger.info('Authenticating flow request');\n\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for flow. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n const result = await api.flow.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!result.valid) {\n logger.error('Received an invalid flow request', {reason: result.reason});\n\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const payload = JSON.parse(rawBody);\n\n logger.debug('Flow request is valid, looking for an offline session', {\n shop: payload.shopify_domain,\n });\n\n const sessionId = api.session.getOfflineId(payload.shopify_domain);\n const session = await config.sessionStorage!.loadSession(sessionId);\n\n if (!session) {\n logger.info('Flow request could not find session', {\n shop: payload.shopify_domain,\n });\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n logger.debug('Found a session for the flow request', {shop: session.shop});\n\n return {\n session,\n payload,\n admin: adminClientFactory({params, session}),\n };\n };\n}\n"],"names":[],"mappings":";;AAKM,SAAU,uBAAuB,CAAC,MAAmB,EAAA;IACzD,MAAM,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAC,GAAG,MAAM;AAEpC,IAAA,OAAO,eAAe,YAAY,CAAC,OAAgB,EAAA;AACjD,QAAA,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC;AAE1C,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,uEAAuE,EACvE,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;YACrC,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACjB,YAAA,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAC,CAAC;AAEzE,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;QAEA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAEnC,QAAA,MAAM,CAAC,KAAK,CAAC,uDAAuD,EAAE;YACpE,IAAI,EAAE,OAAO,CAAC,cAAc;AAC7B,SAAA,CAAC;AAEF,QAAA,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC;QAClE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAe,CAAC,WAAW,CAAC,SAAS,CAAC;QAEnE,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE;gBACjD,IAAI,EAAE,OAAO,CAAC,cAAc;AAC7B,aAAA,CAAC;AACF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAC,CAAC;QAE1E,OAAO;YACL,OAAO;YACP,OAAO;YACP,KAAK,EAAE,kBAAkB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SAC7C;AACH,IAAA,CAAC;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/fulfillment-service/authenticate.ts"],"sourcesContent":["import {ShopifyRestResources, ShopifyHeader} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../config-types';\nimport {adminClientFactory} from '../../clients/admin';\nimport {BasicParams} from '../../types';\nimport {createOrLoadOfflineSession} from '../helpers';\n\nimport type {\n AuthenticateFulfillmentService,\n FulfillmentServiceContext,\n} from './types';\n\nexport function authenticateFulfillmentServiceFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources = ShopifyRestResources,\n>(params: BasicParams): AuthenticateFulfillmentService<ConfigArg, Resources> {\n const {api, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<FulfillmentServiceContext<ConfigArg, Resources>> {\n logger.info('Authenticating fulfillment service request');\n\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for fulfillment service. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n const result = await api.fulfillmentService.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!result.valid) {\n logger.error('Received an invalid fulfillment service request', {\n reason: result.reason,\n });\n\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const payload = JSON.parse(rawBody);\n const shop = request.headers.get(ShopifyHeader.Domain) || '';\n\n logger.debug(\n 'Fulfillment service request is valid, looking for an offline session',\n {\n shop,\n },\n );\n\n const session = await createOrLoadOfflineSession(shop, params);\n\n if (!session) {\n logger.info('Fulfillment service request could not find session', {\n shop,\n });\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n logger.debug('Found a session for the fulfillment service request', {\n shop,\n });\n\n return {\n session,\n payload,\n admin: adminClientFactory<ConfigArg, Resources>({params, session}),\n };\n };\n}\n"],"names":[],"mappings":";;;;;;AAYM,SAAU,qCAAqC,CAGnD,MAAmB,EAAA;AACnB,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;AAEhB,QAAA,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC;AAEzD,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,sFAAsF,EACtF,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YACnD,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACjB,YAAA,MAAM,CAAC,KAAK,CAAC,iDAAiD,EAAE;gBAC9D,MAAM,EAAE,MAAM,CAAC,MAAM;AACtB,aAAA,CAAC;AAEF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;QAEA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AACnC,QAAA,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE;AAE5D,QAAA,MAAM,CAAC,KAAK,CACV,sEAAsE,EACtE;YACE,IAAI;AACL,SAAA,CACF;QAED,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC;QAE9D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE;gBAChE,IAAI;AACL,aAAA,CAAC;AACF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,qDAAqD,EAAE;YAClE,IAAI;AACL,SAAA,CAAC;QAEF,OAAO;YACL,OAAO;YACP,OAAO;YACP,KAAK,EAAE,kBAAkB,CAAuB,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SACnE;AACH,IAAA,CAAC;AACH;;;;"}
1
+ {"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/fulfillment-service/authenticate.ts"],"sourcesContent":["import {ShopifyHeader} from '@shopify/shopify-api';\n\nimport {adminClientFactory} from '../../clients/admin';\nimport {BasicParams} from '../../types';\nimport {createOrLoadOfflineSession} from '../helpers';\n\nimport type {\n AuthenticateFulfillmentService,\n FulfillmentServiceContext,\n} from './types';\n\nexport function authenticateFulfillmentServiceFactory(\n params: BasicParams,\n): AuthenticateFulfillmentService {\n const {api, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<FulfillmentServiceContext> {\n logger.info('Authenticating fulfillment service request');\n\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for fulfillment service. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n const result = await api.fulfillmentService.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!result.valid) {\n logger.error('Received an invalid fulfillment service request', {\n reason: result.reason,\n });\n\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const payload = JSON.parse(rawBody);\n const shop = request.headers.get(ShopifyHeader.Domain) || '';\n\n logger.debug(\n 'Fulfillment service request is valid, looking for an offline session',\n {\n shop,\n },\n );\n\n const session = await createOrLoadOfflineSession(shop, params);\n\n if (!session) {\n logger.info('Fulfillment service request could not find session', {\n shop,\n });\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n logger.debug('Found a session for the fulfillment service request', {\n shop,\n });\n\n return {\n session,\n payload,\n admin: adminClientFactory({params, session}),\n };\n };\n}\n"],"names":[],"mappings":";;;;;;AAWM,SAAU,qCAAqC,CACnD,MAAmB,EAAA;AAEnB,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;AAEhB,QAAA,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC;AAEzD,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,sFAAsF,EACtF,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YACnD,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACjB,YAAA,MAAM,CAAC,KAAK,CAAC,iDAAiD,EAAE;gBAC9D,MAAM,EAAE,MAAM,CAAC,MAAM;AACtB,aAAA,CAAC;AAEF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;QAEA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AACnC,QAAA,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE;AAE5D,QAAA,MAAM,CAAC,KAAK,CACV,sEAAsE,EACtE;YACE,IAAI;AACL,SAAA,CACF;QAED,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC;QAE9D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE;gBAChE,IAAI;AACL,aAAA,CAAC;AACF,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,aAAa;AAC1B,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,qDAAqD,EAAE;YAClE,IAAI;AACL,SAAA,CAAC;QAEF,OAAO;YACL,OAAO;YACP,OAAO;YACP,KAAK,EAAE,kBAAkB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SAC7C;AACH,IAAA,CAAC;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticate.mjs","sources":["../../../../../../../src/server/authenticate/public/appProxy/authenticate.ts"],"sourcesContent":["import {ShopifyRestResources} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../../config-types';\nimport {adminClientFactory, storefrontClientFactory} from '../../../clients';\nimport {BasicParams} from '../../../types';\n\nimport {\n AppProxyContext,\n AppProxyContextWithSession,\n AuthenticateAppProxy,\n LiquidResponseFunction,\n} from './types';\n\nexport function authenticateAppProxyFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources,\n>(params: BasicParams): AuthenticateAppProxy<ConfigArg, Resources> {\n const {api, config, logger} = params;\n\n return async function authenticate(\n request,\n ): Promise<\n AppProxyContext | AppProxyContextWithSession<ConfigArg, Resources>\n > {\n const url = new URL(request.url);\n const shop = url.searchParams.get('shop')!;\n logger.info('Authenticating app proxy request', {shop});\n\n if (!(await validateAppProxyHmac(params, url))) {\n logger.info('App proxy request has invalid signature', {shop});\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const sessionId = api.session.getOfflineId(shop);\n const session = await config.sessionStorage!.loadSession(sessionId);\n\n if (!session) {\n logger.debug('Could not find offline session, returning empty context', {\n shop,\n ...Object.fromEntries(url.searchParams.entries()),\n });\n\n const context: AppProxyContext = {\n liquid,\n session: undefined,\n admin: undefined,\n storefront: undefined,\n };\n\n return context;\n }\n\n const context: AppProxyContextWithSession<ConfigArg, Resources> = {\n liquid,\n session,\n admin: adminClientFactory<ConfigArg, Resources>({params, session}),\n storefront: storefrontClientFactory({params, session}),\n };\n\n return context;\n };\n}\n\nconst liquid: LiquidResponseFunction = (body, initAndOptions) => {\n const processedBody = processLiquidBody(body);\n\n if (typeof initAndOptions !== 'object') {\n return new Response(processedBody, {\n status: initAndOptions || 200,\n headers: {\n 'Content-Type': 'application/liquid',\n },\n });\n }\n\n const {layout, ...responseInit} = initAndOptions || {};\n const responseBody =\n layout === false ? `{% layout none %} ${processedBody}` : processedBody;\n\n const headers = new Headers(responseInit.headers);\n headers.set('Content-Type', 'application/liquid');\n\n return new Response(responseBody, {\n ...responseInit,\n headers,\n });\n};\n\nasync function validateAppProxyHmac(\n params: BasicParams,\n url: URL,\n): Promise<boolean> {\n const {api, logger} = params;\n\n try {\n let searchParams = new URLSearchParams(url.search);\n if (!searchParams.get('index')) {\n searchParams.delete('index');\n }\n\n let isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n\n if (!isValid) {\n const cleanPath = url.pathname\n .replace(/^\\//, '')\n .replace(/\\/$/, '')\n .replaceAll('/', '.');\n const data = `routes%2F${cleanPath}`;\n\n searchParams = new URLSearchParams(\n `?_data=${data}&${searchParams.toString().replace(/^\\?/, '')}`,\n );\n\n isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n\n if (!isValid) {\n const searchParams = new URLSearchParams(\n `?_data=${data}._index&${url.search.replace(/^\\?/, '')}`,\n );\n\n isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n }\n }\n\n return isValid;\n } catch (error) {\n const shop = url.searchParams.get('shop')!;\n logger.info(error.message, {shop});\n throw new Response(undefined, {status: 400, statusText: 'Bad Request'});\n }\n}\n\nfunction processLiquidBody(body: string) {\n return (\n body\n // Add trailing slashes to relative form action URLs\n .replaceAll(\n /<(form[^>]+)action=\"(\\/[^\"?]+)(\\?[^\"]+)?\">/g,\n '<$1action=\"$2/$3\">',\n )\n // Add trailing slashes to relative link href URLs\n .replaceAll(/<(a[^>]+)href=\"(\\/[^\"?]+)(\\?[^\"]+)?\">/g, '<$1href=\"$2/$3\">')\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authenticate.mjs","sources":["../../../../../../../src/server/authenticate/public/appProxy/authenticate.ts"],"sourcesContent":["import {adminClientFactory, storefrontClientFactory} from '../../../clients';\nimport {BasicParams} from '../../../types';\n\nimport {\n AppProxyContext,\n AppProxyContextWithSession,\n AuthenticateAppProxy,\n LiquidResponseFunction,\n} from './types';\n\nexport function authenticateAppProxyFactory(\n params: BasicParams,\n): AuthenticateAppProxy {\n const {api, config, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<AppProxyContext | AppProxyContextWithSession> {\n const url = new URL(request.url);\n const shop = url.searchParams.get('shop')!;\n logger.info('Authenticating app proxy request', {shop});\n\n if (!(await validateAppProxyHmac(params, url))) {\n logger.info('App proxy request has invalid signature', {shop});\n throw new Response(undefined, {\n status: 400,\n statusText: 'Bad Request',\n });\n }\n\n const sessionId = api.session.getOfflineId(shop);\n const session = await config.sessionStorage!.loadSession(sessionId);\n\n if (!session) {\n logger.debug('Could not find offline session, returning empty context', {\n shop,\n ...Object.fromEntries(url.searchParams.entries()),\n });\n\n const context: AppProxyContext = {\n liquid,\n session: undefined,\n admin: undefined,\n storefront: undefined,\n };\n\n return context;\n }\n\n const context: AppProxyContextWithSession = {\n liquid,\n session,\n admin: adminClientFactory({params, session}),\n storefront: storefrontClientFactory({params, session}),\n };\n\n return context;\n };\n}\n\nconst liquid: LiquidResponseFunction = (body, initAndOptions) => {\n const processedBody = processLiquidBody(body);\n\n if (typeof initAndOptions !== 'object') {\n return new Response(processedBody, {\n status: initAndOptions || 200,\n headers: {\n 'Content-Type': 'application/liquid',\n },\n });\n }\n\n const {layout, ...responseInit} = initAndOptions || {};\n const responseBody =\n layout === false ? `{% layout none %} ${processedBody}` : processedBody;\n\n const headers = new Headers(responseInit.headers);\n headers.set('Content-Type', 'application/liquid');\n\n return new Response(responseBody, {\n ...responseInit,\n headers,\n });\n};\n\nasync function validateAppProxyHmac(\n params: BasicParams,\n url: URL,\n): Promise<boolean> {\n const {api, logger} = params;\n\n try {\n let searchParams = new URLSearchParams(url.search);\n if (!searchParams.get('index')) {\n searchParams.delete('index');\n }\n\n let isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n\n if (!isValid) {\n const cleanPath = url.pathname\n .replace(/^\\//, '')\n .replace(/\\/$/, '')\n .replaceAll('/', '.');\n const data = `routes%2F${cleanPath}`;\n\n searchParams = new URLSearchParams(\n `?_data=${data}&${searchParams.toString().replace(/^\\?/, '')}`,\n );\n\n isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n\n if (!isValid) {\n const searchParams = new URLSearchParams(\n `?_data=${data}._index&${url.search.replace(/^\\?/, '')}`,\n );\n\n isValid = await api.utils.validateHmac(\n Object.fromEntries(searchParams.entries()),\n {signator: 'appProxy'},\n );\n }\n }\n\n return isValid;\n } catch (error) {\n const shop = url.searchParams.get('shop')!;\n logger.info(error.message, {shop});\n throw new Response(undefined, {status: 400, statusText: 'Bad Request'});\n }\n}\n\nfunction processLiquidBody(body: string) {\n return (\n body\n // Add trailing slashes to relative form action URLs\n .replaceAll(\n /<(form[^>]+)action=\"(\\/[^\"?]+)(\\?[^\"]+)?\">/g,\n '<$1action=\"$2/$3\">',\n )\n // Add trailing slashes to relative link href URLs\n .replaceAll(/<(a[^>]+)href=\"(\\/[^\"?]+)(\\?[^\"]+)?\">/g, '<$1href=\"$2/$3\">')\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"factory.mjs","sources":["../../../../../../src/server/authenticate/public/factory.ts"],"sourcesContent":["import {ShopifyRestResources} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../config-types';\nimport {BasicParams} from '../../types';\n\nimport {authenticateCheckoutFactory} from './checkout/authenticate';\nimport {authenticateAppProxyFactory} from './appProxy/authenticate';\nimport {authenticateCustomerAccountFactory} from './customer-account/authenticate';\nimport {AuthenticatePublic} from './types';\nimport {authenticatePOSFactory} from './pos/authenticate';\n\nexport function authenticatePublicFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources,\n>(params: BasicParams) {\n const authenticateCheckout = authenticateCheckoutFactory(params);\n const authenticateAppProxy = authenticateAppProxyFactory<\n ConfigArg,\n Resources\n >(params);\n const authenticateCustomerAccount =\n authenticateCustomerAccountFactory(params);\n const authenticatePOS = authenticatePOSFactory(params);\n\n const context: AuthenticatePublic<ConfigArg> = {\n checkout: authenticateCheckout,\n appProxy: authenticateAppProxy,\n customerAccount: authenticateCustomerAccount,\n pos: authenticatePOS,\n };\n\n return context;\n}\n"],"names":[],"mappings":";;;;;AAWM,SAAU,yBAAyB,CAGvC,MAAmB,EAAA;AACnB,IAAA,MAAM,oBAAoB,GAAG,2BAA2B,CAAC,MAAM,CAAC;AAChE,IAAA,MAAM,oBAAoB,GAAG,2BAA2B,CAGtD,MAAM,CAAC;AACT,IAAA,MAAM,2BAA2B,GAC/B,kCAAkC,CAAC,MAAM,CAAC;AAC5C,IAAA,MAAM,eAAe,GAAG,sBAAsB,CAAC,MAAM,CAAC;AAEtD,IAAA,MAAM,OAAO,GAAkC;AAC7C,QAAA,QAAQ,EAAE,oBAAoB;AAC9B,QAAA,QAAQ,EAAE,oBAAoB;AAC9B,QAAA,eAAe,EAAE,2BAA2B;AAC5C,QAAA,GAAG,EAAE,eAAe;KACrB;AAED,IAAA,OAAO,OAAO;AAChB;;;;"}
1
+ {"version":3,"file":"factory.mjs","sources":["../../../../../../src/server/authenticate/public/factory.ts"],"sourcesContent":["import {BasicParams} from '../../types';\n\nimport {authenticateCheckoutFactory} from './checkout/authenticate';\nimport {authenticateAppProxyFactory} from './appProxy/authenticate';\nimport {authenticateCustomerAccountFactory} from './customer-account/authenticate';\nimport {AuthenticatePublic} from './types';\nimport {authenticatePOSFactory} from './pos/authenticate';\n\nexport function authenticatePublicFactory(params: BasicParams) {\n const authenticateCheckout = authenticateCheckoutFactory(params);\n const authenticateAppProxy = authenticateAppProxyFactory(params);\n const authenticateCustomerAccount =\n authenticateCustomerAccountFactory(params);\n const authenticatePOS = authenticatePOSFactory(params);\n\n const context: AuthenticatePublic = {\n checkout: authenticateCheckout,\n appProxy: authenticateAppProxy,\n customerAccount: authenticateCustomerAccount,\n pos: authenticatePOS,\n };\n\n return context;\n}\n"],"names":[],"mappings":";;;;;AAQM,SAAU,yBAAyB,CAAC,MAAmB,EAAA;AAC3D,IAAA,MAAM,oBAAoB,GAAG,2BAA2B,CAAC,MAAM,CAAC;AAChE,IAAA,MAAM,oBAAoB,GAAG,2BAA2B,CAAC,MAAM,CAAC;AAChE,IAAA,MAAM,2BAA2B,GAC/B,kCAAkC,CAAC,MAAM,CAAC;AAC5C,IAAA,MAAM,eAAe,GAAG,sBAAsB,CAAC,MAAM,CAAC;AAEtD,IAAA,MAAM,OAAO,GAAuB;AAClC,QAAA,QAAQ,EAAE,oBAAoB;AAC9B,QAAA,QAAQ,EAAE,oBAAoB;AAC9B,QAAA,eAAe,EAAE,2BAA2B;AAC5C,QAAA,GAAG,EAAE,eAAe;KACrB;AAED,IAAA,OAAO,OAAO;AAChB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/webhooks/authenticate.ts"],"sourcesContent":["import {\n ShopifyRestResources,\n WebhookValidationErrorReason,\n} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../config-types';\nimport type {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients';\nimport {handleClientErrorFactory} from '../admin/helpers';\nimport {createOrLoadOfflineSession} from '../helpers';\n\nimport type {\n AuthenticateWebhook,\n WebhookContext,\n WebhookContextWithoutSession,\n} from './types';\n\nexport function authenticateWebhookFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources,\n Topics extends string,\n>(params: BasicParams): AuthenticateWebhook<ConfigArg, Resources, Topics> {\n const {api, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<WebhookContext<ConfigArg, Resources, Topics>> {\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for a webhook. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n\n const check = await api.webhooks.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!check.valid) {\n if (check.reason === WebhookValidationErrorReason.InvalidHmac) {\n logger.debug('Webhook HMAC validation failed', check);\n throw new Response(undefined, {\n status: 401,\n statusText: 'Unauthorized',\n });\n } else {\n logger.debug('Webhook validation failed', check);\n throw new Response(undefined, {status: 400, statusText: 'Bad Request'});\n }\n }\n const session = await createOrLoadOfflineSession(check.domain, params);\n const webhookContext: WebhookContextWithoutSession<Topics> = {\n apiVersion: check.apiVersion,\n shop: check.domain,\n topic: check.topic as Topics,\n webhookId: check.webhookId,\n payload: JSON.parse(rawBody),\n subTopic: check.subTopic || undefined,\n session: undefined,\n admin: undefined,\n };\n\n if (!session) {\n return webhookContext;\n }\n\n const admin = adminClientFactory<ConfigArg, Resources>({\n params,\n session,\n handleClientError: handleClientErrorFactory({request}),\n });\n\n return {\n ...webhookContext,\n session,\n admin,\n };\n };\n}\n"],"names":[],"mappings":";;;;;;;AAiBM,SAAU,0BAA0B,CAIxC,MAAmB,EAAA;AACnB,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;AAEhB,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,4EAA4E,EAC5E,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QAEpC,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YAChB,IAAI,KAAK,CAAC,MAAM,KAAK,4BAA4B,CAAC,WAAW,EAAE;AAC7D,gBAAA,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC;AACrD,gBAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,oBAAA,MAAM,EAAE,GAAG;AACX,oBAAA,UAAU,EAAE,cAAc;AAC3B,iBAAA,CAAC;YACJ;iBAAO;AACL,gBAAA,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC;AAChD,gBAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAC,CAAC;YACzE;QACF;QACA,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;AACtE,QAAA,MAAM,cAAc,GAAyC;YAC3D,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,IAAI,EAAE,KAAK,CAAC,MAAM;YAClB,KAAK,EAAE,KAAK,CAAC,KAAe;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;AAC1B,YAAA,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAC5B,YAAA,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;AACrC,YAAA,OAAO,EAAE,SAAS;AAClB,YAAA,KAAK,EAAE,SAAS;SACjB;QAED,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,cAAc;QACvB;QAEA,MAAM,KAAK,GAAG,kBAAkB,CAAuB;YACrD,MAAM;YACN,OAAO;AACP,YAAA,iBAAiB,EAAE,wBAAwB,CAAC,EAAC,OAAO,EAAC,CAAC;AACvD,SAAA,CAAC;QAEF,OAAO;AACL,YAAA,GAAG,cAAc;YACjB,OAAO;YACP,KAAK;SACN;AACH,IAAA,CAAC;AACH;;;;"}
1
+ {"version":3,"file":"authenticate.mjs","sources":["../../../../../../src/server/authenticate/webhooks/authenticate.ts"],"sourcesContent":["import {WebhookValidationErrorReason} from '@shopify/shopify-api';\n\nimport type {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients';\nimport {handleClientErrorFactory} from '../admin/helpers';\nimport {createOrLoadOfflineSession} from '../helpers';\n\nimport type {\n AuthenticateWebhook,\n WebhookContext,\n WebhookContextWithoutSession,\n} from './types';\n\nexport function authenticateWebhookFactory<Topics extends string>(\n params: BasicParams,\n): AuthenticateWebhook<Topics> {\n const {api, logger} = params;\n\n return async function authenticate(\n request: Request,\n ): Promise<WebhookContext<Topics>> {\n if (request.method !== 'POST') {\n logger.debug(\n 'Received a non-POST request for a webhook. Only POST requests are allowed.',\n {url: request.url, method: request.method},\n );\n throw new Response(undefined, {\n status: 405,\n statusText: 'Method not allowed',\n });\n }\n\n const rawBody = await request.text();\n\n const check = await api.webhooks.validate({\n rawBody,\n rawRequest: request,\n });\n\n if (!check.valid) {\n if (check.reason === WebhookValidationErrorReason.InvalidHmac) {\n logger.debug('Webhook HMAC validation failed', check);\n throw new Response(undefined, {\n status: 401,\n statusText: 'Unauthorized',\n });\n } else {\n logger.debug('Webhook validation failed', check);\n throw new Response(undefined, {status: 400, statusText: 'Bad Request'});\n }\n }\n const session = await createOrLoadOfflineSession(check.domain, params);\n const webhookContext: WebhookContextWithoutSession<Topics> = {\n apiVersion: check.apiVersion,\n shop: check.domain,\n topic: check.topic as Topics,\n webhookId: check.webhookId,\n payload: JSON.parse(rawBody),\n subTopic: check.subTopic || undefined,\n session: undefined,\n admin: undefined,\n };\n\n if (!session) {\n return webhookContext;\n }\n\n const admin = adminClientFactory({\n params,\n session,\n handleClientError: handleClientErrorFactory({request}),\n });\n\n return {\n ...webhookContext,\n session,\n admin,\n };\n };\n}\n"],"names":[],"mappings":";;;;;;;AAaM,SAAU,0BAA0B,CACxC,MAAmB,EAAA;AAEnB,IAAA,MAAM,EAAC,GAAG,EAAE,MAAM,EAAC,GAAG,MAAM;AAE5B,IAAA,OAAO,eAAe,YAAY,CAChC,OAAgB,EAAA;AAEhB,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,KAAK,CACV,4EAA4E,EAC5E,EAAC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAC,CAC3C;AACD,YAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,EAAE,GAAG;AACX,gBAAA,UAAU,EAAE,oBAAoB;AACjC,aAAA,CAAC;QACJ;AAEA,QAAA,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;QAEpC,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,OAAO;AACP,YAAA,UAAU,EAAE,OAAO;AACpB,SAAA,CAAC;AAEF,QAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YAChB,IAAI,KAAK,CAAC,MAAM,KAAK,4BAA4B,CAAC,WAAW,EAAE;AAC7D,gBAAA,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC;AACrD,gBAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE;AAC5B,oBAAA,MAAM,EAAE,GAAG;AACX,oBAAA,UAAU,EAAE,cAAc;AAC3B,iBAAA,CAAC;YACJ;iBAAO;AACL,gBAAA,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC;AAChD,gBAAA,MAAM,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAC,CAAC;YACzE;QACF;QACA,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;AACtE,QAAA,MAAM,cAAc,GAAyC;YAC3D,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,IAAI,EAAE,KAAK,CAAC,MAAM;YAClB,KAAK,EAAE,KAAK,CAAC,KAAe;YAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;AAC1B,YAAA,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AAC5B,YAAA,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS;AACrC,YAAA,OAAO,EAAE,SAAS;AAClB,YAAA,KAAK,EAAE,SAAS;SACjB;QAED,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,cAAc;QACvB;QAEA,MAAM,KAAK,GAAG,kBAAkB,CAAC;YAC/B,MAAM;YACN,OAAO;AACP,YAAA,iBAAiB,EAAE,wBAAwB,CAAC,EAAC,OAAO,EAAC,CAAC;AACvD,SAAA,CAAC;QAEF,OAAO;AACL,YAAA,GAAG,cAAc;YACjB,OAAO;YACP,KAAK;SACN;AACH,IAAA,CAAC;AACH;;;;"}
@@ -1,18 +1,7 @@
1
1
  import { graphqlClientFactory } from './graphql.mjs';
2
- import { restClientFactory } from './rest.mjs';
3
2
 
4
3
  function adminClientFactory({ params, handleClientError, session, }) {
5
- if (params.config.future.removeRest) {
6
- return {
7
- graphql: graphqlClientFactory({ params, session, handleClientError }),
8
- };
9
- }
10
4
  return {
11
- rest: restClientFactory({
12
- params,
13
- session,
14
- handleClientError,
15
- }),
16
5
  graphql: graphqlClientFactory({ params, session, handleClientError }),
17
6
  };
18
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.mjs","sources":["../../../../../../src/server/clients/admin/factory.ts"],"sourcesContent":["import {Session, ShopifyRestResources} from '@shopify/shopify-api';\n\nimport type {AppConfigArg} from '../../config-types';\nimport {BasicParams} from '../../types';\n\nimport {graphqlClientFactory} from './graphql';\nimport {restClientFactory} from './rest';\nimport type {AdminApiContext} from './types';\n\ninterface RestClientOptions {\n params: BasicParams;\n session: Session;\n handleClientError?: (error: any) => Promise<void>;\n}\n\nexport function adminClientFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources = ShopifyRestResources,\n>({\n params,\n handleClientError,\n session,\n}: RestClientOptions): AdminApiContext<ConfigArg, Resources> {\n if (params.config.future.removeRest) {\n return {\n graphql: graphqlClientFactory({params, session, handleClientError}),\n } as AdminApiContext<ConfigArg, Resources>;\n }\n\n return {\n rest: restClientFactory<Resources>({\n params,\n session,\n handleClientError,\n }),\n graphql: graphqlClientFactory({params, session, handleClientError}),\n } as AdminApiContext<ConfigArg, Resources>;\n}\n"],"names":[],"mappings":";;;AAeM,SAAU,kBAAkB,CAGhC,EACA,MAAM,EACN,iBAAiB,EACjB,OAAO,GACW,EAAA;IAClB,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE;QACnC,OAAO;YACL,OAAO,EAAE,oBAAoB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAC,CAAC;SAC3B;IAC5C;IAEA,OAAO;QACL,IAAI,EAAE,iBAAiB,CAAY;YACjC,MAAM;YACN,OAAO;YACP,iBAAiB;SAClB,CAAC;QACF,OAAO,EAAE,oBAAoB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAC,CAAC;KAC3B;AAC5C;;;;"}
1
+ {"version":3,"file":"factory.mjs","sources":["../../../../../../src/server/clients/admin/factory.ts"],"sourcesContent":["import {Session} from '@shopify/shopify-api';\n\nimport {BasicParams} from '../../types';\n\nimport {graphqlClientFactory} from './graphql';\nimport type {AdminApiContext} from './types';\n\ninterface AdminClientOptions {\n params: BasicParams;\n session: Session;\n handleClientError?: (error: any) => Promise<void>;\n}\n\nexport function adminClientFactory({\n params,\n handleClientError,\n session,\n}: AdminClientOptions): AdminApiContext {\n return {\n graphql: graphqlClientFactory({params, session, handleClientError}),\n };\n}\n"],"names":[],"mappings":";;AAaM,SAAU,kBAAkB,CAAC,EACjC,MAAM,EACN,iBAAiB,EACjB,OAAO,GACY,EAAA;IACnB,OAAO;QACL,OAAO,EAAE,oBAAoB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAC,CAAC;KACpE;AACH;;;;"}
@@ -1,7 +1,6 @@
1
1
  // eslint-disable-next-line no-warning-comments
2
2
  // TODO: This is actually just a call through to the Shopify API client, but with a different API. We should eventually
3
- // move this over to the library layer. While doing that, we should also allow the apiVersion to be passed into the REST
4
- // client request calls.
3
+ // move this over to the library layer.
5
4
  function graphqlClientFactory({ params, handleClientError, session, }) {
6
5
  return async function query(operation, options) {
7
6
  const client = new params.api.clients.Graphql({
@@ -1 +1 @@
1
- {"version":3,"file":"graphql.mjs","sources":["../../../../../../src/server/clients/admin/graphql.ts"],"sourcesContent":["import {AdminOperations} from '@shopify/admin-api-client';\n\nimport {GraphQLClient} from '../types';\n\nimport {AdminClientOptions} from './types';\n\n// eslint-disable-next-line no-warning-comments\n// TODO: This is actually just a call through to the Shopify API client, but with a different API. We should eventually\n// move this over to the library layer. While doing that, we should also allow the apiVersion to be passed into the REST\n// client request calls.\nexport function graphqlClientFactory({\n params,\n handleClientError,\n session,\n}: AdminClientOptions): GraphQLClient<AdminOperations> {\n return async function query(operation, options) {\n const client = new params.api.clients.Graphql({\n session,\n apiVersion: options?.apiVersion,\n });\n\n try {\n // We convert the incoming response to a Response object to bring this client closer to the Remix client.\n const apiResponse = await client.request(operation, {\n variables: options?.variables,\n retries: options?.tries ? options.tries - 1 : 0,\n headers: options?.headers,\n signal: options?.signal,\n });\n\n return new Response(JSON.stringify(apiResponse));\n } catch (error) {\n if (handleClientError) {\n throw await handleClientError({error, params, session});\n }\n\n throw error;\n }\n };\n}\n"],"names":[],"mappings":"AAMA;AACA;AACA;AACA;AACM,SAAU,oBAAoB,CAAC,EACnC,MAAM,EACN,iBAAiB,EACjB,OAAO,GACY,EAAA;AACnB,IAAA,OAAO,eAAe,KAAK,CAAC,SAAS,EAAE,OAAO,EAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;YAC5C,OAAO;YACP,UAAU,EAAE,OAAO,EAAE,UAAU;AAChC,SAAA,CAAC;AAEF,QAAA,IAAI;;YAEF,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE;gBAClD,SAAS,EAAE,OAAO,EAAE,SAAS;AAC7B,gBAAA,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC;gBAC/C,OAAO,EAAE,OAAO,EAAE,OAAO;gBACzB,MAAM,EAAE,OAAO,EAAE,MAAM;AACxB,aAAA,CAAC;YAEF,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClD;QAAE,OAAO,KAAK,EAAE;YACd,IAAI,iBAAiB,EAAE;gBACrB,MAAM,MAAM,iBAAiB,CAAC,EAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAC,CAAC;YACzD;AAEA,YAAA,MAAM,KAAK;QACb;AACF,IAAA,CAAC;AACH;;;;"}
1
+ {"version":3,"file":"graphql.mjs","sources":["../../../../../../src/server/clients/admin/graphql.ts"],"sourcesContent":["import {AdminOperations} from '@shopify/admin-api-client';\n\nimport {GraphQLClient} from '../types';\n\nimport {AdminClientOptions} from './types';\n\n// eslint-disable-next-line no-warning-comments\n// TODO: This is actually just a call through to the Shopify API client, but with a different API. We should eventually\n// move this over to the library layer.\nexport function graphqlClientFactory({\n params,\n handleClientError,\n session,\n}: AdminClientOptions): GraphQLClient<AdminOperations> {\n return async function query(operation, options) {\n const client = new params.api.clients.Graphql({\n session,\n apiVersion: options?.apiVersion,\n });\n\n try {\n // We convert the incoming response to a Response object to bring this client closer to the Remix client.\n const apiResponse = await client.request(operation, {\n variables: options?.variables,\n retries: options?.tries ? options.tries - 1 : 0,\n headers: options?.headers,\n signal: options?.signal,\n });\n\n return new Response(JSON.stringify(apiResponse));\n } catch (error) {\n if (handleClientError) {\n throw await handleClientError({error, params, session});\n }\n\n throw error;\n }\n };\n}\n"],"names":[],"mappings":"AAMA;AACA;AACA;AACM,SAAU,oBAAoB,CAAC,EACnC,MAAM,EACN,iBAAiB,EACjB,OAAO,GACY,EAAA;AACnB,IAAA,OAAO,eAAe,KAAK,CAAC,SAAS,EAAE,OAAO,EAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;YAC5C,OAAO;YACP,UAAU,EAAE,OAAO,EAAE,UAAU;AAChC,SAAA,CAAC;AAEF,QAAA,IAAI;;YAEF,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE;gBAClD,SAAS,EAAE,OAAO,EAAE,SAAS;AAC7B,gBAAA,OAAO,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC;gBAC/C,OAAO,EAAE,OAAO,EAAE,OAAO;gBACzB,MAAM,EAAE,OAAO,EAAE,MAAM;AACxB,aAAA,CAAC;YAEF,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClD;QAAE,OAAO,KAAK,EAAE;YACd,IAAI,iBAAiB,EAAE;gBACrB,MAAM,MAAM,iBAAiB,CAAC,EAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAC,CAAC;YACzD;AAEA,YAAA,MAAM,KAAK;QACb;AACF,IAAA,CAAC;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"flags.mjs","sources":["../../../../../src/server/future/flags.ts"],"sourcesContent":["import type {\n ConfigParams,\n Shopify,\n ShopifyRestResources,\n} from '@shopify/shopify-api';\n\nimport {AppConfig} from '../config-types';\n\n// When adding new flags, you should also add them to the `TEST_FUTURE_FLAGS` object in `test-config.ts` to ensure that\n// it doesn't cause regressions.\nexport interface FutureFlags {\n /**\n * When enabled, embedded apps will fetch access tokens via [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange).\n * This assumes the app has scopes declared for [Shopify managing installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).\n *\n * Learn more about this [new embedded app auth strategy](https://shopify.dev/docs/api/shopify-app-remix#embedded-auth-strategy).\n *\n * @default false\n */\n unstable_newEmbeddedAuthStrategy?: boolean;\n\n /**\n * When enabled, methods for interacting with the admin REST API will not be returned.\n *\n * This affects:\n *\n * * `authenticate.admin(request)`\n * * `authenticate.webhook(request)`\n * * `authenticate.flow(request)`\n * * `authenticate.appProxy(request)`\n * * `authenticate.fulfillmentService(request)`\n * * `unauthenticated.admin(shop)`\n *\n * In a future release we will remove REST from the package completely.\n *\n * Please see: [https://www.shopify.com/ca/partners/blog/all-in-on-graphql](https://www.shopify.com/ca/partners/blog/all-in-on-graphql)\n *\n * @default false\n */\n removeRest?: boolean;\n}\n\n// When adding new flags, use this format:\n// apiFutureFlag: Future extends FutureFlags ? Future['remixFutureFlag'] : false;\nexport interface ApiFutureFlags<_Future extends FutureFlagOptions> {\n // We're currently hardcoding this flag to true in our settings, so we should propagate it here\n lineItemBilling: true;\n unstable_managedPricingSupport: true;\n}\n\nexport type ApiConfigWithFutureFlags<Future extends FutureFlagOptions> =\n ConfigParams<ShopifyRestResources, ApiFutureFlags<Future>>;\n\nexport type FutureFlagOptions = FutureFlags | undefined;\n\nexport type FeatureEnabled<\n Future extends FutureFlagOptions,\n Flag extends keyof FutureFlags,\n> = Future extends FutureFlags\n ? Future[Flag] extends true\n ? true\n : false\n : false;\n\nexport function logDisabledFutureFlags(\n config: AppConfig,\n logger: Shopify['logger'],\n) {\n const logFlag = (flag: string, message: string) =>\n logger.info(`Future flag ${flag} is disabled.\\n\\n ${message}\\n`);\n\n if (!config.future.unstable_newEmbeddedAuthStrategy) {\n logFlag(\n 'unstable_newEmbeddedAuthStrategy',\n 'Enable this to use OAuth token exchange instead of auth code to generate API access tokens.' +\n '\\n Your app must be using Shopify managed install: https://shopify.dev/docs/apps/auth/installation',\n );\n }\n}\n"],"names":[],"mappings":"AAgEM,SAAU,sBAAsB,CACpC,MAAiB,EACjB,MAAyB,EAAA;AAEzB,IAAA,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,OAAe,KAC5C,MAAM,CAAC,IAAI,CAAC,CAAA,YAAA,EAAe,IAAI,sBAAsB,OAAO,CAAA,EAAA,CAAI,CAAC;AAEnE,IAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,gCAAgC,EAAE;QACnD,OAAO,CACL,kCAAkC,EAClC,6FAA6F;AAC3F,YAAA,qGAAqG,CACxG;IACH;AACF;;;;"}
1
+ {"version":3,"file":"flags.mjs","sources":["../../../../../src/server/future/flags.ts"],"sourcesContent":["import type {ConfigParams, Shopify} from '@shopify/shopify-api';\n\nimport {AppConfig} from '../config-types';\n\n// When adding new flags, you should also add them to the `TEST_FUTURE_FLAGS` object in `test-config.ts` to ensure that\n// it doesn't cause regressions.\nexport interface FutureFlags {\n /**\n * When enabled, embedded apps will fetch access tokens via [token exchange](https://shopify.dev/docs/apps/auth/get-access-tokens/token-exchange).\n * This assumes the app has scopes declared for [Shopify managing installation](https://shopify.dev/docs/apps/auth/installation#shopify-managed-installation).\n *\n * Learn more about this [new embedded app auth strategy](https://shopify.dev/docs/api/shopify-app-remix#embedded-auth-strategy).\n *\n * @default false\n */\n unstable_newEmbeddedAuthStrategy?: boolean;\n}\n\n// When adding new flags, use this format:\n// apiFutureFlag: Future extends FutureFlags ? Future['remixFutureFlag'] : false;\nexport interface ApiFutureFlags<_Future extends FutureFlagOptions> {\n unstable_managedPricingSupport: true;\n}\n\nexport type ApiConfigWithFutureFlags<Future extends FutureFlagOptions> =\n ConfigParams<ApiFutureFlags<Future>>;\n\nexport type FutureFlagOptions = FutureFlags | undefined;\n\nexport type FeatureEnabled<\n Future extends FutureFlagOptions,\n Flag extends keyof FutureFlags,\n> = Future extends FutureFlags\n ? Future[Flag] extends true\n ? true\n : false\n : false;\n\nexport function logDisabledFutureFlags(\n config: AppConfig,\n logger: Shopify['logger'],\n) {\n const logFlag = (flag: string, message: string) =>\n logger.info(`Future flag ${flag} is disabled.\\n\\n ${message}\\n`);\n\n if (!config.future.unstable_newEmbeddedAuthStrategy) {\n logFlag(\n 'unstable_newEmbeddedAuthStrategy',\n 'Enable this to use OAuth token exchange instead of auth code to generate API access tokens.' +\n '\\n Your app must be using Shopify managed install: https://shopify.dev/docs/apps/auth/installation',\n );\n }\n}\n"],"names":[],"mappings":"AAsCM,SAAU,sBAAsB,CACpC,MAAiB,EACjB,MAAyB,EAAA;AAEzB,IAAA,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,OAAe,KAC5C,MAAM,CAAC,IAAI,CAAC,CAAA,YAAA,EAAe,IAAI,sBAAsB,OAAO,CAAA,EAAA,CAAI,CAAC;AAEnE,IAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,gCAAgC,EAAE;QACnD,OAAO,CACL,kCAAkC,EAClC,6FAA6F;AAC3F,YAAA,qGAAqG,CACxG;IACH;AACF;;;;"}
@@ -1,6 +1,6 @@
1
1
  import '@shopify/shopify-api/adapters/web-api';
2
2
  import { setAbstractRuntimeString } from '@shopify/shopify-api/runtime';
3
- export { ApiVersion, BillingInterval, BillingReplacementBehavior, DeliveryMethod, LATEST_API_VERSION, LogSeverity, RELEASE_CANDIDATE_API_VERSION, Session } from '@shopify/shopify-api';
3
+ export { ApiVersion, BillingInterval, BillingReplacementBehavior, DeliveryMethod, LogSeverity, Session } from '@shopify/shopify-api';
4
4
  export { AppDistribution, LoginErrorType } from './types.mjs';
5
5
  export { boundary } from './boundary/index.mjs';
6
6
  export { shopifyApp } from './shopify-app.mjs';
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../../src/server/index.ts"],"sourcesContent":["import '@shopify/shopify-api/adapters/web-api';\nimport {setAbstractRuntimeString} from '@shopify/shopify-api/runtime';\n\nsetAbstractRuntimeString(() => {\n return `Remix`;\n});\n\nexport {\n LATEST_API_VERSION,\n RELEASE_CANDIDATE_API_VERSION,\n LogSeverity,\n DeliveryMethod,\n BillingInterval,\n BillingReplacementBehavior,\n ApiVersion,\n Session,\n} from '@shopify/shopify-api';\n\nexport type {JwtPayload} from '@shopify/shopify-api';\n\nexport type * from './types-contexts';\nexport type {ShopifyApp, LoginError} from './types';\nexport {LoginErrorType, AppDistribution} from './types';\nexport {boundary} from './boundary';\nexport {shopifyApp} from './shopify-app';\nexport * from './errors';\n"],"names":[],"mappings":";;;;;;;;AAGA,wBAAwB,CAAC,MAAK;AAC5B,IAAA,OAAO,OAAO;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../../src/server/index.ts"],"sourcesContent":["import '@shopify/shopify-api/adapters/web-api';\nimport {setAbstractRuntimeString} from '@shopify/shopify-api/runtime';\n\nsetAbstractRuntimeString(() => {\n return `Remix`;\n});\n\nexport {\n LogSeverity,\n DeliveryMethod,\n BillingInterval,\n BillingReplacementBehavior,\n ApiVersion,\n Session,\n} from '@shopify/shopify-api';\n\nexport type {JwtPayload} from '@shopify/shopify-api';\n\nexport type * from './types-contexts';\nexport type {ShopifyApp, LoginError} from './types';\nexport {LoginErrorType, AppDistribution} from './types';\nexport {boundary} from './boundary';\nexport {shopifyApp} from './shopify-app';\nexport * from './errors';\n"],"names":[],"mappings":";;;;;;;;AAGA,wBAAwB,CAAC,MAAK;AAC5B,IAAA,OAAO,OAAO;AAChB,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import semver from 'semver';
1
+ import { compare } from 'compare-versions';
2
2
  import { FeatureDeprecatedError } from '@shopify/shopify-api';
3
3
  import { SHOPIFY_REMIX_LIBRARY_VERSION } from './version.mjs';
4
4
 
@@ -10,7 +10,7 @@ function overrideLogger(logger) {
10
10
  const warningFunction = (message, context = {}) => logger.warning(message, { ...baseContext, ...context });
11
11
  function deprecated(warningFunction) {
12
12
  return function (version, message) {
13
- if (semver.gte(SHOPIFY_REMIX_LIBRARY_VERSION, version)) {
13
+ if (compare(SHOPIFY_REMIX_LIBRARY_VERSION, version, '>=')) {
14
14
  throw new FeatureDeprecatedError(`Feature was deprecated in version ${version}`);
15
15
  }
16
16
  return warningFunction(`[Deprecated | ${version}] ${message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"override-logger.mjs","sources":["../../../../src/server/override-logger.ts"],"sourcesContent":["import semver from 'semver';\nimport {FeatureDeprecatedError, Shopify} from '@shopify/shopify-api';\n\nimport {SHOPIFY_REMIX_LIBRARY_VERSION} from './version';\n\n// eslint-disable-next-line no-warning-comments\n// TODO This has been copied from shopify-app-express, it should be extracted into a shared package\n// https://github.com/orgs/Shopify/projects/6899/views/1?pane=issue&itemId=28358070\nexport function overrideLogger(logger: Shopify['logger']): Shopify['logger'] {\n const baseContext = {package: 'shopify-app'};\n\n const warningFunction: Shopify['logger']['warning'] = (\n message,\n context = {},\n ) => logger.warning(message, {...baseContext, ...context});\n\n function deprecated(warningFunction: Shopify['logger']['warning']) {\n return function (version: string, message: string): Promise<void> {\n if (semver.gte(SHOPIFY_REMIX_LIBRARY_VERSION, version)) {\n throw new FeatureDeprecatedError(\n `Feature was deprecated in version ${version}`,\n );\n }\n\n return warningFunction(`[Deprecated | ${version}] ${message}`);\n };\n }\n\n return {\n ...logger,\n log: (severity, message, context = {}) =>\n logger.log(severity, message, {...baseContext, ...context}),\n debug: (message, context = {}) =>\n logger.debug(message, {...baseContext, ...context}),\n info: (message, context = {}) =>\n logger.info(message, {...baseContext, ...context}),\n warning: warningFunction,\n error: (message, context = {}) =>\n logger.error(message, {...baseContext, ...context}),\n deprecated: deprecated(warningFunction),\n };\n}\n"],"names":[],"mappings":";;;;AAKA;AACA;AACA;AACM,SAAU,cAAc,CAAC,MAAyB,EAAA;AACtD,IAAA,MAAM,WAAW,GAAG,EAAC,OAAO,EAAE,aAAa,EAAC;IAE5C,MAAM,eAAe,GAAiC,CACpD,OAAO,EACP,OAAO,GAAG,EAAE,KACT,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;IAE1D,SAAS,UAAU,CAAC,eAA6C,EAAA;QAC/D,OAAO,UAAU,OAAe,EAAE,OAAe,EAAA;YAC/C,IAAI,MAAM,CAAC,GAAG,CAAC,6BAA6B,EAAE,OAAO,CAAC,EAAE;AACtD,gBAAA,MAAM,IAAI,sBAAsB,CAC9B,qCAAqC,OAAO,CAAA,CAAE,CAC/C;YACH;YAEA,OAAO,eAAe,CAAC,CAAA,cAAA,EAAiB,OAAO,KAAK,OAAO,CAAA,CAAE,CAAC;AAChE,QAAA,CAAC;IACH;IAEA,OAAO;AACL,QAAA,GAAG,MAAM;QACT,GAAG,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,KACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;QAC7D,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,KAC3B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;QACrD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,KAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;AACpD,QAAA,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,KAC3B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;AACrD,QAAA,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC;KACxC;AACH;;;;"}
1
+ {"version":3,"file":"override-logger.mjs","sources":["../../../../src/server/override-logger.ts"],"sourcesContent":["import {compare} from 'compare-versions';\nimport {FeatureDeprecatedError, Shopify} from '@shopify/shopify-api';\n\nimport {SHOPIFY_REMIX_LIBRARY_VERSION} from './version';\n\n// eslint-disable-next-line no-warning-comments\n// TODO This has been copied from shopify-app-express, it should be extracted into a shared package\n// https://github.com/orgs/Shopify/projects/6899/views/1?pane=issue&itemId=28358070\nexport function overrideLogger(logger: Shopify['logger']): Shopify['logger'] {\n const baseContext = {package: 'shopify-app'};\n\n const warningFunction: Shopify['logger']['warning'] = (\n message,\n context = {},\n ) => logger.warning(message, {...baseContext, ...context});\n\n function deprecated(warningFunction: Shopify['logger']['warning']) {\n return function (version: string, message: string): Promise<void> {\n if (compare(SHOPIFY_REMIX_LIBRARY_VERSION, version, '>=')) {\n throw new FeatureDeprecatedError(\n `Feature was deprecated in version ${version}`,\n );\n }\n\n return warningFunction(`[Deprecated | ${version}] ${message}`);\n };\n }\n\n return {\n ...logger,\n log: (severity, message, context = {}) =>\n logger.log(severity, message, {...baseContext, ...context}),\n debug: (message, context = {}) =>\n logger.debug(message, {...baseContext, ...context}),\n info: (message, context = {}) =>\n logger.info(message, {...baseContext, ...context}),\n warning: warningFunction,\n error: (message, context = {}) =>\n logger.error(message, {...baseContext, ...context}),\n deprecated: deprecated(warningFunction),\n };\n}\n"],"names":[],"mappings":";;;;AAKA;AACA;AACA;AACM,SAAU,cAAc,CAAC,MAAyB,EAAA;AACtD,IAAA,MAAM,WAAW,GAAG,EAAC,OAAO,EAAE,aAAa,EAAC;IAE5C,MAAM,eAAe,GAAiC,CACpD,OAAO,EACP,OAAO,GAAG,EAAE,KACT,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;IAE1D,SAAS,UAAU,CAAC,eAA6C,EAAA;QAC/D,OAAO,UAAU,OAAe,EAAE,OAAe,EAAA;YAC/C,IAAI,OAAO,CAAC,6BAA6B,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;AACzD,gBAAA,MAAM,IAAI,sBAAsB,CAC9B,qCAAqC,OAAO,CAAA,CAAE,CAC/C;YACH;YAEA,OAAO,eAAe,CAAC,CAAA,cAAA,EAAiB,OAAO,KAAK,OAAO,CAAA,CAAE,CAAC;AAChE,QAAA,CAAC;IACH;IAEA,OAAO;AACL,QAAA,GAAG,MAAM;QACT,GAAG,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,KACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;QAC7D,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,KAC3B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;QACrD,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,KAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;AACpD,QAAA,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,KAC3B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAC,GAAG,WAAW,EAAE,GAAG,OAAO,EAAC,CAAC;AACrD,QAAA,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC;KACxC;AACH;;;;"}
@@ -1,5 +1,5 @@
1
1
  import '@shopify/shopify-api/adapters/web-api';
2
- import { ShopifyError, shopifyApi, LATEST_API_VERSION } from '@shopify/shopify-api';
2
+ import { ShopifyError, shopifyApi } from '@shopify/shopify-api';
3
3
  import { AppDistribution } from './types.mjs';
4
4
  import { SHOPIFY_REMIX_LIBRARY_VERSION } from './version.mjs';
5
5
  import { registerWebhooksFactory } from './authenticate/webhooks/register.mjs';
@@ -124,11 +124,10 @@ function deriveApi(appConfig) {
124
124
  hostScheme: appUrl.protocol.replace(':', ''),
125
125
  userAgentPrefix,
126
126
  isEmbeddedApp: appConfig.isEmbeddedApp ?? true,
127
- apiVersion: appConfig.apiVersion ?? LATEST_API_VERSION,
127
+ apiVersion: appConfig.apiVersion,
128
128
  isCustomStoreApp: appConfig.distribution === AppDistribution.ShopifyAdmin,
129
129
  billing: appConfig.billing,
130
130
  future: {
131
- lineItemBilling: true,
132
131
  unstable_managedPricingSupport: true,
133
132
  },
134
133
  _logDisabledFutureFlags: false,
@@ -1 +1 @@
1
- {"version":3,"file":"shopify-app.mjs","sources":["../../../../src/server/shopify-app.ts"],"sourcesContent":["import '@shopify/shopify-api/adapters/web-api';\nimport {\n ConfigInterface as ApiConfig,\n LATEST_API_VERSION,\n ShopifyError,\n ShopifyRestResources,\n shopifyApi,\n} from '@shopify/shopify-api';\nimport {SessionStorage} from '@shopify/shopify-app-session-storage';\n\nimport {type AppConfig, type AppConfigArg} from './config-types';\nimport {\n AppDistribution,\n type BasicParams,\n type ShopifyApp,\n type ShopifyAppBase,\n type AdminApp,\n type SingleMerchantApp,\n type AppStoreApp,\n} from './types';\nimport {SHOPIFY_REMIX_LIBRARY_VERSION} from './version';\nimport {registerWebhooksFactory} from './authenticate/webhooks';\nimport {authStrategyFactory} from './authenticate/admin/authenticate';\nimport {authenticateWebhookFactory} from './authenticate/webhooks/authenticate';\nimport {overrideLogger} from './override-logger';\nimport {addDocumentResponseHeadersFactory} from './authenticate/helpers';\nimport {loginFactory} from './authenticate/login/login';\nimport {unauthenticatedAdminContextFactory} from './unauthenticated/admin';\nimport {authenticatePublicFactory} from './authenticate/public';\nimport {unauthenticatedStorefrontContextFactory} from './unauthenticated/storefront';\nimport {AuthCodeFlowStrategy} from './authenticate/admin/strategies/auth-code-flow';\nimport {TokenExchangeStrategy} from './authenticate/admin/strategies/token-exchange';\nimport {MerchantCustomAuth} from './authenticate/admin/strategies/merchant-custom-app';\nimport {IdempotentPromiseHandler} from './authenticate/helpers/idempotent-promise-handler';\nimport {authenticateFlowFactory} from './authenticate/flow/authenticate';\nimport {authenticateFulfillmentServiceFactory} from './authenticate/fulfillment-service/authenticate';\nimport {FutureFlagOptions, logDisabledFutureFlags} from './future/flags';\n\n/**\n * Creates an object your app will use to interact with Shopify.\n *\n * @param appConfig Configuration options for your Shopify app, such as the scopes your app needs.\n * @returns `ShopifyApp` An object constructed using your appConfig. It has methods for interacting with Shopify.\n *\n * @example\n * <caption>The minimum viable configuration</caption>\n * ```ts\n * // /shopify.server.ts\n * import { shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * apiKey: process.env.SHOPIFY_API_KEY!,\n * apiSecretKey: process.env.SHOPIFY_API_SECRET!,\n * scopes: process.env.SCOPES?.split(\",\")!,\n * appUrl: process.env.SHOPIFY_APP_URL!,\n * });\n * export default shopify;\n * ```\n */\nexport function shopifyApp<\n Config extends AppConfigArg<Resources, Storage, Future>,\n Resources extends ShopifyRestResources,\n Storage extends SessionStorage,\n Future extends FutureFlagOptions = Config['future'],\n>(appConfig: Readonly<Config>): ShopifyApp<Config> {\n const api = deriveApi(appConfig);\n const config = deriveConfig<Storage>(appConfig, api.config);\n const logger = overrideLogger(api.logger);\n\n if (appConfig.webhooks) {\n api.webhooks.addHandlers(appConfig.webhooks);\n }\n\n const params: BasicParams = {api, config, logger};\n\n let strategy;\n if (config.distribution === AppDistribution.ShopifyAdmin) {\n strategy = new MerchantCustomAuth(params);\n } else if (\n config.future.unstable_newEmbeddedAuthStrategy &&\n config.isEmbeddedApp\n ) {\n strategy = new TokenExchangeStrategy(params);\n } else {\n strategy = new AuthCodeFlowStrategy(params);\n }\n\n const authStrategy = authStrategyFactory<Config, Resources>({\n ...params,\n strategy,\n });\n\n const shopify:\n | AdminApp<Config>\n | AppStoreApp<Config>\n | SingleMerchantApp<Config> = {\n sessionStorage: config.sessionStorage,\n addDocumentResponseHeaders: addDocumentResponseHeadersFactory(params),\n registerWebhooks: registerWebhooksFactory(params),\n authenticate: {\n admin: authStrategy,\n flow: authenticateFlowFactory<Config, Resources>(params),\n public: authenticatePublicFactory<Config, Resources>(params),\n fulfillmentService: authenticateFulfillmentServiceFactory<\n Config,\n Resources\n >(params),\n webhook: authenticateWebhookFactory<Config, Resources, string>(params),\n },\n unauthenticated: {\n admin: unauthenticatedAdminContextFactory<Config, Resources>(params),\n storefront: unauthenticatedStorefrontContextFactory(params),\n },\n };\n\n if (\n isAppStoreApp(shopify, appConfig) ||\n isSingleMerchantApp(shopify, appConfig)\n ) {\n shopify.login = loginFactory(params);\n }\n\n logDisabledFutureFlags(config, logger);\n\n return shopify as ShopifyApp<Config>;\n}\n\nfunction isAppStoreApp<Config extends AppConfigArg>(\n _shopify: ShopifyAppBase<Config>,\n config: Config,\n): _shopify is AppStoreApp<Config> {\n return config.distribution === AppDistribution.AppStore;\n}\n\nfunction isSingleMerchantApp<Config extends AppConfigArg>(\n _shopify: ShopifyAppBase<Config>,\n config: Config,\n): _shopify is SingleMerchantApp<Config> {\n return config.distribution === AppDistribution.SingleMerchant;\n}\n\n// This function is only exported so we can unit test it without having to mock the underlying module.\n// It's not available to consumers of the library because it is not exported in the index module, and never should be.\nexport function deriveApi(appConfig: AppConfigArg): BasicParams['api'] {\n let appUrl: URL;\n try {\n appUrl = new URL(appConfig.appUrl);\n } catch (error) {\n const message =\n appConfig.appUrl === ''\n ? `Detected an empty appUrl configuration, please make sure to set the necessary environment variables.\\n` +\n `If you're deploying your app, you can find more information at https://shopify.dev/docs/apps/launch/deployment/deploy-web-app/deploy-to-hosting-service#step-4-set-up-environment-variables`\n : `Invalid appUrl configuration '${appConfig.appUrl}', please provide a valid URL.`;\n throw new ShopifyError(message);\n }\n\n /* eslint-disable no-process-env */\n if (appUrl.hostname === 'localhost' && !appUrl.port && process.env.PORT) {\n appUrl.port = process.env.PORT;\n }\n /* eslint-enable no-process-env */\n appConfig.appUrl = appUrl.origin;\n\n let userAgentPrefix = `Shopify Remix Library v${SHOPIFY_REMIX_LIBRARY_VERSION}`;\n if (appConfig.userAgentPrefix) {\n userAgentPrefix = `${appConfig.userAgentPrefix} | ${userAgentPrefix}`;\n }\n\n return shopifyApi({\n ...appConfig,\n hostName: appUrl.host,\n hostScheme: appUrl.protocol.replace(':', '') as 'http' | 'https',\n userAgentPrefix,\n isEmbeddedApp: appConfig.isEmbeddedApp ?? true,\n apiVersion: appConfig.apiVersion ?? LATEST_API_VERSION,\n isCustomStoreApp: appConfig.distribution === AppDistribution.ShopifyAdmin,\n billing: appConfig.billing as ApiConfig['billing'],\n future: {\n lineItemBilling: true,\n unstable_managedPricingSupport: true,\n },\n _logDisabledFutureFlags: false,\n });\n}\n\nfunction deriveConfig<Storage extends SessionStorage>(\n appConfig: AppConfigArg,\n apiConfig: ApiConfig,\n): AppConfig<Storage> {\n if (\n !appConfig.sessionStorage &&\n appConfig.distribution !== AppDistribution.ShopifyAdmin\n ) {\n throw new ShopifyError(\n 'Please provide a valid session storage. Refer to https://github.com/Shopify/shopify-app-js/blob/main/README.md#session-storage-options for options.',\n );\n }\n\n const authPathPrefix = appConfig.authPathPrefix || '/auth';\n appConfig.distribution = appConfig.distribution ?? AppDistribution.AppStore;\n\n return {\n ...appConfig,\n ...apiConfig,\n billing: appConfig.billing as ApiConfig['billing'],\n scopes: apiConfig.scopes,\n idempotentPromiseHandler: new IdempotentPromiseHandler(),\n canUseLoginForm: appConfig.distribution !== AppDistribution.ShopifyAdmin,\n useOnlineTokens: appConfig.useOnlineTokens ?? false,\n hooks: appConfig.hooks ?? {},\n sessionStorage: appConfig.sessionStorage as Storage,\n future: appConfig.future ?? {},\n auth: {\n path: authPathPrefix,\n callbackPath: `${authPathPrefix}/callback`,\n patchSessionTokenPath: `${authPathPrefix}/session-token`,\n exitIframePath: `${authPathPrefix}/exit-iframe`,\n loginPath: `${authPathPrefix}/login`,\n },\n distribution: appConfig.distribution,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shopify-app.mjs","sources":["../../../../src/server/shopify-app.ts"],"sourcesContent":["import '@shopify/shopify-api/adapters/web-api';\nimport {\n ConfigInterface as ApiConfig,\n ShopifyError,\n shopifyApi,\n} from '@shopify/shopify-api';\nimport {SessionStorage} from '@shopify/shopify-app-session-storage';\n\nimport {type AppConfig, type AppConfigArg} from './config-types';\nimport {\n AppDistribution,\n type BasicParams,\n type ShopifyApp,\n type ShopifyAppBase,\n type AdminApp,\n type SingleMerchantApp,\n type AppStoreApp,\n} from './types';\nimport {SHOPIFY_REMIX_LIBRARY_VERSION} from './version';\nimport {registerWebhooksFactory} from './authenticate/webhooks';\nimport {authStrategyFactory} from './authenticate/admin/authenticate';\nimport {authenticateWebhookFactory} from './authenticate/webhooks/authenticate';\nimport {overrideLogger} from './override-logger';\nimport {addDocumentResponseHeadersFactory} from './authenticate/helpers';\nimport {loginFactory} from './authenticate/login/login';\nimport {unauthenticatedAdminContextFactory} from './unauthenticated/admin';\nimport {authenticatePublicFactory} from './authenticate/public';\nimport {unauthenticatedStorefrontContextFactory} from './unauthenticated/storefront';\nimport {AuthCodeFlowStrategy} from './authenticate/admin/strategies/auth-code-flow';\nimport {TokenExchangeStrategy} from './authenticate/admin/strategies/token-exchange';\nimport {MerchantCustomAuth} from './authenticate/admin/strategies/merchant-custom-app';\nimport {IdempotentPromiseHandler} from './authenticate/helpers/idempotent-promise-handler';\nimport {authenticateFlowFactory} from './authenticate/flow/authenticate';\nimport {authenticateFulfillmentServiceFactory} from './authenticate/fulfillment-service/authenticate';\nimport {FutureFlagOptions, logDisabledFutureFlags} from './future/flags';\n\n/**\n * Creates an object your app will use to interact with Shopify.\n *\n * @param appConfig Configuration options for your Shopify app, such as the scopes your app needs.\n * @returns `ShopifyApp` An object constructed using your appConfig. It has methods for interacting with Shopify.\n *\n * @example\n * <caption>The minimum viable configuration</caption>\n * ```ts\n * // /shopify.server.ts\n * import { shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * apiKey: process.env.SHOPIFY_API_KEY!,\n * apiSecretKey: process.env.SHOPIFY_API_SECRET!,\n * scopes: process.env.SCOPES?.split(\",\")!,\n * appUrl: process.env.SHOPIFY_APP_URL!,\n * });\n * export default shopify;\n * ```\n */\nexport function shopifyApp<\n Config extends AppConfigArg<Storage, Future>,\n Storage extends SessionStorage,\n Future extends FutureFlagOptions = Config['future'],\n>(appConfig: Readonly<Config>): ShopifyApp<Config> {\n const api = deriveApi(appConfig);\n const config = deriveConfig<Storage>(appConfig, api.config);\n const logger = overrideLogger(api.logger);\n\n if (appConfig.webhooks) {\n api.webhooks.addHandlers(appConfig.webhooks);\n }\n\n const params: BasicParams = {api, config, logger};\n\n let strategy;\n if (config.distribution === AppDistribution.ShopifyAdmin) {\n strategy = new MerchantCustomAuth(params);\n } else if (\n config.future.unstable_newEmbeddedAuthStrategy &&\n config.isEmbeddedApp\n ) {\n strategy = new TokenExchangeStrategy(params);\n } else {\n strategy = new AuthCodeFlowStrategy(params);\n }\n\n const authStrategy = authStrategyFactory<Config>({\n ...params,\n strategy,\n });\n\n const shopify:\n | AdminApp<Config>\n | AppStoreApp<Config>\n | SingleMerchantApp<Config> = {\n sessionStorage: config.sessionStorage,\n addDocumentResponseHeaders: addDocumentResponseHeadersFactory(params),\n registerWebhooks: registerWebhooksFactory(params),\n authenticate: {\n admin: authStrategy,\n flow: authenticateFlowFactory(params),\n public: authenticatePublicFactory(params),\n fulfillmentService: authenticateFulfillmentServiceFactory(params),\n webhook: authenticateWebhookFactory<string>(params),\n },\n unauthenticated: {\n admin: unauthenticatedAdminContextFactory(params),\n storefront: unauthenticatedStorefrontContextFactory(params),\n },\n };\n\n if (\n isAppStoreApp(shopify, appConfig) ||\n isSingleMerchantApp(shopify, appConfig)\n ) {\n shopify.login = loginFactory(params);\n }\n\n logDisabledFutureFlags(config, logger);\n\n return shopify as ShopifyApp<Config>;\n}\n\nfunction isAppStoreApp<Config extends AppConfigArg>(\n _shopify: ShopifyAppBase<Config>,\n config: Config,\n): _shopify is AppStoreApp<Config> {\n return config.distribution === AppDistribution.AppStore;\n}\n\nfunction isSingleMerchantApp<Config extends AppConfigArg>(\n _shopify: ShopifyAppBase<Config>,\n config: Config,\n): _shopify is SingleMerchantApp<Config> {\n return config.distribution === AppDistribution.SingleMerchant;\n}\n\n// This function is only exported so we can unit test it without having to mock the underlying module.\n// It's not available to consumers of the library because it is not exported in the index module, and never should be.\nexport function deriveApi(appConfig: AppConfigArg): BasicParams['api'] {\n let appUrl: URL;\n try {\n appUrl = new URL(appConfig.appUrl);\n } catch (error) {\n const message =\n appConfig.appUrl === ''\n ? `Detected an empty appUrl configuration, please make sure to set the necessary environment variables.\\n` +\n `If you're deploying your app, you can find more information at https://shopify.dev/docs/apps/launch/deployment/deploy-web-app/deploy-to-hosting-service#step-4-set-up-environment-variables`\n : `Invalid appUrl configuration '${appConfig.appUrl}', please provide a valid URL.`;\n throw new ShopifyError(message);\n }\n\n /* eslint-disable no-process-env */\n if (appUrl.hostname === 'localhost' && !appUrl.port && process.env.PORT) {\n appUrl.port = process.env.PORT;\n }\n /* eslint-enable no-process-env */\n appConfig.appUrl = appUrl.origin;\n\n let userAgentPrefix = `Shopify Remix Library v${SHOPIFY_REMIX_LIBRARY_VERSION}`;\n if (appConfig.userAgentPrefix) {\n userAgentPrefix = `${appConfig.userAgentPrefix} | ${userAgentPrefix}`;\n }\n\n return shopifyApi({\n ...appConfig,\n hostName: appUrl.host,\n hostScheme: appUrl.protocol.replace(':', '') as 'http' | 'https',\n userAgentPrefix,\n isEmbeddedApp: appConfig.isEmbeddedApp ?? true,\n apiVersion: appConfig.apiVersion,\n isCustomStoreApp: appConfig.distribution === AppDistribution.ShopifyAdmin,\n billing: appConfig.billing as ApiConfig['billing'],\n future: {\n unstable_managedPricingSupport: true,\n },\n _logDisabledFutureFlags: false,\n });\n}\n\nfunction deriveConfig<Storage extends SessionStorage>(\n appConfig: AppConfigArg,\n apiConfig: ApiConfig,\n): AppConfig<Storage> {\n if (\n !appConfig.sessionStorage &&\n appConfig.distribution !== AppDistribution.ShopifyAdmin\n ) {\n throw new ShopifyError(\n 'Please provide a valid session storage. Refer to https://github.com/Shopify/shopify-app-js/blob/main/README.md#session-storage-options for options.',\n );\n }\n\n const authPathPrefix = appConfig.authPathPrefix || '/auth';\n appConfig.distribution = appConfig.distribution ?? AppDistribution.AppStore;\n\n return {\n ...appConfig,\n ...apiConfig,\n billing: appConfig.billing as ApiConfig['billing'],\n scopes: apiConfig.scopes,\n idempotentPromiseHandler: new IdempotentPromiseHandler(),\n canUseLoginForm: appConfig.distribution !== AppDistribution.ShopifyAdmin,\n useOnlineTokens: appConfig.useOnlineTokens ?? false,\n hooks: appConfig.hooks ?? {},\n sessionStorage: appConfig.sessionStorage as Storage,\n future: appConfig.future ?? {},\n auth: {\n path: authPathPrefix,\n callbackPath: `${authPathPrefix}/callback`,\n patchSessionTokenPath: `${authPathPrefix}/session-token`,\n exitIframePath: `${authPathPrefix}/exit-iframe`,\n loginPath: `${authPathPrefix}/login`,\n },\n distribution: appConfig.distribution,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"test-config.mjs","sources":["../../../../../src/server/test-helpers/test-config.ts"],"sourcesContent":["import {LogSeverity, ShopifyRestResources} from '@shopify/shopify-api';\nimport {SessionStorage} from '@shopify/shopify-app-session-storage';\nimport {MemorySessionStorage} from '@shopify/shopify-app-session-storage-memory';\nimport {\n API_KEY,\n API_SECRET_KEY,\n APP_URL,\n} from '@shopify/shopify-api/test-helpers';\n\nimport type {AppConfigArg} from '../config-types';\nimport type {FutureFlagOptions} from '../future/flags';\n\nconst TEST_CONFIG = {\n apiKey: API_KEY,\n apiSecretKey: API_SECRET_KEY,\n scopes: ['testScope'] as any,\n appUrl: APP_URL,\n adminApiAccessToken: API_KEY,\n privateAppStorefrontAccessToken: API_KEY,\n logger: {\n level: LogSeverity.Debug,\n },\n sessionStorage: new MemorySessionStorage(),\n isTesting: true,\n} as const;\n\nexport function testConfig<\n Overrides extends TestOverridesArg,\n Future extends FutureFlagOptions,\n>(\n {future, ...overrides}: Overrides & {future?: Future} = {} as Overrides & {\n future?: Future;\n },\n): TestConfig<Overrides> {\n return {\n ...TEST_CONFIG,\n ...overrides,\n logger: {\n ...TEST_CONFIG.logger,\n ...(overrides as NonNullable<Overrides>).logger,\n },\n future,\n } as any;\n}\n\n/*\n * This type combines both passed in types, by ignoring any keys from Type1 that are present (and not undefined)\n * in Type2, and then adding any keys from Type1 that are not present in Type2.\n *\n * This effectively enables us to create a type that is the const TEST_CONFIG below, plus any overrides passed in with\n * the output being a const object.\n */\ntype Modify<Type1, Type2> = {\n [key in keyof Type2 as Type2[key] extends undefined\n ? never\n : key]: Type2[key];\n} & {\n [key in keyof Type1 as key extends keyof Type2 ? never : key]: Type1[key];\n};\n\n/*\n * We omit the future prop and then redefine it with a partial of that object so we can pass the fully typed object in\n * to AppConfigArg.\n */\ntype TestOverrides = Partial<\n Omit<\n AppConfigArg<ShopifyRestResources, SessionStorage, FutureFlagOptions>,\n 'future'\n > & {\n future: Partial<FutureFlagOptions>;\n }\n>;\n\nexport type TestOverridesArg = undefined | TestOverrides;\n\nexport type TestConfig<Overrides extends TestOverridesArg> = Modify<\n typeof TEST_CONFIG,\n Overrides\n> & {\n future: FutureFlagOptions;\n logger: AppConfigArg['logger'];\n};\n"],"names":[],"mappings":";;;;AAYA,MAAM,WAAW,GAAG;AAClB,IAAA,MAAM,EAAE,OAAO;AACf,IAAA,YAAY,EAAE,cAAc;IAC5B,MAAM,EAAE,CAAC,WAAW,CAAQ;AAC5B,IAAA,MAAM,EAAE,OAAO;AACf,IAAA,mBAAmB,EAAE,OAAO;AAC5B,IAAA,+BAA+B,EAAE,OAAO;AACxC,IAAA,MAAM,EAAE;QACN,KAAK,EAAE,WAAW,CAAC,KAAK;AACzB,KAAA;IACD,cAAc,EAAE,IAAI,oBAAoB,EAAE;AAC1C,IAAA,SAAS,EAAE,IAAI;CACP;AAEJ,SAAU,UAAU,CAIxB,EAAC,MAAM,EAAE,GAAG,SAAS,EAAA,GAAmC,EAEvD,EAAA;IAED,OAAO;AACL,QAAA,GAAG,WAAW;AACd,QAAA,GAAG,SAAS;AACZ,QAAA,MAAM,EAAE;YACN,GAAG,WAAW,CAAC,MAAM;YACrB,GAAI,SAAoC,CAAC,MAAM;AAChD,SAAA;QACD,MAAM;KACA;AACV;;;;"}
1
+ {"version":3,"file":"test-config.mjs","sources":["../../../../../src/server/test-helpers/test-config.ts"],"sourcesContent":["import {LogSeverity} from '@shopify/shopify-api';\nimport {SessionStorage} from '@shopify/shopify-app-session-storage';\nimport {MemorySessionStorage} from '@shopify/shopify-app-session-storage-memory';\nimport {\n API_KEY,\n API_SECRET_KEY,\n APP_URL,\n} from '@shopify/shopify-api/test-helpers';\n\nimport type {AppConfigArg} from '../config-types';\nimport type {FutureFlagOptions} from '../future/flags';\n\nconst TEST_CONFIG = {\n apiKey: API_KEY,\n apiSecretKey: API_SECRET_KEY,\n scopes: ['testScope'] as any,\n appUrl: APP_URL,\n adminApiAccessToken: API_KEY,\n privateAppStorefrontAccessToken: API_KEY,\n logger: {\n level: LogSeverity.Debug,\n },\n sessionStorage: new MemorySessionStorage(),\n isTesting: true,\n} as const;\n\nexport function testConfig<\n Overrides extends TestOverridesArg,\n Future extends FutureFlagOptions,\n>(\n {future, ...overrides}: Overrides & {future?: Future} = {} as Overrides & {\n future?: Future;\n },\n): TestConfig<Overrides> {\n return {\n ...TEST_CONFIG,\n ...overrides,\n logger: {\n ...TEST_CONFIG.logger,\n ...(overrides as NonNullable<Overrides>).logger,\n },\n future,\n } as any;\n}\n\n/*\n * This type combines both passed in types, by ignoring any keys from Type1 that are present (and not undefined)\n * in Type2, and then adding any keys from Type1 that are not present in Type2.\n *\n * This effectively enables us to create a type that is the const TEST_CONFIG below, plus any overrides passed in with\n * the output being a const object.\n */\ntype Modify<Type1, Type2> = {\n [key in keyof Type2 as Type2[key] extends undefined\n ? never\n : key]: Type2[key];\n} & {\n [key in keyof Type1 as key extends keyof Type2 ? never : key]: Type1[key];\n};\n\n/*\n * We omit the future prop and then redefine it with a partial of that object so we can pass the fully typed object in\n * to AppConfigArg.\n */\ntype TestOverrides = Partial<\n Omit<AppConfigArg<SessionStorage, FutureFlagOptions>, 'future'> & {\n future: Partial<FutureFlagOptions>;\n }\n>;\n\nexport type TestOverridesArg = undefined | TestOverrides;\n\nexport type TestConfig<Overrides extends TestOverridesArg> = Modify<\n typeof TEST_CONFIG,\n Overrides\n> & {\n future: FutureFlagOptions;\n logger: AppConfigArg['logger'];\n};\n"],"names":[],"mappings":";;;;AAYA,MAAM,WAAW,GAAG;AAClB,IAAA,MAAM,EAAE,OAAO;AACf,IAAA,YAAY,EAAE,cAAc;IAC5B,MAAM,EAAE,CAAC,WAAW,CAAQ;AAC5B,IAAA,MAAM,EAAE,OAAO;AACf,IAAA,mBAAmB,EAAE,OAAO;AAC5B,IAAA,+BAA+B,EAAE,OAAO;AACxC,IAAA,MAAM,EAAE;QACN,KAAK,EAAE,WAAW,CAAC,KAAK;AACzB,KAAA;IACD,cAAc,EAAE,IAAI,oBAAoB,EAAE;AAC1C,IAAA,SAAS,EAAE,IAAI;CACP;AAEJ,SAAU,UAAU,CAIxB,EAAC,MAAM,EAAE,GAAG,SAAS,EAAA,GAAmC,EAEvD,EAAA;IAED,OAAO;AACL,QAAA,GAAG,WAAW;AACd,QAAA,GAAG,SAAS;AACZ,QAAA,MAAM,EAAE;YACN,GAAG,WAAW,CAAC,MAAM;YACrB,GAAI,SAAoC,CAAC,MAAM;AAChD,SAAA;QACD,MAAM;KACA;AACV;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sources":["../../../../src/server/types.ts"],"sourcesContent":["import {\n RegisterReturn,\n Shopify,\n ShopifyRestResources,\n} from '@shopify/shopify-api';\nimport {SessionStorage} from '@shopify/shopify-app-session-storage';\n\nimport type {AuthenticateAdmin} from './authenticate/admin/types';\nimport type {AuthenticateFlow} from './authenticate/flow/types';\nimport {AuthenticateFulfillmentService} from './authenticate/fulfillment-service/types';\nimport type {AuthenticatePublic} from './authenticate/public/types';\nimport type {\n AuthenticateWebhook,\n RegisterWebhooksOptions,\n} from './authenticate/webhooks/types';\nimport type {AppConfig, AppConfigArg} from './config-types';\nimport type {\n ApiConfigWithFutureFlags,\n ApiFutureFlags,\n FutureFlagOptions,\n} from './future/flags';\nimport type {Unauthenticated} from './unauthenticated/types';\n\nexport interface BasicParams<\n Future extends FutureFlagOptions = FutureFlagOptions,\n> {\n api: Shopify<\n ApiConfigWithFutureFlags<Future>,\n ShopifyRestResources,\n ApiFutureFlags<Future>\n >;\n config: AppConfig;\n logger: Shopify['logger'];\n}\n\n// eslint-disable-next-line no-warning-comments\n// TODO: Use this enum to replace the isCustomStoreApp config option in shopify-api-js\nexport enum AppDistribution {\n AppStore = 'app_store',\n SingleMerchant = 'single_merchant',\n ShopifyAdmin = 'shopify_admin',\n}\n\ntype RegisterWebhooks = (\n options: RegisterWebhooksOptions,\n) => Promise<RegisterReturn | void>;\n\nexport enum LoginErrorType {\n MissingShop = 'MISSING_SHOP',\n InvalidShop = 'INVALID_SHOP',\n}\n\nexport interface LoginError {\n shop?: LoginErrorType;\n}\n\ntype Login = (request: Request) => Promise<LoginError | never>;\n\ntype AddDocumentResponseHeaders = (request: Request, headers: Headers) => void;\n\ntype RestResourcesType<Config extends AppConfigArg> =\n Config['restResources'] extends ShopifyRestResources\n ? Config['restResources']\n : ShopifyRestResources;\n\ntype SessionStorageType<Config extends AppConfigArg> =\n Config['sessionStorage'] extends SessionStorage\n ? Config['sessionStorage']\n : SessionStorage;\n\ninterface Authenticate<Config extends AppConfigArg> {\n /**\n * Authenticate an admin Request and get back an authenticated admin context. Use the authenticated admin context to interact with Shopify.\n *\n * Examples of when to use this are requests from your app's UI, or requests from admin extensions.\n *\n * If there is no session for the Request, this will redirect the merchant to correct auth flows.\n *\n * @example\n * <caption>Authenticating a request for an embedded app.</caption>\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticate } from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const {admin, session, sessionToken, billing} = authenticate.admin(request);\n * const response = await admin.graphql(`{ shop { name } }`)\n *\n * return json(await response.json());\n * }\n * ```\n * ```ts\n * // /app/shopify.server.ts\n * import { LATEST_API_VERSION, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * export const authenticate = shopify.authenticate;\n * ```\n */\n admin: AuthenticateAdmin<Config, RestResourcesType<Config>>;\n\n /**\n * Authenticate a Flow extension Request and get back an authenticated context, containing an admin context to access\n * the API, and the payload of the request.\n *\n * If there is no session for the Request, this will return an HTTP 400 error.\n *\n * Note that this will always be a POST request.\n *\n * @example\n * <caption>Authenticating a Flow extension request.</caption>\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { ActionFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticate } from \"../../shopify.server\";\n *\n * export async function action({ request }: ActionFunctionArgs) {\n * const {admin, session, payload} = authenticate.flow(request);\n *\n * // Perform flow extension logic\n *\n * // Return a 200 response\n * return null;\n * }\n * ```\n * ```ts\n * // /app/shopify.server.ts\n * import { LATEST_API_VERSION, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * export const authenticate = shopify.authenticate;\n * ```\n */\n flow: AuthenticateFlow<Config, RestResourcesType<Config>>;\n\n /**\n * Authenticate a request from a fulfillment service and get back an authenticated context.\n *\n * @example\n * <caption>Shopify session for the fulfillment service request.</caption>\n * <description>Use the session associated with this request to use the Admin GraphQL API </description>\n * ```ts\n * // /app/routes/fulfillment_order_notification.ts\n * import { ActionFunctionArgs } from \"@remix-run/node\";\n * import { authenticate } from \"../shopify.server\";\n *\n * export async function action({ request }: ActionFunctionArgs) {\n * const { admin, session } = await authenticate.fulfillmentService(request);\n *\n * console.log(session.id)\n *\n * return new Response();\n * }\n * ```\n * */\n fulfillmentService: AuthenticateFulfillmentService<\n Config,\n RestResourcesType<Config>\n >;\n\n /**\n * Authenticate a public request and get back a session token.\n *\n * @example\n * <caption>Authenticating a request from a checkout extension</caption>\n *\n * ```ts\n * // /app/routes/api/checkout.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticate } from \"../../shopify.server\";\n * import { getWidgets } from \"~/db/widgets\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const {sessionToken} = authenticate.public.checkout(request);\n *\n * return json(await getWidgets(sessionToken));\n * }\n * ```\n */\n public: AuthenticatePublic<Config>;\n\n /**\n * Authenticate a Shopify webhook request, get back an authenticated admin context and details on the webhook request\n * \n * @example\n * <caption>Authenticating a webhook request</caption>\n *\n * ```ts\n * // app/routes/webhooks.ts\n * import { ActionFunctionArgs } from \"@remix-run/node\";\n * import { authenticate } from \"../shopify.server\";\n * import db from \"../db.server\";\n *\n * export const action = async ({ request }: ActionFunctionArgs) => {\n * const { topic, shop, session, payload } = await authenticate.webhook(request);\n * \n * // Webhook requests can trigger after an app is uninstalled\n * // If the app is already uninstalled, the session may be undefined.\n * if (!session) {\n * throw new Response();\n * }\n * \n * // Handle the webhook\n * console.log(`${TOPIC} webhook received with payload:`, JSON.stringify(payload))\n *\n * throw new Response();\n * };\n * ```\n * \n * @example\n * <caption>Registering app-specific webhooks (Recommended)</caption>\n * ```toml\n * # shopify.app.toml\n * [webhooks]\n * api_version = \"2024-07\"\n\n * [[webhooks.subscriptions]]\n * topics = [\"products/create\"]\n * uri = \"/webhooks/products/create\"\n * \n * ```\n * \n * @example\n * <caption>Registering shop-specific webhooks.</caption>\n * <description>In many cases you won't need this. Please see: [https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions](https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions)\n * </description>\n * ```ts\n * // app/shopify.server.ts\n * import { DeliveryMethod, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * webhooks: {\n * PRODUCTS_CREATE: {\n * deliveryMethod: DeliveryMethod.Http,\n * callbackUrl: \"/webhooks/products/create\",\n * },\n * },\n * hooks: {\n * afterAuth: async ({ session }) => {\n * // Register webhooks for the shop\n * // In this example, every shop will have these webhooks\n * // You could wrap this in some custom shop specific conditional logic if needed\n * shopify.registerWebhooks({ session });\n * },\n * },\n * // ...etc\n * });\n * ```\n */\n webhook: AuthenticateWebhook<Config, RestResourcesType<Config>, string>;\n}\n\nexport interface ShopifyAppBase<Config extends AppConfigArg> {\n /**\n * The `SessionStorage` instance you passed in as a config option.\n *\n * @example\n * <caption>Storing sessions with Prisma.</caption>\n * <description>Import the `@shopify/shopify-app-session-storage-prisma` package to store sessions in your Prisma database.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { shopifyApp } from \"@shopify/shopify-app-remix/server\";\n * import { PrismaSessionStorage } from \"@shopify/shopify-app-session-storage-prisma\";\n * import prisma from \"~/db.server\";\n *\n * const shopify = shopifyApp({\n * sessionStorage: new PrismaSessionStorage(prisma),\n * // ...etc\n * })\n *\n * // shopify.sessionStorage is an instance of PrismaSessionStorage\n * ```\n */\n sessionStorage?: SessionStorageType<Config>;\n\n /**\n * Adds the required Content Security Policy headers for Shopify apps to the given Headers object.\n *\n * {@link https://shopify.dev/docs/apps/store/security/iframe-protection}\n *\n * @example\n * <caption>Return headers on all requests.</caption>\n * <description>Add headers to all HTML requests by calling `shopify.addDocumentResponseHeaders` in `entry.server.tsx`.</description>\n *\n * ```\n * // ~/shopify.server.ts\n * import { shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * export const addDocumentResponseheaders = shopify.addDocumentResponseheaders;\n * ```\n *\n * ```ts\n * // entry.server.tsx\n * import { addDocumentResponseHeaders } from \"~/shopify.server\";\n *\n * export default function handleRequest(\n * request: Request,\n * responseStatusCode: number,\n * responseHeaders: Headers,\n * remixContext: EntryContext\n * ) {\n * const markup = renderToString(\n * <RemixServer context={remixContext} url={request.url} />\n * );\n *\n * responseHeaders.set(\"Content-Type\", \"text/html\");\n * addDocumentResponseHeaders(request, responseHeaders);\n *\n * return new Response(\"<!DOCTYPE html>\" + markup, {\n * status: responseStatusCode,\n * headers: responseHeaders,\n * });\n * }\n * ```\n */\n addDocumentResponseHeaders: AddDocumentResponseHeaders;\n\n /**\n * Register shop-specific webhook subscriptions using the Admin GraphQL API.\n *\n * In many cases defining app-specific webhooks in the `shopify.app.toml` will be sufficient and easier to manage. Please see:\n *\n * {@link https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions}\n *\n * You should only use this if you need shop-specific webhooks.\n *\n * @example\n * <caption>Registering shop-specific webhooks after install</caption>\n * <description>Trigger the registration to create the shop-specific webhook subscriptions after a merchant installs your app using the `afterAuth` hook. Learn more about [subscribing to webhooks.](https://shopify.dev/docs/api/shopify-app-remix/v3/guide-webhooks)</description>\n * ```ts\n * // app/shopify.server.ts\n * import { DeliveryMethod, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * webhooks: {\n * PRODUCTS_CREATE: {\n * deliveryMethod: DeliveryMethod.Http,\n * callbackUrl: \"/webhooks/products/create\",\n * },\n * },\n * hooks: {\n * afterAuth: async ({ session }) => {\n * // Register webhooks for the shop\n * // In this example, every shop will have these webhooks\n * // You could wrap this in some custom shop specific conditional logic if needed\n * shopify.registerWebhooks({ session });\n * },\n * },\n * // ...etc\n * });\n * ```\n */\n registerWebhooks: RegisterWebhooks;\n\n /**\n * Ways to authenticate requests from different surfaces across Shopify.\n *\n * @example\n * <caption>Authenticate Shopify requests.</caption>\n * <description>Use the functions in `authenticate` to validate requests coming from Shopify.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { LATEST_API_VERSION, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * ```\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import shopify from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const {admin, session, sessionToken, billing} = shopify.authenticate.admin(request);\n * const response = admin.graphql(`{ shop { name } }`)\n *\n * return json(await response.json());\n * }\n * ```\n */\n authenticate: Authenticate<Config>;\n\n /**\n * Ways to get Contexts from requests that do not originate from Shopify.\n *\n * @example\n * <caption>Using unauthenticated contexts.</caption>\n * <description>Create contexts for requests that don't come from Shopify.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { LATEST_API_VERSION, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * ```\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticateExternal } from \"~/helpers/authenticate\"\n * import shopify from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const shop = await authenticateExternal(request)\n * const {admin} = await shopify.unauthenticated.admin(shop);\n * const response = admin.graphql(`{ shop { currencyCode } }`)\n *\n * return json(await response.json());\n * }\n * ```\n */\n unauthenticated: Unauthenticated<Config, RestResourcesType<Config>>;\n}\n\nexport interface ShopifyAppLogin {\n /**\n * Log a merchant in, and redirect them to the app root. Will redirect the merchant to authentication if a shop is\n * present in the URL search parameters or form data.\n *\n * This function won't be present when the `distribution` config option is set to `AppDistribution.ShopifyAdmin`,\n * because Admin apps aren't allowed to show a login page.\n *\n * @example\n * <caption>Creating a login page.</caption>\n * <description>Use `shopify.login` to create a login form, in a route that can handle GET and POST requests.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { LATEST_API_VERSION, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * ```\n * ```ts\n * // /app/routes/auth/login.tsx\n * import shopify from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const errors = shopify.login(request);\n *\n * return json(errors);\n * }\n *\n * export async function action({ request }: ActionFunctionArgs) {\n * const errors = shopify.login(request);\n *\n * return json(errors);\n * }\n *\n * export default function Auth() {\n * const actionData = useActionData<typeof action>();\n * const [shop, setShop] = useState(\"\");\n *\n * return (\n * <Page>\n * <Card>\n * <Form method=\"post\">\n * <FormLayout>\n * <Text variant=\"headingMd\" as=\"h2\">\n * Login\n * </Text>\n * <TextField\n * type=\"text\"\n * name=\"shop\"\n * label=\"Shop domain\"\n * helpText=\"e.g: my-shop-domain.myshopify.com\"\n * value={shop}\n * onChange={setShop}\n * autoComplete=\"on\"\n * error={actionData?.errors.shop}\n * />\n * <Button submit primary>\n * Submit\n * </Button>\n * </FormLayout>\n * </Form>\n * </Card>\n * </Page>\n * );\n * }\n * ```\n */\n login: Login;\n}\n\nexport type AdminApp<Config extends AppConfigArg> = ShopifyAppBase<Config>;\nexport type SingleMerchantApp<Config extends AppConfigArg> =\n ShopifyAppBase<Config> & ShopifyAppLogin;\nexport type AppStoreApp<Config extends AppConfigArg> = ShopifyAppBase<Config> &\n ShopifyAppLogin;\n\ntype EnforceSessionStorage<Config extends AppConfigArg, Base> = Base & {\n sessionStorage: SessionStorageType<Config>;\n};\n\n/**\n * An object your app can use to interact with Shopify.\n *\n * By default, the app's distribution is `AppStore`.\n */\nexport type ShopifyApp<Config extends AppConfigArg> =\n Config['distribution'] extends AppDistribution.ShopifyAdmin\n ? AdminApp<Config>\n : Config['distribution'] extends AppDistribution.SingleMerchant\n ? EnforceSessionStorage<Config, SingleMerchantApp<Config>>\n : Config['distribution'] extends AppDistribution.AppStore\n ? EnforceSessionStorage<Config, AppStoreApp<Config>>\n : EnforceSessionStorage<Config, AppStoreApp<Config>>;\n"],"names":[],"mappings":"AAmCA;AACA;IACY;AAAZ,CAAA,UAAY,eAAe,EAAA;AACzB,IAAA,eAAA,CAAA,UAAA,CAAA,GAAA,WAAsB;AACtB,IAAA,eAAA,CAAA,gBAAA,CAAA,GAAA,iBAAkC;AAClC,IAAA,eAAA,CAAA,cAAA,CAAA,GAAA,eAA8B;AAChC,CAAC,EAJW,eAAe,KAAf,eAAe,GAAA,EAAA,CAAA,CAAA;IAUf;AAAZ,CAAA,UAAY,cAAc,EAAA;AACxB,IAAA,cAAA,CAAA,aAAA,CAAA,GAAA,cAA4B;AAC5B,IAAA,cAAA,CAAA,aAAA,CAAA,GAAA,cAA4B;AAC9B,CAAC,EAHW,cAAc,KAAd,cAAc,GAAA,EAAA,CAAA,CAAA;;;;"}
1
+ {"version":3,"file":"types.mjs","sources":["../../../../src/server/types.ts"],"sourcesContent":["import {RegisterReturn, Shopify} from '@shopify/shopify-api';\nimport {SessionStorage} from '@shopify/shopify-app-session-storage';\n\nimport type {AuthenticateAdmin} from './authenticate/admin/types';\nimport type {AuthenticateFlow} from './authenticate/flow/types';\nimport {AuthenticateFulfillmentService} from './authenticate/fulfillment-service/types';\nimport type {AuthenticatePublic} from './authenticate/public/types';\nimport type {\n AuthenticateWebhook,\n RegisterWebhooksOptions,\n} from './authenticate/webhooks/types';\nimport type {AppConfig, AppConfigArg} from './config-types';\nimport type {\n ApiConfigWithFutureFlags,\n ApiFutureFlags,\n FutureFlagOptions,\n} from './future/flags';\nimport type {Unauthenticated} from './unauthenticated/types';\n\nexport interface BasicParams<\n Future extends FutureFlagOptions = FutureFlagOptions,\n> {\n api: Shopify<ApiConfigWithFutureFlags<Future>, ApiFutureFlags<Future>>;\n config: AppConfig;\n logger: Shopify['logger'];\n}\n\n// eslint-disable-next-line no-warning-comments\n// TODO: Use this enum to replace the isCustomStoreApp config option in shopify-api-js\nexport enum AppDistribution {\n AppStore = 'app_store',\n SingleMerchant = 'single_merchant',\n ShopifyAdmin = 'shopify_admin',\n}\n\ntype RegisterWebhooks = (\n options: RegisterWebhooksOptions,\n) => Promise<RegisterReturn | void>;\n\nexport enum LoginErrorType {\n MissingShop = 'MISSING_SHOP',\n InvalidShop = 'INVALID_SHOP',\n}\n\nexport interface LoginError {\n shop?: LoginErrorType;\n}\n\ntype Login = (request: Request) => Promise<LoginError | never>;\n\ntype AddDocumentResponseHeaders = (request: Request, headers: Headers) => void;\n\ntype SessionStorageType<Config extends AppConfigArg> =\n Config['sessionStorage'] extends SessionStorage\n ? Config['sessionStorage']\n : SessionStorage;\n\ninterface Authenticate<Config extends AppConfigArg> {\n /**\n * Authenticate an admin Request and get back an authenticated admin context. Use the authenticated admin context to interact with Shopify.\n *\n * Examples of when to use this are requests from your app's UI, or requests from admin extensions.\n *\n * If there is no session for the Request, this will redirect the merchant to correct auth flows.\n *\n * @example\n * <caption>Authenticating a request for an embedded app.</caption>\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticate } from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const {admin, session, sessionToken, billing} = authenticate.admin(request);\n * const response = await admin.graphql(`{ shop { name } }`)\n *\n * return json(await response.json());\n * }\n * ```\n * ```ts\n * // /app/shopify.server.ts\n * import { ApiVersion, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * export const authenticate = shopify.authenticate;\n * ```\n */\n admin: AuthenticateAdmin<Config>;\n\n /**\n * Authenticate a Flow extension Request and get back an authenticated context, containing an admin context to access\n * the API, and the payload of the request.\n *\n * If there is no session for the Request, this will return an HTTP 400 error.\n *\n * Note that this will always be a POST request.\n *\n * @example\n * <caption>Authenticating a Flow extension request.</caption>\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { ActionFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticate } from \"../../shopify.server\";\n *\n * export async function action({ request }: ActionFunctionArgs) {\n * const {admin, session, payload} = authenticate.flow(request);\n *\n * // Perform flow extension logic\n *\n * // Return a 200 response\n * return null;\n * }\n * ```\n * ```ts\n * // /app/shopify.server.ts\n * import { ApiVersion, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * export const authenticate = shopify.authenticate;\n * ```\n */\n flow: AuthenticateFlow;\n\n /**\n * Authenticate a request from a fulfillment service and get back an authenticated context.\n *\n * @example\n * <caption>Shopify session for the fulfillment service request.</caption>\n * <description>Use the session associated with this request to use the Admin GraphQL API </description>\n * ```ts\n * // /app/routes/fulfillment_order_notification.ts\n * import { ActionFunctionArgs } from \"@remix-run/node\";\n * import { authenticate } from \"../shopify.server\";\n *\n * export async function action({ request }: ActionFunctionArgs) {\n * const { admin, session } = await authenticate.fulfillmentService(request);\n *\n * console.log(session.id)\n *\n * return new Response();\n * }\n * ```\n * */\n fulfillmentService: AuthenticateFulfillmentService;\n\n /**\n * Authenticate a public request and get back a session token.\n *\n * @example\n * <caption>Authenticating a request from a checkout extension</caption>\n *\n * ```ts\n * // /app/routes/api/checkout.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticate } from \"../../shopify.server\";\n * import { getWidgets } from \"~/db/widgets\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const {sessionToken} = authenticate.public.checkout(request);\n *\n * return json(await getWidgets(sessionToken));\n * }\n * ```\n */\n public: AuthenticatePublic;\n\n /**\n * Authenticate a Shopify webhook request, get back an authenticated admin context and details on the webhook request\n * \n * @example\n * <caption>Authenticating a webhook request</caption>\n *\n * ```ts\n * // app/routes/webhooks.ts\n * import { ActionFunctionArgs } from \"@remix-run/node\";\n * import { authenticate } from \"../shopify.server\";\n * import db from \"../db.server\";\n *\n * export const action = async ({ request }: ActionFunctionArgs) => {\n * const { topic, shop, session, payload } = await authenticate.webhook(request);\n * \n * // Webhook requests can trigger after an app is uninstalled\n * // If the app is already uninstalled, the session may be undefined.\n * if (!session) {\n * throw new Response();\n * }\n * \n * // Handle the webhook\n * console.log(`${TOPIC} webhook received with payload:`, JSON.stringify(payload))\n *\n * throw new Response();\n * };\n * ```\n * \n * @example\n * <caption>Registering app-specific webhooks (Recommended)</caption>\n * ```toml\n * # shopify.app.toml\n * [webhooks]\n * api_version = \"2024-07\"\n\n * [[webhooks.subscriptions]]\n * topics = [\"products/create\"]\n * uri = \"/webhooks/products/create\"\n * \n * ```\n * \n * @example\n * <caption>Registering shop-specific webhooks.</caption>\n * <description>In many cases you won't need this. Please see: [https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions](https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions)\n * </description>\n * ```ts\n * // app/shopify.server.ts\n * import { DeliveryMethod, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * webhooks: {\n * PRODUCTS_CREATE: {\n * deliveryMethod: DeliveryMethod.Http,\n * callbackUrl: \"/webhooks/products/create\",\n * },\n * },\n * hooks: {\n * afterAuth: async ({ session }) => {\n * // Register webhooks for the shop\n * // In this example, every shop will have these webhooks\n * // You could wrap this in some custom shop specific conditional logic if needed\n * shopify.registerWebhooks({ session });\n * },\n * },\n * // ...etc\n * });\n * ```\n */\n webhook: AuthenticateWebhook<string>;\n}\n\nexport interface ShopifyAppBase<Config extends AppConfigArg> {\n /**\n * The `SessionStorage` instance you passed in as a config option.\n *\n * @example\n * <caption>Storing sessions with Prisma.</caption>\n * <description>Import the `@shopify/shopify-app-session-storage-prisma` package to store sessions in your Prisma database.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { shopifyApp } from \"@shopify/shopify-app-remix/server\";\n * import { PrismaSessionStorage } from \"@shopify/shopify-app-session-storage-prisma\";\n * import prisma from \"~/db.server\";\n *\n * const shopify = shopifyApp({\n * sessionStorage: new PrismaSessionStorage(prisma),\n * // ...etc\n * })\n *\n * // shopify.sessionStorage is an instance of PrismaSessionStorage\n * ```\n */\n sessionStorage?: SessionStorageType<Config>;\n\n /**\n * Adds the required Content Security Policy headers for Shopify apps to the given Headers object.\n *\n * {@link https://shopify.dev/docs/apps/store/security/iframe-protection}\n *\n * @example\n * <caption>Return headers on all requests.</caption>\n * <description>Add headers to all HTML requests by calling `shopify.addDocumentResponseHeaders` in `entry.server.tsx`.</description>\n *\n * ```\n * // ~/shopify.server.ts\n * import { shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * export const addDocumentResponseheaders = shopify.addDocumentResponseheaders;\n * ```\n *\n * ```ts\n * // entry.server.tsx\n * import { addDocumentResponseHeaders } from \"~/shopify.server\";\n *\n * export default function handleRequest(\n * request: Request,\n * responseStatusCode: number,\n * responseHeaders: Headers,\n * remixContext: EntryContext\n * ) {\n * const markup = renderToString(\n * <RemixServer context={remixContext} url={request.url} />\n * );\n *\n * responseHeaders.set(\"Content-Type\", \"text/html\");\n * addDocumentResponseHeaders(request, responseHeaders);\n *\n * return new Response(\"<!DOCTYPE html>\" + markup, {\n * status: responseStatusCode,\n * headers: responseHeaders,\n * });\n * }\n * ```\n */\n addDocumentResponseHeaders: AddDocumentResponseHeaders;\n\n /**\n * Register shop-specific webhook subscriptions using the Admin GraphQL API.\n *\n * In many cases defining app-specific webhooks in the `shopify.app.toml` will be sufficient and easier to manage. Please see:\n *\n * {@link https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions}\n *\n * You should only use this if you need shop-specific webhooks.\n *\n * @example\n * <caption>Registering shop-specific webhooks after install</caption>\n * <description>Trigger the registration to create the shop-specific webhook subscriptions after a merchant installs your app using the `afterAuth` hook. Learn more about [subscribing to webhooks.](https://shopify.dev/docs/api/shopify-app-remix/v3/guide-webhooks)</description>\n * ```ts\n * // app/shopify.server.ts\n * import { DeliveryMethod, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * webhooks: {\n * PRODUCTS_CREATE: {\n * deliveryMethod: DeliveryMethod.Http,\n * callbackUrl: \"/webhooks/products/create\",\n * },\n * },\n * hooks: {\n * afterAuth: async ({ session }) => {\n * // Register webhooks for the shop\n * // In this example, every shop will have these webhooks\n * // You could wrap this in some custom shop specific conditional logic if needed\n * shopify.registerWebhooks({ session });\n * },\n * },\n * // ...etc\n * });\n * ```\n */\n registerWebhooks: RegisterWebhooks;\n\n /**\n * Ways to authenticate requests from different surfaces across Shopify.\n *\n * @example\n * <caption>Authenticate Shopify requests.</caption>\n * <description>Use the functions in `authenticate` to validate requests coming from Shopify.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { ApiVersion, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * ```\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import shopify from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const {admin, session, sessionToken, billing} = shopify.authenticate.admin(request);\n * const response = admin.graphql(`{ shop { name } }`)\n *\n * return json(await response.json());\n * }\n * ```\n */\n authenticate: Authenticate<Config>;\n\n /**\n * Ways to get Contexts from requests that do not originate from Shopify.\n *\n * @example\n * <caption>Using unauthenticated contexts.</caption>\n * <description>Create contexts for requests that don't come from Shopify.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { ApiVersion, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * ```\n * ```ts\n * // /app/routes/**\\/*.jsx\n * import { LoaderFunctionArgs, json } from \"@remix-run/node\";\n * import { authenticateExternal } from \"~/helpers/authenticate\"\n * import shopify from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const shop = await authenticateExternal(request)\n * const {admin} = await shopify.unauthenticated.admin(shop);\n * const response = admin.graphql(`{ shop { currencyCode } }`)\n *\n * return json(await response.json());\n * }\n * ```\n */\n unauthenticated: Unauthenticated;\n}\n\nexport interface ShopifyAppLogin {\n /**\n * Log a merchant in, and redirect them to the app root. Will redirect the merchant to authentication if a shop is\n * present in the URL search parameters or form data.\n *\n * This function won't be present when the `distribution` config option is set to `AppDistribution.ShopifyAdmin`,\n * because Admin apps aren't allowed to show a login page.\n *\n * @example\n * <caption>Creating a login page.</caption>\n * <description>Use `shopify.login` to create a login form, in a route that can handle GET and POST requests.</description>\n * ```ts\n * // /app/shopify.server.ts\n * import { ApiVersion, shopifyApp } from \"@shopify/shopify-app-remix/server\";\n *\n * const shopify = shopifyApp({\n * // ...etc\n * });\n * export default shopify;\n * ```\n * ```ts\n * // /app/routes/auth/login.tsx\n * import shopify from \"../../shopify.server\";\n *\n * export async function loader({ request }: LoaderFunctionArgs) {\n * const errors = shopify.login(request);\n *\n * return json(errors);\n * }\n *\n * export async function action({ request }: ActionFunctionArgs) {\n * const errors = shopify.login(request);\n *\n * return json(errors);\n * }\n *\n * export default function Auth() {\n * const actionData = useActionData<typeof action>();\n * const [shop, setShop] = useState(\"\");\n *\n * return (\n * <Page>\n * <Card>\n * <Form method=\"post\">\n * <FormLayout>\n * <Text variant=\"headingMd\" as=\"h2\">\n * Login\n * </Text>\n * <TextField\n * type=\"text\"\n * name=\"shop\"\n * label=\"Shop domain\"\n * helpText=\"e.g: my-shop-domain.myshopify.com\"\n * value={shop}\n * onChange={setShop}\n * autoComplete=\"on\"\n * error={actionData?.errors.shop}\n * />\n * <Button submit primary>\n * Submit\n * </Button>\n * </FormLayout>\n * </Form>\n * </Card>\n * </Page>\n * );\n * }\n * ```\n */\n login: Login;\n}\n\nexport type AdminApp<Config extends AppConfigArg> = ShopifyAppBase<Config>;\nexport type SingleMerchantApp<Config extends AppConfigArg> =\n ShopifyAppBase<Config> & ShopifyAppLogin;\nexport type AppStoreApp<Config extends AppConfigArg> = ShopifyAppBase<Config> &\n ShopifyAppLogin;\n\ntype EnforceSessionStorage<Config extends AppConfigArg, Base> = Base & {\n sessionStorage: SessionStorageType<Config>;\n};\n\n/**\n * An object your app can use to interact with Shopify.\n *\n * By default, the app's distribution is `AppStore`.\n */\nexport type ShopifyApp<Config extends AppConfigArg> =\n Config['distribution'] extends AppDistribution.ShopifyAdmin\n ? AdminApp<Config>\n : Config['distribution'] extends AppDistribution.SingleMerchant\n ? EnforceSessionStorage<Config, SingleMerchantApp<Config>>\n : Config['distribution'] extends AppDistribution.AppStore\n ? EnforceSessionStorage<Config, AppStoreApp<Config>>\n : EnforceSessionStorage<Config, AppStoreApp<Config>>;\n"],"names":[],"mappings":"AA2BA;AACA;IACY;AAAZ,CAAA,UAAY,eAAe,EAAA;AACzB,IAAA,eAAA,CAAA,UAAA,CAAA,GAAA,WAAsB;AACtB,IAAA,eAAA,CAAA,gBAAA,CAAA,GAAA,iBAAkC;AAClC,IAAA,eAAA,CAAA,cAAA,CAAA,GAAA,eAA8B;AAChC,CAAC,EAJW,eAAe,KAAf,eAAe,GAAA,EAAA,CAAA,CAAA;IAUf;AAAZ,CAAA,UAAY,cAAc,EAAA;AACxB,IAAA,cAAA,CAAA,aAAA,CAAA,GAAA,cAA4B;AAC5B,IAAA,cAAA,CAAA,aAAA,CAAA,GAAA,cAA4B;AAC9B,CAAC,EAHW,cAAc,KAAd,cAAc,GAAA,EAAA,CAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"factory.mjs","sources":["../../../../../../src/server/unauthenticated/admin/factory.ts"],"sourcesContent":["import {ShopifyRestResources} from '@shopify/shopify-api';\n\nimport {AppConfigArg} from '../../config-types';\nimport {createOrLoadOfflineSession} from '../../authenticate/helpers/create-or-load-offline-session';\nimport {SessionNotFoundError} from '../../errors';\nimport {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients/admin';\n\nimport {UnauthenticatedAdminContext} from './types';\n\nexport function unauthenticatedAdminContextFactory<\n ConfigArg extends AppConfigArg,\n Resources extends ShopifyRestResources,\n>(params: BasicParams) {\n return async (\n shop: string,\n ): Promise<UnauthenticatedAdminContext<ConfigArg, Resources>> => {\n const session = await createOrLoadOfflineSession(shop, params);\n\n if (!session) {\n throw new SessionNotFoundError(\n `Could not find a session for shop ${shop} when creating unauthenticated admin context`,\n );\n }\n\n return {\n session,\n admin: adminClientFactory<ConfigArg, Resources>({params, session}),\n };\n };\n}\n"],"names":[],"mappings":";;;;AAUM,SAAU,kCAAkC,CAGhD,MAAmB,EAAA;AACnB,IAAA,OAAO,OACL,IAAY,KACkD;QAC9D,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC;QAE9D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,IAAI,oBAAoB,CAC5B,qCAAqC,IAAI,CAAA,4CAAA,CAA8C,CACxF;QACH;QAEA,OAAO;YACL,OAAO;YACP,KAAK,EAAE,kBAAkB,CAAuB,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SACnE;AACH,IAAA,CAAC;AACH;;;;"}
1
+ {"version":3,"file":"factory.mjs","sources":["../../../../../../src/server/unauthenticated/admin/factory.ts"],"sourcesContent":["import {createOrLoadOfflineSession} from '../../authenticate/helpers/create-or-load-offline-session';\nimport {SessionNotFoundError} from '../../errors';\nimport {BasicParams} from '../../types';\nimport {adminClientFactory} from '../../clients/admin';\n\nimport {UnauthenticatedAdminContext} from './types';\n\nexport function unauthenticatedAdminContextFactory(params: BasicParams) {\n return async (shop: string): Promise<UnauthenticatedAdminContext> => {\n const session = await createOrLoadOfflineSession(shop, params);\n\n if (!session) {\n throw new SessionNotFoundError(\n `Could not find a session for shop ${shop} when creating unauthenticated admin context`,\n );\n }\n\n return {\n session,\n admin: adminClientFactory({params, session}),\n };\n };\n}\n"],"names":[],"mappings":";;;;AAOM,SAAU,kCAAkC,CAAC,MAAmB,EAAA;AACpE,IAAA,OAAO,OAAO,IAAY,KAA0C;QAClE,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC,IAAI,EAAE,MAAM,CAAC;QAE9D,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,MAAM,IAAI,oBAAoB,CAC5B,qCAAqC,IAAI,CAAA,4CAAA,CAA8C,CACxF;QACH;QAEA,OAAO;YACL,OAAO;YACP,KAAK,EAAE,kBAAkB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;SAC7C;AACH,IAAA,CAAC;AACH;;;;"}
@@ -1,4 +1,4 @@
1
- const SHOPIFY_REMIX_LIBRARY_VERSION = '3.8.4';
1
+ const SHOPIFY_REMIX_LIBRARY_VERSION = '4.0.0';
2
2
 
3
3
  export { SHOPIFY_REMIX_LIBRARY_VERSION };
4
4
  //# sourceMappingURL=version.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.mjs","sources":["../../../../src/server/version.ts"],"sourcesContent":["export const SHOPIFY_REMIX_LIBRARY_VERSION = '3.8.4';\n"],"names":[],"mappings":"AAAO,MAAM,6BAA6B,GAAG;;;;"}
1
+ {"version":3,"file":"version.mjs","sources":["../../../../src/server/version.ts"],"sourcesContent":["export const SHOPIFY_REMIX_LIBRARY_VERSION = '4.0.0';\n"],"names":[],"mappings":"AAAO,MAAM,6BAA6B,GAAG;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"authenticate.admin.doc.d.ts","sourceRoot":"","sources":["../../../../../src/server/authenticate/admin/authenticate.admin.doc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,6BAA6B,EAAC,MAAM,wBAAwB,CAAC;AAErE,QAAA,MAAM,IAAI,EAAE,6BA+CX,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"authenticate.admin.doc.d.ts","sourceRoot":"","sources":["../../../../../src/server/authenticate/admin/authenticate.admin.doc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,6BAA6B,EAAC,MAAM,wBAAwB,CAAC;AAErE,QAAA,MAAM,IAAI,EAAE,6BA8CX,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,4 +1,4 @@
1
- import { JwtPayload, ShopifyRestResources } from '@shopify/shopify-api';
1
+ import { JwtPayload } from '@shopify/shopify-api';
2
2
  import type { BasicParams } from '../../types';
3
3
  import type { AppConfigArg } from '../../config-types';
4
4
  import type { AuthenticateAdmin } from './types';
@@ -12,6 +12,6 @@ export interface SessionTokenContext {
12
12
  interface AuthStrategyParams extends BasicParams {
13
13
  strategy: AuthorizationStrategy;
14
14
  }
15
- export declare function authStrategyFactory<ConfigArg extends AppConfigArg, Resources extends ShopifyRestResources = ShopifyRestResources>({ strategy, ...params }: AuthStrategyParams): AuthenticateAdmin<ConfigArg, Resources>;
15
+ export declare function authStrategyFactory<ConfigArg extends AppConfigArg>({ strategy, ...params }: AuthStrategyParams): AuthenticateAdmin<ConfigArg>;
16
16
  export {};
17
17
  //# sourceMappingURL=authenticate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../../../../src/server/authenticate/admin/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAW,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AAE/E,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAmBrD,OAAO,KAAK,EAEV,iBAAiB,EAGlB,MAAM,SAAS,CAAC;AASjB,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,UAAU,kBAAmB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED,wBAAgB,mBAAmB,CACjC,SAAS,SAAS,YAAY,EAC9B,SAAS,SAAS,oBAAoB,GAAG,oBAAoB,EAC7D,EACA,QAAQ,EACR,GAAG,MAAM,EACV,EAAE,kBAAkB,GAAG,iBAAiB,CAAC,SAAS,EAAE,SAAS,CAAC,CAwI9D"}
1
+ {"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../../../../src/server/authenticate/admin/authenticate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAU,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAmBrD,OAAO,KAAK,EAEV,iBAAiB,EAGlB,MAAM,SAAS,CAAC;AASjB,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,UAAU,kBAAmB,SAAQ,WAAW;IAC9C,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,SAAS,YAAY,EAAE,EAClE,QAAQ,EACR,GAAG,MAAM,EACV,EAAE,kBAAkB,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAwInD"}