shopify-app-js 0.0.1-security → 1.0.1

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.

Potentially problematic release.


This version of shopify-app-js might be problematic. Click here for more details.

Files changed (424) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +14 -0
  3. package/.changeset/flat-clouds-camp.md +5 -0
  4. package/.eslintrc.js +36 -0
  5. package/.github/CODEOWNERS +1 -0
  6. package/.github/ISSUE_TEMPLATE/BUG_REPORT.md +36 -0
  7. package/.github/ISSUE_TEMPLATE/ENHANCEMENT.md +9 -0
  8. package/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +9 -0
  9. package/.github/PULL_REQUEST_TEMPLATE.md +34 -0
  10. package/.github/dependabot.yml +9 -0
  11. package/.github/workflows/changelog.yml +30 -0
  12. package/.github/workflows/ci.yml +22 -0
  13. package/.github/workflows/cla.yml +22 -0
  14. package/.github/workflows/close-waiting-for-response-issues.yml +20 -0
  15. package/.github/workflows/main-release.yml +36 -0
  16. package/.github/workflows/markdown_link_check.yml +14 -0
  17. package/.github/workflows/markdown_link_checker_config.json +9 -0
  18. package/.github/workflows/publish-experimental-build.yml +30 -0
  19. package/.github/workflows/release-candidate.yml +35 -0
  20. package/.github/workflows/remove-labels-on-activity.yml +16 -0
  21. package/.github/workflows/stale.yml +26 -0
  22. package/.prettierignore +5 -0
  23. package/.prettierrc +1 -0
  24. package/CODE_OF_CONDUCT.md +46 -0
  25. package/CONTRIBUTING.md +39 -0
  26. package/LICENSE.md +9 -0
  27. package/README.md +62 -3
  28. package/RELEASING.md +142 -0
  29. package/loom.config.ts +115 -0
  30. package/package.json +44 -3
  31. package/packages/.prettierrc +1 -0
  32. package/packages/shopify-app-express/CHANGELOG.md +316 -0
  33. package/packages/shopify-app-express/LICENSE.md +9 -0
  34. package/packages/shopify-app-express/README.md +93 -0
  35. package/packages/shopify-app-express/docs/reference/README.md +3 -0
  36. package/packages/shopify-app-express/docs/reference/auth.md +76 -0
  37. package/packages/shopify-app-express/docs/reference/cspHeaders.md +24 -0
  38. package/packages/shopify-app-express/docs/reference/ensureInstalledOnShop.md +17 -0
  39. package/packages/shopify-app-express/docs/reference/migrating-app-v6-api-lib-to-express-lib.md +345 -0
  40. package/packages/shopify-app-express/docs/reference/processWebhooks.md +67 -0
  41. package/packages/shopify-app-express/docs/reference/redirectOutOfApp.md +77 -0
  42. package/packages/shopify-app-express/docs/reference/redirectToShopifyOrAppRoot.md +20 -0
  43. package/packages/shopify-app-express/docs/reference/shopifyApp.md +148 -0
  44. package/packages/shopify-app-express/docs/reference/validateAuthenticatedSession.md +30 -0
  45. package/packages/shopify-app-express/loom.config.ts +27 -0
  46. package/packages/shopify-app-express/package.json +54 -0
  47. package/packages/shopify-app-express/src/__tests__/index.test.ts +100 -0
  48. package/packages/shopify-app-express/src/__tests__/integration/oauth.test.ts +445 -0
  49. package/packages/shopify-app-express/src/__tests__/integration/responses.ts +135 -0
  50. package/packages/shopify-app-express/src/__tests__/integration/types.ts +22 -0
  51. package/packages/shopify-app-express/src/__tests__/integration/utils.ts +68 -0
  52. package/packages/shopify-app-express/src/__tests__/integration/webhooks.test.ts +208 -0
  53. package/packages/shopify-app-express/src/__tests__/redirect-to-auth.test.ts +103 -0
  54. package/packages/shopify-app-express/src/__tests__/setup-jest.ts +8 -0
  55. package/packages/shopify-app-express/src/__tests__/test-helper.ts +204 -0
  56. package/packages/shopify-app-express/src/app-installations.ts +42 -0
  57. package/packages/shopify-app-express/src/auth/__tests__/auth.test.ts +303 -0
  58. package/packages/shopify-app-express/src/auth/auth-callback.ts +131 -0
  59. package/packages/shopify-app-express/src/auth/index.ts +32 -0
  60. package/packages/shopify-app-express/src/auth/types.ts +13 -0
  61. package/packages/shopify-app-express/src/config-types.ts +38 -0
  62. package/packages/shopify-app-express/src/error.ts +8 -0
  63. package/packages/shopify-app-express/src/index.ts +171 -0
  64. package/packages/shopify-app-express/src/middlewares/__tests__/csp-headers.test.ts +69 -0
  65. package/packages/shopify-app-express/src/middlewares/__tests__/ensure-installed-on-shop.test.ts +193 -0
  66. package/packages/shopify-app-express/src/middlewares/__tests__/redirect-to-shopify-or-app-root.test.ts +59 -0
  67. package/packages/shopify-app-express/src/middlewares/__tests__/validate-authenticated-session.test.ts +319 -0
  68. package/packages/shopify-app-express/src/middlewares/csp-headers.ts +31 -0
  69. package/packages/shopify-app-express/src/middlewares/ensure-installed-on-shop.ts +176 -0
  70. package/packages/shopify-app-express/src/middlewares/has-valid-access-token.ts +25 -0
  71. package/packages/shopify-app-express/src/middlewares/index.ts +15 -0
  72. package/packages/shopify-app-express/src/middlewares/redirect-to-shopify-or-app-root.ts +39 -0
  73. package/packages/shopify-app-express/src/middlewares/types.ts +6 -0
  74. package/packages/shopify-app-express/src/middlewares/validate-authenticated-session.ts +142 -0
  75. package/packages/shopify-app-express/src/redirect-out-of-app.ts +80 -0
  76. package/packages/shopify-app-express/src/redirect-to-auth.ts +70 -0
  77. package/packages/shopify-app-express/src/types.ts +26 -0
  78. package/packages/shopify-app-express/src/version.ts +1 -0
  79. package/packages/shopify-app-express/src/webhooks/__tests__/process.test.ts +138 -0
  80. package/packages/shopify-app-express/src/webhooks/index.ts +54 -0
  81. package/packages/shopify-app-express/src/webhooks/process.ts +22 -0
  82. package/packages/shopify-app-express/src/webhooks/types.ts +24 -0
  83. package/packages/shopify-app-express/tsconfig.json +10 -0
  84. package/packages/shopify-app-remix/.eslintrc.js +3 -0
  85. package/packages/shopify-app-remix/CHANGELOG.md +569 -0
  86. package/packages/shopify-app-remix/LICENSE.md +9 -0
  87. package/packages/shopify-app-remix/README.md +223 -0
  88. package/packages/shopify-app-remix/docs/build-docs.sh +11 -0
  89. package/packages/shopify-app-remix/docs/generated/generated_docs_data.json +18650 -0
  90. package/packages/shopify-app-remix/docs/generated/generated_static_pages.json +540 -0
  91. package/packages/shopify-app-remix/docs/staticPages/admin.doc.ts +130 -0
  92. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/auth-cors.example.tsx +11 -0
  93. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/auth.example.tsx +19 -0
  94. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/graphql.example.tsx +29 -0
  95. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/headers.example.tsx +10 -0
  96. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/rest-resources.example.tsx +9 -0
  97. package/packages/shopify-app-remix/docs/staticPages/examples/guides/admin/rest.example.tsx +17 -0
  98. package/packages/shopify-app-remix/docs/staticPages/examples/guides/future-flags/config.example.ts +8 -0
  99. package/packages/shopify-app-remix/docs/staticPages/examples/guides/future-flags/unstable.example.ts +9 -0
  100. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/.graphqlrc.ts +16 -0
  101. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/install.npm.example.sh +2 -0
  102. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/install.pnpm.example.sh +2 -0
  103. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/install.yarn.example.sh +2 -0
  104. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/package.json +5 -0
  105. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/run.npm.example.sh +1 -0
  106. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/run.pnpm.example.sh +1 -0
  107. package/packages/shopify-app-remix/docs/staticPages/examples/guides/graphql-types/run.yarn.example.sh +1 -0
  108. package/packages/shopify-app-remix/docs/staticPages/examples/guides/webhooks/config.example.ts +19 -0
  109. package/packages/shopify-app-remix/docs/staticPages/examples/guides/webhooks/endpoint.example.ts +24 -0
  110. package/packages/shopify-app-remix/docs/staticPages/examples/index/app-provider.example.ts +30 -0
  111. package/packages/shopify-app-remix/docs/staticPages/examples/index/boundaries.example.ts +9 -0
  112. package/packages/shopify-app-remix/docs/staticPages/examples/index/create.npm.example.sh +1 -0
  113. package/packages/shopify-app-remix/docs/staticPages/examples/index/create.pnpm.example.sh +1 -0
  114. package/packages/shopify-app-remix/docs/staticPages/examples/index/create.yarn.example.sh +1 -0
  115. package/packages/shopify-app-remix/docs/staticPages/examples/index/embedded-app-auth-strategy-config.example.ts +10 -0
  116. package/packages/shopify-app-remix/docs/staticPages/examples/index/entry-server.example.ts +12 -0
  117. package/packages/shopify-app-remix/docs/staticPages/examples/index/install.npm.example.sh +1 -0
  118. package/packages/shopify-app-remix/docs/staticPages/examples/index/install.pnpm.example.sh +1 -0
  119. package/packages/shopify-app-remix/docs/staticPages/examples/index/install.yarn.example.sh +1 -0
  120. package/packages/shopify-app-remix/docs/staticPages/examples/index/shopify-app.example.ts +14 -0
  121. package/packages/shopify-app-remix/docs/staticPages/examples/index/splat-route.example.ts +11 -0
  122. package/packages/shopify-app-remix/docs/staticPages/future-flags.doc.ts +94 -0
  123. package/packages/shopify-app-remix/docs/staticPages/graphql-types.doc.ts +148 -0
  124. package/packages/shopify-app-remix/docs/staticPages/index.doc.ts +227 -0
  125. package/packages/shopify-app-remix/docs/staticPages/webhooks.doc.ts +64 -0
  126. package/packages/shopify-app-remix/docs/tsconfig.docs.json +9 -0
  127. package/packages/shopify-app-remix/docs/typeOverride.json +1 -0
  128. package/packages/shopify-app-remix/docs/upcoming_changes.md +153 -0
  129. package/packages/shopify-app-remix/loom.config.ts +57 -0
  130. package/packages/shopify-app-remix/package.json +93 -0
  131. package/packages/shopify-app-remix/src/react/.eslintrc.js +16 -0
  132. package/packages/shopify-app-remix/src/react/__tests__/test-helper.ts +22 -0
  133. package/packages/shopify-app-remix/src/react/components/AppProvider/AppProvider.doc.ts +34 -0
  134. package/packages/shopify-app-remix/src/react/components/AppProvider/AppProvider.tsx +121 -0
  135. package/packages/shopify-app-remix/src/react/components/AppProvider/__tests__/AppProvider.test.tsx +68 -0
  136. package/packages/shopify-app-remix/src/react/components/AppProvider/index.ts +1 -0
  137. package/packages/shopify-app-remix/src/react/components/RemixPolarisLink.tsx +14 -0
  138. package/packages/shopify-app-remix/src/react/components/index.ts +1 -0
  139. package/packages/shopify-app-remix/src/react/const.ts +2 -0
  140. package/packages/shopify-app-remix/src/react/index.ts +1 -0
  141. package/packages/shopify-app-remix/src/server/.eslintrc.js +16 -0
  142. package/packages/shopify-app-remix/src/server/__test-helpers/__tests__/request-mock.test.ts +171 -0
  143. package/packages/shopify-app-remix/src/server/__test-helpers/const.ts +11 -0
  144. package/packages/shopify-app-remix/src/server/__test-helpers/expect-admin-api-client.ts +119 -0
  145. package/packages/shopify-app-remix/src/server/__test-helpers/expect-begin-auth-redirect.ts +22 -0
  146. package/packages/shopify-app-remix/src/server/__test-helpers/expect-document-request-headers.ts +25 -0
  147. package/packages/shopify-app-remix/src/server/__test-helpers/expect-exit-iframe.ts +37 -0
  148. package/packages/shopify-app-remix/src/server/__test-helpers/expect-login-redirect.ts +8 -0
  149. package/packages/shopify-app-remix/src/server/__test-helpers/expect-storefront-api-client.ts +50 -0
  150. package/packages/shopify-app-remix/src/server/__test-helpers/get-hmac.ts +10 -0
  151. package/packages/shopify-app-remix/src/server/__test-helpers/get-jwt.ts +31 -0
  152. package/packages/shopify-app-remix/src/server/__test-helpers/get-thrown-response.ts +17 -0
  153. package/packages/shopify-app-remix/src/server/__test-helpers/index.ts +14 -0
  154. package/packages/shopify-app-remix/src/server/__test-helpers/request-mock.ts +169 -0
  155. package/packages/shopify-app-remix/src/server/__test-helpers/setup-valid-session.ts +45 -0
  156. package/packages/shopify-app-remix/src/server/__test-helpers/sign-request-cookie.ts +21 -0
  157. package/packages/shopify-app-remix/src/server/__test-helpers/test-config.ts +112 -0
  158. package/packages/shopify-app-remix/src/server/__tests__/override-logger.test.ts +101 -0
  159. package/packages/shopify-app-remix/src/server/__tests__/shopify-app.test.ts +119 -0
  160. package/packages/shopify-app-remix/src/server/adapters/__tests__/node-app-bridge-url.test.ts +18 -0
  161. package/packages/shopify-app-remix/src/server/adapters/__tests__/node.test.ts +28 -0
  162. package/packages/shopify-app-remix/src/server/adapters/node/__tests__/setup-jest.ts +10 -0
  163. package/packages/shopify-app-remix/src/server/adapters/node/index.ts +20 -0
  164. package/packages/shopify-app-remix/src/server/adapters/vercel/__tests__/setup-jest.ts +12 -0
  165. package/packages/shopify-app-remix/src/server/adapters/vercel/index.ts +13 -0
  166. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/admin-client.test.ts +181 -0
  167. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/doc-request-path.test.ts +151 -0
  168. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/exit-i-frame-path.test.ts +99 -0
  169. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/patch-session-token-path.test.ts +58 -0
  170. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/reject-bot.test.ts +23 -0
  171. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/respond-to-options.test.ts +50 -0
  172. package/packages/shopify-app-remix/src/server/authenticate/admin/__tests__/session-token-header-path.test.ts +91 -0
  173. package/packages/shopify-app-remix/src/server/authenticate/admin/authenticate.admin.doc.ts +37 -0
  174. package/packages/shopify-app-remix/src/server/authenticate/admin/authenticate.ts +201 -0
  175. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/cancel.test.ts +258 -0
  176. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/check.test.ts +254 -0
  177. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/mock-responses.ts +65 -0
  178. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/request.test.ts +373 -0
  179. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/__tests__/require.test.ts +316 -0
  180. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/authenticate.admin.billing.doc.ts +28 -0
  181. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/cancel.ts +37 -0
  182. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/check.ts +38 -0
  183. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/index.ts +4 -0
  184. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/request.ts +101 -0
  185. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/require.ts +56 -0
  186. package/packages/shopify-app-remix/src/server/authenticate/admin/billing/types.ts +383 -0
  187. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/__tests__/redirect.test.ts +313 -0
  188. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/__tests__/validate-redirect-url.test.ts +84 -0
  189. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/begin-auth.ts +17 -0
  190. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/create-admin-api-context.ts +22 -0
  191. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/ensure-app-is-embedded-if-required.ts +18 -0
  192. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/ensure-session-token-search-param-if-required.ts +25 -0
  193. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/handle-client-error.ts +43 -0
  194. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/index.ts +14 -0
  195. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-to-auth-page.ts +28 -0
  196. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-to-bounce-page.ts +23 -0
  197. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-to-shopify-or-app-root.ts +21 -0
  198. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-with-app-bridge-headers.ts +13 -0
  199. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect-with-exitiframe.ts +28 -0
  200. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/redirect.ts +83 -0
  201. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/render-app-bridge.ts +46 -0
  202. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/trigger-after-auth-hook.ts +28 -0
  203. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/validate-redirect-url.ts +67 -0
  204. package/packages/shopify-app-remix/src/server/authenticate/admin/helpers/validate-shop-and-host-params.ts +28 -0
  205. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/admin-client.test.ts +222 -0
  206. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/auth-callback-path.test.ts +395 -0
  207. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/auth-path.test.ts +83 -0
  208. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/authenticate.test.ts +183 -0
  209. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/ensure-installed-on-shop.test.ts +234 -0
  210. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/auth-code-flow/session-token-header-path.test.ts +79 -0
  211. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/token-exchange/admin-client.test.ts +189 -0
  212. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/__tests__/token-exchange/authenticate.test.ts +310 -0
  213. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/auth-code-flow.ts +333 -0
  214. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/token-exchange.ts +169 -0
  215. package/packages/shopify-app-remix/src/server/authenticate/admin/strategies/types.ts +29 -0
  216. package/packages/shopify-app-remix/src/server/authenticate/admin/types.ts +199 -0
  217. package/packages/shopify-app-remix/src/server/authenticate/const.ts +15 -0
  218. package/packages/shopify-app-remix/src/server/authenticate/flow/__tests__/authenticate.test.ts +142 -0
  219. package/packages/shopify-app-remix/src/server/authenticate/flow/authenticate.flow.doc.ts +34 -0
  220. package/packages/shopify-app-remix/src/server/authenticate/flow/authenticate.ts +71 -0
  221. package/packages/shopify-app-remix/src/server/authenticate/flow/types.ts +90 -0
  222. package/packages/shopify-app-remix/src/server/authenticate/helpers/__tests__/add-response-headers.test.ts +25 -0
  223. package/packages/shopify-app-remix/src/server/authenticate/helpers/__tests__/app-bridge-url.test.ts +21 -0
  224. package/packages/shopify-app-remix/src/server/authenticate/helpers/__tests__/idempotent-promise-handler.test.ts +104 -0
  225. package/packages/shopify-app-remix/src/server/authenticate/helpers/add-response-headers.ts +43 -0
  226. package/packages/shopify-app-remix/src/server/authenticate/helpers/app-bridge-url.ts +10 -0
  227. package/packages/shopify-app-remix/src/server/authenticate/helpers/ensure-cors-headers.ts +38 -0
  228. package/packages/shopify-app-remix/src/server/authenticate/helpers/get-session-token-header.ts +11 -0
  229. package/packages/shopify-app-remix/src/server/authenticate/helpers/idempotent-promise-handler.ts +45 -0
  230. package/packages/shopify-app-remix/src/server/authenticate/helpers/index.ts +8 -0
  231. package/packages/shopify-app-remix/src/server/authenticate/helpers/reject-bot-request.ts +13 -0
  232. package/packages/shopify-app-remix/src/server/authenticate/helpers/respond-to-invalid-session-token.ts +29 -0
  233. package/packages/shopify-app-remix/src/server/authenticate/helpers/respond-to-options-request.ts +26 -0
  234. package/packages/shopify-app-remix/src/server/authenticate/helpers/validate-session-token.ts +32 -0
  235. package/packages/shopify-app-remix/src/server/authenticate/login/__tests__/login.test.ts +157 -0
  236. package/packages/shopify-app-remix/src/server/authenticate/login/login.ts +53 -0
  237. package/packages/shopify-app-remix/src/server/authenticate/public/__tests__/factory.test.ts +224 -0
  238. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/__tests__/authenticate.test.ts +282 -0
  239. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/authenticate.public.app-proxy.doc.ts +36 -0
  240. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/authenticate.ts +90 -0
  241. package/packages/shopify-app-remix/src/server/authenticate/public/appProxy/types.ts +164 -0
  242. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/__tests__/authenticate.test.ts +142 -0
  243. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/authenticate.public.checkout.doc.ts +23 -0
  244. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/authenticate.ts +45 -0
  245. package/packages/shopify-app-remix/src/server/authenticate/public/checkout/types.ts +65 -0
  246. package/packages/shopify-app-remix/src/server/authenticate/public/factory.ts +49 -0
  247. package/packages/shopify-app-remix/src/server/authenticate/public/index.ts +1 -0
  248. package/packages/shopify-app-remix/src/server/authenticate/public/types.ts +77 -0
  249. package/packages/shopify-app-remix/src/server/authenticate/webhooks/__tests__/authenticate.test.ts +207 -0
  250. package/packages/shopify-app-remix/src/server/authenticate/webhooks/__tests__/mock-responses.ts +45 -0
  251. package/packages/shopify-app-remix/src/server/authenticate/webhooks/__tests__/register.test.ts +210 -0
  252. package/packages/shopify-app-remix/src/server/authenticate/webhooks/authenticate.ts +113 -0
  253. package/packages/shopify-app-remix/src/server/authenticate/webhooks/authenticate.webhooks.doc.ts +28 -0
  254. package/packages/shopify-app-remix/src/server/authenticate/webhooks/index.ts +1 -0
  255. package/packages/shopify-app-remix/src/server/authenticate/webhooks/register.ts +48 -0
  256. package/packages/shopify-app-remix/src/server/authenticate/webhooks/types.ts +246 -0
  257. package/packages/shopify-app-remix/src/server/boundary/__tests__/error.test.tsx +36 -0
  258. package/packages/shopify-app-remix/src/server/boundary/__tests__/headers.test.ts +66 -0
  259. package/packages/shopify-app-remix/src/server/boundary/error.tsx +14 -0
  260. package/packages/shopify-app-remix/src/server/boundary/headers.ts +15 -0
  261. package/packages/shopify-app-remix/src/server/boundary/index.ts +39 -0
  262. package/packages/shopify-app-remix/src/server/boundary/types.ts +4 -0
  263. package/packages/shopify-app-remix/src/server/clients/admin/authenticate.admin.api.doc.ts +34 -0
  264. package/packages/shopify-app-remix/src/server/clients/admin/factory.ts +30 -0
  265. package/packages/shopify-app-remix/src/server/clients/admin/graphql.ts +39 -0
  266. package/packages/shopify-app-remix/src/server/clients/admin/index.ts +2 -0
  267. package/packages/shopify-app-remix/src/server/clients/admin/rest.ts +157 -0
  268. package/packages/shopify-app-remix/src/server/clients/admin/types.ts +178 -0
  269. package/packages/shopify-app-remix/src/server/clients/index.ts +2 -0
  270. package/packages/shopify-app-remix/src/server/clients/storefront/authenticate.storefront.api.doc.ts +34 -0
  271. package/packages/shopify-app-remix/src/server/clients/storefront/factory.ts +32 -0
  272. package/packages/shopify-app-remix/src/server/clients/storefront/index.ts +2 -0
  273. package/packages/shopify-app-remix/src/server/clients/storefront/types.ts +31 -0
  274. package/packages/shopify-app-remix/src/server/clients/types.ts +27 -0
  275. package/packages/shopify-app-remix/src/server/config-types.ts +293 -0
  276. package/packages/shopify-app-remix/src/server/errors.ts +3 -0
  277. package/packages/shopify-app-remix/src/server/future/flags.ts +57 -0
  278. package/packages/shopify-app-remix/src/server/index.ts +20 -0
  279. package/packages/shopify-app-remix/src/server/override-logger.ts +42 -0
  280. package/packages/shopify-app-remix/src/server/shopify-app.doc.ts +45 -0
  281. package/packages/shopify-app-remix/src/server/shopify-app.ts +198 -0
  282. package/packages/shopify-app-remix/src/server/types.ts +509 -0
  283. package/packages/shopify-app-remix/src/server/unauthenticated/admin/__tests__/factory.test.ts +30 -0
  284. package/packages/shopify-app-remix/src/server/unauthenticated/admin/factory.ts +29 -0
  285. package/packages/shopify-app-remix/src/server/unauthenticated/admin/index.ts +1 -0
  286. package/packages/shopify-app-remix/src/server/unauthenticated/admin/types.ts +117 -0
  287. package/packages/shopify-app-remix/src/server/unauthenticated/admin/unauthenticated.admin.doc.ts +40 -0
  288. package/packages/shopify-app-remix/src/server/unauthenticated/helpers/get-offline-session.ts +13 -0
  289. package/packages/shopify-app-remix/src/server/unauthenticated/helpers/index.ts +1 -0
  290. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/__tests__/factory.test.ts +30 -0
  291. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/factory.ts +28 -0
  292. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/index.ts +1 -0
  293. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/types.ts +39 -0
  294. package/packages/shopify-app-remix/src/server/unauthenticated/storefront/unauthenticated.storefront.doc.ts +40 -0
  295. package/packages/shopify-app-remix/src/server/unauthenticated/types.ts +68 -0
  296. package/packages/shopify-app-remix/src/server/version.ts +1 -0
  297. package/packages/shopify-app-remix/tsconfig.json +11 -0
  298. package/packages/shopify-app-session-storage/CHANGELOG.md +149 -0
  299. package/packages/shopify-app-session-storage/LICENSE.md +9 -0
  300. package/packages/shopify-app-session-storage/README.md +5 -0
  301. package/packages/shopify-app-session-storage/implementing-session-storage.md +214 -0
  302. package/packages/shopify-app-session-storage/loom.config.ts +45 -0
  303. package/packages/shopify-app-session-storage/package.json +44 -0
  304. package/packages/shopify-app-session-storage/src/__tests__/setup-jest.ts +8 -0
  305. package/packages/shopify-app-session-storage/src/abstract-migration-engine.ts +53 -0
  306. package/packages/shopify-app-session-storage/src/index.ts +3 -0
  307. package/packages/shopify-app-session-storage/src/rdbms-session-storage-migrator.ts +59 -0
  308. package/packages/shopify-app-session-storage/src/types.ts +174 -0
  309. package/packages/shopify-app-session-storage/tsconfig.json +10 -0
  310. package/packages/shopify-app-session-storage-dynamodb/CHANGELOG.md +150 -0
  311. package/packages/shopify-app-session-storage-dynamodb/LICENSE.md +9 -0
  312. package/packages/shopify-app-session-storage-dynamodb/README.md +75 -0
  313. package/packages/shopify-app-session-storage-dynamodb/loom.config.ts +27 -0
  314. package/packages/shopify-app-session-storage-dynamodb/package.json +51 -0
  315. package/packages/shopify-app-session-storage-dynamodb/src/__tests__/dynamodb.test.ts +93 -0
  316. package/packages/shopify-app-session-storage-dynamodb/src/__tests__/setup-jest.ts +8 -0
  317. package/packages/shopify-app-session-storage-dynamodb/src/dynamodb.ts +126 -0
  318. package/packages/shopify-app-session-storage-dynamodb/tsconfig.json +10 -0
  319. package/packages/shopify-app-session-storage-kv/CHANGELOG.md +204 -0
  320. package/packages/shopify-app-session-storage-kv/LICENSE.md +9 -0
  321. package/packages/shopify-app-session-storage-kv/README.md +41 -0
  322. package/packages/shopify-app-session-storage-kv/loom.config.ts +27 -0
  323. package/packages/shopify-app-session-storage-kv/package.json +52 -0
  324. package/packages/shopify-app-session-storage-kv/src/__tests__/kv-namespace-dummy-worker.ts +8 -0
  325. package/packages/shopify-app-session-storage-kv/src/__tests__/kv.test.ts +22 -0
  326. package/packages/shopify-app-session-storage-kv/src/__tests__/setup-jest.ts +8 -0
  327. package/packages/shopify-app-session-storage-kv/src/kv.ts +87 -0
  328. package/packages/shopify-app-session-storage-kv/tsconfig.json +11 -0
  329. package/packages/shopify-app-session-storage-memory/CHANGELOG.md +190 -0
  330. package/packages/shopify-app-session-storage-memory/LICENSE.md +9 -0
  331. package/packages/shopify-app-session-storage-memory/README.md +19 -0
  332. package/packages/shopify-app-session-storage-memory/loom.config.ts +27 -0
  333. package/packages/shopify-app-session-storage-memory/package.json +46 -0
  334. package/packages/shopify-app-session-storage-memory/src/__tests__/memory.test.ts +12 -0
  335. package/packages/shopify-app-session-storage-memory/src/__tests__/setup-jest.ts +8 -0
  336. package/packages/shopify-app-session-storage-memory/src/memory.ts +34 -0
  337. package/packages/shopify-app-session-storage-memory/tsconfig.json +10 -0
  338. package/packages/shopify-app-session-storage-mongodb/CHANGELOG.md +208 -0
  339. package/packages/shopify-app-session-storage-mongodb/LICENSE.md +9 -0
  340. package/packages/shopify-app-session-storage-mongodb/README.md +30 -0
  341. package/packages/shopify-app-session-storage-mongodb/loom.config.ts +27 -0
  342. package/packages/shopify-app-session-storage-mongodb/package.json +49 -0
  343. package/packages/shopify-app-session-storage-mongodb/src/__tests__/mongodb.test.ts +54 -0
  344. package/packages/shopify-app-session-storage-mongodb/src/__tests__/setup-jest.ts +8 -0
  345. package/packages/shopify-app-session-storage-mongodb/src/mongodb.ts +120 -0
  346. package/packages/shopify-app-session-storage-mongodb/tsconfig.json +10 -0
  347. package/packages/shopify-app-session-storage-mysql/CHANGELOG.md +220 -0
  348. package/packages/shopify-app-session-storage-mysql/LICENSE.md +9 -0
  349. package/packages/shopify-app-session-storage-mysql/README.md +41 -0
  350. package/packages/shopify-app-session-storage-mysql/loom.config.ts +27 -0
  351. package/packages/shopify-app-session-storage-mysql/package.json +50 -0
  352. package/packages/shopify-app-session-storage-mysql/src/__tests__/mysql.test.ts +137 -0
  353. package/packages/shopify-app-session-storage-mysql/src/__tests__/setup-jest.ts +8 -0
  354. package/packages/shopify-app-session-storage-mysql/src/migrations.ts +18 -0
  355. package/packages/shopify-app-session-storage-mysql/src/mysql-connection.ts +108 -0
  356. package/packages/shopify-app-session-storage-mysql/src/mysql-migrator.ts +53 -0
  357. package/packages/shopify-app-session-storage-mysql/src/mysql.ts +178 -0
  358. package/packages/shopify-app-session-storage-mysql/tsconfig.json +10 -0
  359. package/packages/shopify-app-session-storage-postgresql/CHANGELOG.md +210 -0
  360. package/packages/shopify-app-session-storage-postgresql/LICENSE.md +9 -0
  361. package/packages/shopify-app-session-storage-postgresql/README.md +39 -0
  362. package/packages/shopify-app-session-storage-postgresql/loom.config.ts +27 -0
  363. package/packages/shopify-app-session-storage-postgresql/package.json +52 -0
  364. package/packages/shopify-app-session-storage-postgresql/src/__tests__/migrate-to-case-sensitivity.test.ts +344 -0
  365. package/packages/shopify-app-session-storage-postgresql/src/__tests__/postgresql.test.ts +136 -0
  366. package/packages/shopify-app-session-storage-postgresql/src/__tests__/setup-jest.ts +8 -0
  367. package/packages/shopify-app-session-storage-postgresql/src/migrations.ts +70 -0
  368. package/packages/shopify-app-session-storage-postgresql/src/postgres-connection.ts +94 -0
  369. package/packages/shopify-app-session-storage-postgresql/src/postgres-migrator.ts +27 -0
  370. package/packages/shopify-app-session-storage-postgresql/src/postgresql.ts +178 -0
  371. package/packages/shopify-app-session-storage-postgresql/tsconfig.json +10 -0
  372. package/packages/shopify-app-session-storage-prisma/CHANGELOG.md +148 -0
  373. package/packages/shopify-app-session-storage-prisma/LICENSE.md +9 -0
  374. package/packages/shopify-app-session-storage-prisma/README.md +68 -0
  375. package/packages/shopify-app-session-storage-prisma/loom.config.ts +27 -0
  376. package/packages/shopify-app-session-storage-prisma/package.json +51 -0
  377. package/packages/shopify-app-session-storage-prisma/prisma/migrations/20230425184828_init/migration.sql +11 -0
  378. package/packages/shopify-app-session-storage-prisma/prisma/migrations/20230906155758_mySession/migration.sql +11 -0
  379. package/packages/shopify-app-session-storage-prisma/prisma/migrations/migration_lock.toml +3 -0
  380. package/packages/shopify-app-session-storage-prisma/prisma/schema.prisma +30 -0
  381. package/packages/shopify-app-session-storage-prisma/src/__tests__/prisma.test.ts +66 -0
  382. package/packages/shopify-app-session-storage-prisma/src/__tests__/setup-jest.ts +8 -0
  383. package/packages/shopify-app-session-storage-prisma/src/prisma.ts +145 -0
  384. package/packages/shopify-app-session-storage-prisma/tsconfig.json +10 -0
  385. package/packages/shopify-app-session-storage-redis/CHANGELOG.md +200 -0
  386. package/packages/shopify-app-session-storage-redis/LICENSE.md +9 -0
  387. package/packages/shopify-app-session-storage-redis/README.md +38 -0
  388. package/packages/shopify-app-session-storage-redis/loom.config.ts +27 -0
  389. package/packages/shopify-app-session-storage-redis/package.json +50 -0
  390. package/packages/shopify-app-session-storage-redis/src/__tests__/migration-test-data.ts +46 -0
  391. package/packages/shopify-app-session-storage-redis/src/__tests__/redis.conf +2 -0
  392. package/packages/shopify-app-session-storage-redis/src/__tests__/redis.test.ts +236 -0
  393. package/packages/shopify-app-session-storage-redis/src/__tests__/setup-jest.ts +8 -0
  394. package/packages/shopify-app-session-storage-redis/src/migrations.ts +36 -0
  395. package/packages/shopify-app-session-storage-redis/src/redis-connection.ts +64 -0
  396. package/packages/shopify-app-session-storage-redis/src/redis-migrator.ts +58 -0
  397. package/packages/shopify-app-session-storage-redis/src/redis.ts +167 -0
  398. package/packages/shopify-app-session-storage-redis/tsconfig.json +10 -0
  399. package/packages/shopify-app-session-storage-sqlite/CHANGELOG.md +202 -0
  400. package/packages/shopify-app-session-storage-sqlite/LICENSE.md +9 -0
  401. package/packages/shopify-app-session-storage-sqlite/README.md +25 -0
  402. package/packages/shopify-app-session-storage-sqlite/loom.config.ts +27 -0
  403. package/packages/shopify-app-session-storage-sqlite/package.json +51 -0
  404. package/packages/shopify-app-session-storage-sqlite/src/__tests__/setup-jest.ts +8 -0
  405. package/packages/shopify-app-session-storage-sqlite/src/__tests__/sqlite.test.ts +44 -0
  406. package/packages/shopify-app-session-storage-sqlite/src/migrations.ts +54 -0
  407. package/packages/shopify-app-session-storage-sqlite/src/sqlite-connection.ts +80 -0
  408. package/packages/shopify-app-session-storage-sqlite/src/sqlite-migrator.ts +34 -0
  409. package/packages/shopify-app-session-storage-sqlite/src/sqlite.ts +147 -0
  410. package/packages/shopify-app-session-storage-sqlite/tsconfig.json +10 -0
  411. package/packages/shopify-app-session-storage-test-utils/CHANGELOG.md +185 -0
  412. package/packages/shopify-app-session-storage-test-utils/LICENSE.md +9 -0
  413. package/packages/shopify-app-session-storage-test-utils/loom.config.ts +27 -0
  414. package/packages/shopify-app-session-storage-test-utils/package.json +48 -0
  415. package/packages/shopify-app-session-storage-test-utils/src/__tests__/session-test-utils.test.ts +273 -0
  416. package/packages/shopify-app-session-storage-test-utils/src/battery-of-tests.ts +250 -0
  417. package/packages/shopify-app-session-storage-test-utils/src/index.ts +2 -0
  418. package/packages/shopify-app-session-storage-test-utils/src/session-test-utils.ts +24 -0
  419. package/packages/shopify-app-session-storage-test-utils/src/utils.ts +71 -0
  420. package/packages/shopify-app-session-storage-test-utils/tsconfig.json +10 -0
  421. package/tests/setup/build.js +1 -0
  422. package/tests/setup/setup-jest.ts +8 -0
  423. package/tsconfig.base.json +41 -0
  424. package/tsconfig.json +19 -0
@@ -0,0 +1,509 @@
1
+ import {
2
+ RegisterReturn,
3
+ Shopify,
4
+ ShopifyRestResources,
5
+ } from '@shopify/shopify-api';
6
+ import {SessionStorage} from '@shopify/shopify-app-session-storage';
7
+
8
+ import type {AppConfig, AppConfigArg} from './config-types';
9
+ import type {
10
+ AuthenticateWebhook,
11
+ RegisterWebhooksOptions,
12
+ } from './authenticate/webhooks/types';
13
+ import type {AuthenticatePublic} from './authenticate/public/types';
14
+ import type {AuthenticateAdmin} from './authenticate/admin/types';
15
+ import type {Unauthenticated} from './unauthenticated/types';
16
+ import type {AuthenticateFlow} from './authenticate/flow/types';
17
+ import type {
18
+ ApiConfigWithFutureFlags,
19
+ ApiFutureFlags,
20
+ FutureFlagOptions,
21
+ } from './future/flags';
22
+
23
+ export interface BasicParams<
24
+ Future extends FutureFlagOptions = FutureFlagOptions,
25
+ > {
26
+ api: Shopify<
27
+ ApiConfigWithFutureFlags<Future>,
28
+ ShopifyRestResources,
29
+ ApiFutureFlags<Future>
30
+ >;
31
+ config: AppConfig;
32
+ logger: Shopify['logger'];
33
+ }
34
+
35
+ export type JSONValue =
36
+ | string
37
+ | number
38
+ | boolean
39
+ | null
40
+ | JSONObject
41
+ | JSONArray;
42
+
43
+ // eslint-disable-next-line no-warning-comments
44
+ // TODO: Use this enum to replace the isCustomStoreApp config option in shopify-api-js
45
+ export enum AppDistribution {
46
+ AppStore = 'app_store',
47
+ SingleMerchant = 'single_merchant',
48
+ ShopifyAdmin = 'shopify_admin',
49
+ }
50
+
51
+ export type MandatoryTopics =
52
+ | 'CUSTOMERS_DATA_REQUEST'
53
+ | 'CUSTOMERS_REDACT'
54
+ | 'SHOP_REDACT';
55
+
56
+ // This can't be a type because it would reference itself
57
+ // eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
58
+ interface JSONObject {
59
+ [x: string]: JSONValue;
60
+ }
61
+
62
+ interface JSONArray extends Array<JSONValue> {}
63
+
64
+ type RegisterWebhooks = (
65
+ options: RegisterWebhooksOptions,
66
+ ) => Promise<RegisterReturn | void>;
67
+
68
+ export enum LoginErrorType {
69
+ MissingShop = 'MISSING_SHOP',
70
+ InvalidShop = 'INVALID_SHOP',
71
+ }
72
+
73
+ export interface LoginError {
74
+ shop?: LoginErrorType;
75
+ }
76
+
77
+ type Login = (request: Request) => Promise<LoginError | never>;
78
+
79
+ type AddDocumentResponseHeaders = (request: Request, headers: Headers) => void;
80
+
81
+ type RestResourcesType<Config extends AppConfigArg> =
82
+ Config['restResources'] extends ShopifyRestResources
83
+ ? Config['restResources']
84
+ : ShopifyRestResources;
85
+
86
+ type SessionStorageType<Config extends AppConfigArg> =
87
+ Config['sessionStorage'] extends SessionStorage
88
+ ? Config['sessionStorage']
89
+ : SessionStorage;
90
+
91
+ interface Authenticate<Config extends AppConfigArg> {
92
+ /**
93
+ * Authenticate an admin Request and get back an authenticated admin context. Use the authenticated admin context to interact with Shopify.
94
+ *
95
+ * Examples of when to use this are requests from your app's UI, or requests from admin extensions.
96
+ *
97
+ * If there is no session for the Request, this will redirect the merchant to correct auth flows.
98
+ *
99
+ * @example
100
+ * <caption>Authenticating a request for an embedded app.</caption>
101
+ * ```ts
102
+ * // /app/routes/**\/*.jsx
103
+ * import { LoaderFunctionArgs, json } from "@remix-run/node";
104
+ * import { authenticate } from "../../shopify.server";
105
+ *
106
+ * export async function loader({ request }: LoaderFunctionArgs) {
107
+ * const {admin, session, sessionToken, billing} = authenticate.admin(request);
108
+ *
109
+ * return json(await admin.rest.resources.Product.count({ session }));
110
+ * }
111
+ * ```
112
+ * ```ts
113
+ * // /app/shopify.server.ts
114
+ * import { LATEST_API_VERSION, shopifyApp } from "@shopify/shopify-app-remix/server";
115
+ * import { restResources } from "@shopify/shopify-api/rest/admin/2023-04";
116
+ *
117
+ * const shopify = shopifyApp({
118
+ * restResources,
119
+ * // ...etc
120
+ * });
121
+ * export default shopify;
122
+ * export const authenticate = shopify.authenticate;
123
+ * ```
124
+ */
125
+ admin: AuthenticateAdmin<Config, RestResourcesType<Config>>;
126
+
127
+ /**
128
+ * Authenticate a Flow extension Request and get back an authenticated context, containing an admin context to access
129
+ * the API, and the payload of the request.
130
+ *
131
+ * If there is no session for the Request, this will return an HTTP 400 error.
132
+ *
133
+ * Note that this will always be a POST request.
134
+ *
135
+ * @example
136
+ * <caption>Authenticating a Flow extension request.</caption>
137
+ * ```ts
138
+ * // /app/routes/**\/*.jsx
139
+ * import { ActionFunctionArgs, json } from "@remix-run/node";
140
+ * import { authenticate } from "../../shopify.server";
141
+ *
142
+ * export async function action({ request }: ActionFunctionArgs) {
143
+ * const {admin, session, payload} = authenticate.flow(request);
144
+ *
145
+ * // Perform flow extension logic
146
+ *
147
+ * // Return a 200 response
148
+ * return null;
149
+ * }
150
+ * ```
151
+ * ```ts
152
+ * // /app/shopify.server.ts
153
+ * import { LATEST_API_VERSION, shopifyApp } from "@shopify/shopify-app-remix/server";
154
+ * import { restResources } from "@shopify/shopify-api/rest/admin/2023-04";
155
+ *
156
+ * const shopify = shopifyApp({
157
+ * restResources,
158
+ * // ...etc
159
+ * });
160
+ * export default shopify;
161
+ * export const authenticate = shopify.authenticate;
162
+ * ```
163
+ */
164
+ flow: AuthenticateFlow<RestResourcesType<Config>>;
165
+
166
+ /**
167
+ * Authenticate a public request and get back a session token.
168
+ *
169
+ * @example
170
+ * <caption>Authenticating a request from a checkout extension</caption>
171
+ *
172
+ * ```ts
173
+ * // /app/routes/api/checkout.jsx
174
+ * import { LoaderFunctionArgs, json } from "@remix-run/node";
175
+ * import { authenticate } from "../../shopify.server";
176
+ * import { getWidgets } from "~/db/widgets";
177
+ *
178
+ * export async function loader({ request }: LoaderFunctionArgs) {
179
+ * const {sessionToken} = authenticate.public.checkout(request);
180
+ *
181
+ * return json(await getWidgets(sessionToken));
182
+ * }
183
+ * ```
184
+ */
185
+ public: AuthenticatePublic<Config['future']>;
186
+
187
+ /**
188
+ * Authenticate a Shopify webhook request, get back an authenticated admin context and details on the webhook request
189
+ *
190
+ * @example
191
+ * <caption>Authenticating a webhook request</caption>
192
+ *
193
+ * ```ts
194
+ * // /app/shopify.server.ts
195
+ * import { DeliveryMethod, shopifyApp } from "@shopify/shopify-app-remix/server";
196
+ *
197
+ * const shopify = shopifyApp({
198
+ * webhooks: {
199
+ * APP_UNINSTALLED: {
200
+ * deliveryMethod: DeliveryMethod.Http,
201
+ * callbackUrl: "/webhooks",
202
+ * },
203
+ * },
204
+ * hooks: {
205
+ * afterAuth: async ({ session }) => {
206
+ * shopify.registerWebhooks({ session });
207
+ * },
208
+ * },
209
+ * // ...etc
210
+ * });
211
+ * export default shopify;
212
+ * export const authenticate = shopify.authenticate;
213
+ * ```
214
+ * ```ts
215
+ * // /app/routes/webhooks.ts
216
+ * import { ActionFunctionArgs } from "@remix-run/node";
217
+ * import { authenticate } from "../shopify.server";
218
+ * import db from "../db.server";
219
+ *
220
+ * export const action = async ({ request }: ActionFunctionArgs) => {
221
+ * const { topic, shop, session } = await authenticate.webhook(request);
222
+ *
223
+ * switch (topic) {
224
+ * case "APP_UNINSTALLED":
225
+ * if (session) {
226
+ * await db.session.deleteMany({ where: { shop } });
227
+ * }
228
+ * break;
229
+ * case "CUSTOMERS_DATA_REQUEST":
230
+ * case "CUSTOMERS_REDACT":
231
+ * case "SHOP_REDACT":
232
+ * default:
233
+ * throw new Response("Unhandled webhook topic", { status: 404 });
234
+ * }
235
+ *
236
+ * throw new Response();
237
+ * };
238
+ * ```
239
+ */
240
+ webhook: AuthenticateWebhook<
241
+ Config['future'],
242
+ RestResourcesType<Config>,
243
+ keyof Config['webhooks'] | MandatoryTopics
244
+ >;
245
+ }
246
+
247
+ export interface ShopifyAppBase<Config extends AppConfigArg> {
248
+ /**
249
+ * The `SessionStorage` instance you passed in as a config option.
250
+ *
251
+ * @example
252
+ * <caption>Storing sessions with Prisma.</caption>
253
+ * <description>Import the `@shopify/shopify-app-session-storage-prisma` package to store sessions in your Prisma database.</description>
254
+ * ```ts
255
+ * // /app/shopify.server.ts
256
+ * import { shopifyApp } from "@shopify/shopify-app-remix/server";
257
+ * import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma";
258
+ * import prisma from "~/db.server";
259
+ *
260
+ * const shopify = shopifyApp({
261
+ * sessionStorage: new PrismaSessionStorage(prisma),
262
+ * // ...etc
263
+ * })
264
+ *
265
+ * // shopify.sessionStorage is an instance of PrismaSessionStorage
266
+ * ```
267
+ */
268
+ sessionStorage: SessionStorageType<Config>;
269
+
270
+ /**
271
+ * Adds the required Content Security Policy headers for Shopify apps to the given Headers object.
272
+ *
273
+ * {@link https://shopify.dev/docs/apps/store/security/iframe-protection}
274
+ *
275
+ * @example
276
+ * <caption>Return headers on all requests.</caption>
277
+ * <description>Add headers to all HTML requests by calling `shopify.addDocumentResponseHeaders` in `entry.server.tsx`.</description>
278
+ *
279
+ * ```
280
+ * // ~/shopify.server.ts
281
+ * import { shopifyApp } from "@shopify/shopify-app-remix/server";
282
+ *
283
+ * const shopify = shopifyApp({
284
+ * // ...etc
285
+ * });
286
+ * export default shopify;
287
+ * export const addDocumentResponseheaders = shopify.addDocumentResponseheaders;
288
+ * ```
289
+ *
290
+ * ```ts
291
+ * // entry.server.tsx
292
+ * import { addDocumentResponseHeaders } from "~/shopify.server";
293
+ *
294
+ * export default function handleRequest(
295
+ * request: Request,
296
+ * responseStatusCode: number,
297
+ * responseHeaders: Headers,
298
+ * remixContext: EntryContext
299
+ * ) {
300
+ * const markup = renderToString(
301
+ * <RemixServer context={remixContext} url={request.url} />
302
+ * );
303
+ *
304
+ * responseHeaders.set("Content-Type", "text/html");
305
+ * addDocumentResponseHeaders(request, responseHeaders);
306
+ *
307
+ * return new Response("<!DOCTYPE html>" + markup, {
308
+ * status: responseStatusCode,
309
+ * headers: responseHeaders,
310
+ * });
311
+ * }
312
+ * ```
313
+ */
314
+ addDocumentResponseHeaders: AddDocumentResponseHeaders;
315
+
316
+ /**
317
+ * Register webhook topics for a store using the given session. Most likely you want to use this in combination with the afterAuth hook.
318
+ *
319
+ * @example
320
+ * <caption>Registering webhooks after install</caption>
321
+ * <description>Trigger the registration to create the webhook subscriptions after a merchant installs your app using the `afterAuth` hook. Learn more about [subscribing to webhooks.](/docs/api/shopify-app-remix/v1/guide-webhooks)</description>
322
+ * ```ts
323
+ * // /app/shopify.server.ts
324
+ * import { DeliveryMethod, shopifyApp } from "@shopify/shopify-app-remix/server";
325
+ *
326
+ * const shopify = shopifyApp({
327
+ * hooks: {
328
+ * afterAuth: async ({ session }) => {
329
+ * shopify.registerWebhooks({ session });
330
+ * }
331
+ * },
332
+ * webhooks: {
333
+ * APP_UNINSTALLED: {
334
+ * deliveryMethod: DeliveryMethod.Http,
335
+ * callbackUrl: "/webhooks",
336
+ * },
337
+ * },
338
+ * // ...etc
339
+ * });
340
+ * ```
341
+ */
342
+ registerWebhooks: RegisterWebhooks;
343
+
344
+ /**
345
+ * Ways to authenticate requests from different surfaces across Shopify.
346
+ *
347
+ * @example
348
+ * <caption>Authenticate Shopify requests.</caption>
349
+ * <description>Use the functions in `authenticate` to validate requests coming from Shopify.</description>
350
+ * ```ts
351
+ * // /app/shopify.server.ts
352
+ * import { LATEST_API_VERSION, shopifyApp } from "@shopify/shopify-app-remix/server";
353
+ * import { restResources } from "@shopify/shopify-api/rest/admin/2023-04";
354
+ *
355
+ * const shopify = shopifyApp({
356
+ * restResources,
357
+ * // ...etc
358
+ * });
359
+ * export default shopify;
360
+ * ```
361
+ * ```ts
362
+ * // /app/routes/**\/*.jsx
363
+ * import { LoaderFunctionArgs, json } from "@remix-run/node";
364
+ * import shopify from "../../shopify.server";
365
+ *
366
+ * export async function loader({ request }: LoaderFunctionArgs) {
367
+ * const {admin, session, sessionToken, billing} = shopify.authenticate.admin(request);
368
+ *
369
+ * return json(await admin.rest.resources.Product.count({ session }));
370
+ * }
371
+ * ```
372
+ */
373
+ authenticate: Authenticate<Config>;
374
+
375
+ /**
376
+ * Ways to get Contexts from requests that do not originate from Shopify.
377
+ *
378
+ * @example
379
+ * <caption>Using unauthenticated contexts.</caption>
380
+ * <description>Create contexts for requests that don't come from Shopify.</description>
381
+ * ```ts
382
+ * // /app/shopify.server.ts
383
+ * import { LATEST_API_VERSION, shopifyApp } from "@shopify/shopify-app-remix/server";
384
+ * import { restResources } from "@shopify/shopify-api/rest/admin/2023-04";
385
+ *
386
+ * const shopify = shopifyApp({
387
+ * restResources,
388
+ * // ...etc
389
+ * });
390
+ * export default shopify;
391
+ * ```
392
+ * ```ts
393
+ * // /app/routes/**\/*.jsx
394
+ * import { LoaderFunctionArgs, json } from "@remix-run/node";
395
+ * import { authenticateExternal } from "~/helpers/authenticate"
396
+ * import shopify from "../../shopify.server";
397
+ *
398
+ * export async function loader({ request }: LoaderFunctionArgs) {
399
+ * const shop = await authenticateExternal(request)
400
+ * const {admin} = await shopify.unauthenticated.admin(shop);
401
+ *
402
+ * return json(await admin.rest.resources.Product.count({ session }));
403
+ * }
404
+ * ```
405
+ */
406
+ unauthenticated: Unauthenticated<RestResourcesType<Config>>;
407
+ }
408
+
409
+ interface ShopifyAppLogin {
410
+ /**
411
+ * Log a merchant in, and redirect them to the app root. Will redirect the merchant to authentication if a shop is
412
+ * present in the URL search parameters or form data.
413
+ *
414
+ * This function won't be present when the `distribution` config option is set to `AppDistribution.ShopifyAdmin`,
415
+ * because Admin apps aren't allowed to show a login page.
416
+ *
417
+ * @example
418
+ * <caption>Creating a login page.</caption>
419
+ * <description>Use `shopify.login` to create a login form, in a route that can handle GET and POST requests.</description>
420
+ * ```ts
421
+ * // /app/shopify.server.ts
422
+ * import { LATEST_API_VERSION, shopifyApp } from "@shopify/shopify-app-remix/server";
423
+ *
424
+ * const shopify = shopifyApp({
425
+ * // ...etc
426
+ * });
427
+ * export default shopify;
428
+ * ```
429
+ * ```ts
430
+ * // /app/routes/auth/login.tsx
431
+ * import shopify from "../../shopify.server";
432
+ *
433
+ * export async function loader({ request }: LoaderFunctionArgs) {
434
+ * const errors = shopify.login(request);
435
+ *
436
+ * return json(errors);
437
+ * }
438
+ *
439
+ * export async function action({ request }: ActionFunctionArgs) {
440
+ * const errors = shopify.login(request);
441
+ *
442
+ * return json(errors);
443
+ * }
444
+ *
445
+ * export default function Auth() {
446
+ * const actionData = useActionData<typeof action>();
447
+ * const [shop, setShop] = useState("");
448
+ *
449
+ * return (
450
+ * <Page>
451
+ * <Card>
452
+ * <Form method="post">
453
+ * <FormLayout>
454
+ * <Text variant="headingMd" as="h2">
455
+ * Login
456
+ * </Text>
457
+ * <TextField
458
+ * type="text"
459
+ * name="shop"
460
+ * label="Shop domain"
461
+ * helpText="e.g: my-shop-domain.myshopify.com"
462
+ * value={shop}
463
+ * onChange={setShop}
464
+ * autoComplete="on"
465
+ * error={actionData?.errors.shop}
466
+ * />
467
+ * <Button submit primary>
468
+ * Submit
469
+ * </Button>
470
+ * </FormLayout>
471
+ * </Form>
472
+ * </Card>
473
+ * </Page>
474
+ * );
475
+ * }
476
+ * ```
477
+ */
478
+ login: Login;
479
+ }
480
+
481
+ export type ShopifyAppLogger = {
482
+ /**
483
+ * Shopify App Logger
484
+ */
485
+
486
+ logger: Shopify['logger'];
487
+ };
488
+
489
+ export type AdminApp<Config extends AppConfigArg> = ShopifyAppBase<Config> &
490
+ ShopifyAppLogger;
491
+ export type SingleMerchantApp<Config extends AppConfigArg> =
492
+ ShopifyAppBase<Config> & ShopifyAppLogin & ShopifyAppLogger;
493
+ export type AppStoreApp<Config extends AppConfigArg> = ShopifyAppBase<Config> &
494
+ ShopifyAppLogin &
495
+ ShopifyAppLogger;
496
+
497
+ /**
498
+ * An object your app can use to interact with Shopify.
499
+ *
500
+ * By default, the app's distribution is `AppStore`.
501
+ */
502
+ export type ShopifyApp<Config extends AppConfigArg> =
503
+ Config['distribution'] extends AppDistribution.ShopifyAdmin
504
+ ? AdminApp<Config>
505
+ : Config['distribution'] extends AppDistribution.SingleMerchant
506
+ ? SingleMerchantApp<Config>
507
+ : Config['distribution'] extends AppDistribution.AppStore
508
+ ? AppStoreApp<Config>
509
+ : AppStoreApp<Config>;
@@ -0,0 +1,30 @@
1
+ import {SessionNotFoundError, shopifyApp} from '../../../index';
2
+ import {
3
+ TEST_SHOP,
4
+ setUpValidSession,
5
+ testConfig,
6
+ expectAdminApiClient,
7
+ } from '../../../__test-helpers';
8
+
9
+ describe('unauthenticated admin context', () => {
10
+ it('throws an error if there is no offline session for the shop', async () => {
11
+ // GIVEN
12
+ const shopify = shopifyApp(testConfig());
13
+
14
+ // EXPECT
15
+ await expect(shopify.unauthenticated.admin(TEST_SHOP)).rejects.toThrow(
16
+ SessionNotFoundError,
17
+ );
18
+ });
19
+
20
+ expectAdminApiClient(async () => {
21
+ const shopify = shopifyApp(testConfig());
22
+ const expectedSession = await setUpValidSession(shopify.sessionStorage, {
23
+ isOnline: false,
24
+ });
25
+ const {admin, session: actualSession} =
26
+ await shopify.unauthenticated.admin(TEST_SHOP);
27
+
28
+ return {admin, expectedSession, actualSession};
29
+ });
30
+ });
@@ -0,0 +1,29 @@
1
+ import {ShopifyRestResources} from '@shopify/shopify-api';
2
+
3
+ import {SessionNotFoundError} from '../../errors';
4
+ import {BasicParams} from '../../types';
5
+ import {adminClientFactory} from '../../clients/admin';
6
+ import {getOfflineSession} from '../helpers';
7
+
8
+ import {UnauthenticatedAdminContext} from './types';
9
+
10
+ export function unauthenticatedAdminContextFactory<
11
+ Resources extends ShopifyRestResources,
12
+ >(params: BasicParams) {
13
+ return async (
14
+ shop: string,
15
+ ): Promise<UnauthenticatedAdminContext<Resources>> => {
16
+ const session = await getOfflineSession(shop, params);
17
+
18
+ if (!session) {
19
+ throw new SessionNotFoundError(
20
+ `Could not find a session for shop ${shop} when creating unauthenticated admin context`,
21
+ );
22
+ }
23
+
24
+ return {
25
+ session,
26
+ admin: adminClientFactory<Resources>({params, session}),
27
+ };
28
+ };
29
+ }
@@ -0,0 +1 @@
1
+ export * from './factory';
@@ -0,0 +1,117 @@
1
+ import {Session, ShopifyRestResources} from '@shopify/shopify-api';
2
+
3
+ import {AdminApiContext} from '../../clients';
4
+
5
+ export interface UnauthenticatedAdminContext<
6
+ Resources extends ShopifyRestResources,
7
+ > {
8
+ /**
9
+ * The session for the given shop.
10
+ *
11
+ * This comes from the session storage which `shopifyApp` uses to store sessions in your database of choice.
12
+ *
13
+ * This will always be an offline session. You can use to get shop-specific data.
14
+ *
15
+ * @example
16
+ * <caption>Using the offline session.</caption>
17
+ * <description>Get your app's shop-specific data using the returned offline `session` object.</description>
18
+ * ```ts
19
+ * // /app/routes/**\/*.ts
20
+ * import { LoaderFunctionArgs, json } from "@remix-run/node";
21
+ * import { unauthenticated } from "../shopify.server";
22
+ * import { getMyAppData } from "~/db/model.server";
23
+ *
24
+ * export const loader = async ({ request }: LoaderFunctionArgs) => {
25
+ * const shop = getShopFromExternalRequest(request);
26
+ * const { session } = await unauthenticated.admin(shop);
27
+ * return json(await getMyAppData({shop: session.shop));
28
+ * };
29
+ * ```
30
+ */
31
+ session: Session;
32
+
33
+ /**
34
+ * Methods for interacting with the GraphQL / REST Admin APIs for the given store.
35
+ *
36
+ * @example
37
+ * <caption>Performing a GET request to the REST API.</caption>
38
+ * <description>Use `admin.rest.get` to make custom requests to make a request to to the `customer/count` endpoint</description>
39
+ *
40
+ * ```ts
41
+ * // /app/routes/**\/*.ts
42
+ * import { LoaderFunctionArgs, json } from "@remix-run/node";
43
+ * import { unauthenticated } from "../shopify.server";
44
+ *
45
+ * export const loader = async ({ request }: LoaderFunctionArgs) => {
46
+ * const { admin, session } = await unauthenticated.admin(request);
47
+ *
48
+ * const response = await admin.rest.get(
49
+ * {
50
+ * path: "/customers/count.json"
51
+ * }
52
+ * );
53
+ * const customers = await response.json();
54
+ *
55
+ * return json({ customers });
56
+ * };
57
+ * ```
58
+ *
59
+ * ```ts
60
+ * // /app/shopify.server.ts
61
+ * import { shopifyApp } from "@shopify/shopify-app-remix/server";
62
+ * import { restResources } from "@shopify/shopify-api/rest/admin/2023-04";
63
+ *
64
+ * const shopify = shopifyApp({
65
+ * restResources,
66
+ * // ...etc
67
+ * });
68
+ *
69
+ * export default shopify;
70
+ * export const unauthenticated = shopify.unauthenticated;
71
+ * ```
72
+ * @example
73
+ * <caption>Querying the GraphQL API.</caption>
74
+ * <description>Use `admin.graphql` to make query / mutation requests.</description>
75
+ * ```ts
76
+ * // /app/routes/**\/*.ts
77
+ * import { ActionFunctionArgs } from "@remix-run/node";
78
+ * import { unauthenticated } from "../shopify.server";
79
+ *
80
+ * export async function action({ request }: ActionFunctionArgs) {
81
+ * const { admin } = await unauthenticated.admin(request);
82
+ *
83
+ * const response = await admin.graphql(
84
+ * `#graphql
85
+ * mutation populateProduct($input: ProductInput!) {
86
+ * productCreate(input: $input) {
87
+ * product {
88
+ * id
89
+ * }
90
+ * }
91
+ * }`,
92
+ * { variables: { input: { title: "Product Name" } } }
93
+ * );
94
+ *
95
+ * const productData = await response.json();
96
+ * return json({ data: productData.data });
97
+ * }
98
+ * ```
99
+ *
100
+ * ```ts
101
+ * // /app/shopify.server.ts
102
+ * import { shopifyApp } from "@shopify/shopify-app-remix/server";
103
+ *
104
+ * const shopify = shopifyApp({
105
+ * restResources,
106
+ * // ...etc
107
+ * });
108
+ * export default shopify;
109
+ * export const unauthenticated = shopify.unauthenticated;
110
+ * ```
111
+ */
112
+ admin: AdminApiContext<Resources>;
113
+ }
114
+
115
+ export type GetUnauthenticatedAdminContext<
116
+ Resources extends ShopifyRestResources,
117
+ > = (shop: string) => Promise<UnauthenticatedAdminContext<Resources>>;