App Extension errors when trying to authenticate for Admin API

washingmachine
Shopify Partner
4 0 1

Hi all,

I built a Shopify app and extension using the CLI tool. The sample code works as intended (a product is created when clicking the button in the Admin dashboard) but I am unable to call the Admin API from my extension.

 

my-app/app/routes/app._index.jsx contains sample code that successfully calls the Admin API. When I copy the entire file exactly as is to my-app/extensions/post-purchase-ui/src/index.jsx (only modifying the relative import from import { authenticate } from "../shopify.server"; to import { authenticate } from "app/shopify.server";). I get errors. First, there was this:

$ shopify app dev
/my-app/node_modules/wrap-ansi/index.js:2
const stringWidth = require('string-width');
                    ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /my-app/node_modules/string-width/index.js from /my-app/node_modules/wrap-ansi/index.js not supported.
Instead change the require of /my-app/node_modules/string-width/index.js in /my-app/node_modules/wrap-ansi/index.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/my-app/node_modules/wrap-ansi/index.js:2:21) {
  code: 'ERR_REQUIRE_ESM'
}

Node.js v21.7.2

which went away after running yarn add string-width@v4.2.3 -W . But after that I got the following error:

    node_modules/@remix-run/node/dist/sessions/fileStorage.js:17:19:
      17 │ var path = require('node:path');
         ╵                    ~~~~~~~~~~~

  The package "node:path" wasn't found on the file system but is built into node. Are you trying to
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:crypto"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/sessions/fileStorage.js:15:21:
00:32:09 │ extensions │       15 │ var crypto = require('node:crypto');
00:32:09 │ extensions │          ╵                      ~~~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, 
which will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:fs"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/sessions/fileStorage.js:16:22:
00:32:09 │ extensions │       16 │ var node_fs = require('node:fs');
00:32:09 │ extensions │          ╵                       ~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which 
will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:path"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/sessions/fileStorage.js:17:19:
00:32:09 │ extensions │       17 │ var path = require('node:path');
00:32:09 │ extensions │          ╵                    ~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:path" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which
 will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:stream"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/stream.js:15:26:
00:32:09 │ extensions │       15 │ var node_stream = require('node:stream');
00:32:09 │ extensions │          ╵                           ~~~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:stream" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, 
which will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:crypto"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:15:21:
00:32:09 │ extensions │       15 │ var crypto = require('node:crypto');
00:32:09 │ extensions │          ╵                      ~~~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, 
which will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:fs"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:16:22:
00:32:09 │ extensions │       16 │ var node_fs = require('node:fs');
00:32:09 │ extensions │          ╵                       ~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which 
will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:fs/promises"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:17:23:
00:32:09 │ extensions │       17 │ var promises = require('node:fs/promises');
00:32:09 │ extensions │          ╵                        ~~~~~~~~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:fs/promises" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do 
that, which will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:os"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:18:22:
00:32:09 │ extensions │       18 │ var node_os = require('node:os');
00:32:09 │ extensions │          ╵                       ~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:os" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which 
will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:path"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:19:19:
00:32:09 │ extensions │       19 │ var path = require('node:path');
00:32:09 │ extensions │          ╵                    ~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:path" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which
 will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:stream"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:20:26:
00:32:09 │ extensions │       20 │ var node_stream = require('node:stream');
00:32:09 │ extensions │          ╵                           ~~~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:stream" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, 
which will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "node:util"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:21:24:
00:32:09 │ extensions │       21 │ var node_util = require('node:util');
00:32:09 │ extensions │          ╵                         ~~~~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "node:util" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which
 will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "crypto"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@remix-run/node/node_modules/cookie-signature/index.js:5:21:
00:32:09 │ extensions │       5 │ var crypto = require('crypto');
00:32:09 │ extensions │         ╵                      ~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which 
will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "crypto"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/@shopify/shopify-app-remix/build/cjs/server/adapters/node/index.js:3:21:
00:32:09 │ extensions │       3 │ var crypto = require('crypto');
00:32:09 │ extensions │         ╵                      ~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which 
will remove this error.
00:32:09 │ extensions │ 
00:32:09 │ extensions │ ✘ [ERROR] Could not resolve "stream"
00:32:09 │ extensions │ 
00:32:09 │ extensions │     node_modules/stream-slice/index.js:3:24:
00:32:09 │ extensions │       3 │ var Transform = require('stream').Transform;
00:32:09 │ extensions │         ╵                         ~~~~~~~~
00:32:09 │ extensions │ 
00:32:09 │ extensions │   The package "stream" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which 
will remove this error.

Error: Build failed with 14 errors:
 node_modules/@remix-run/node/dist/sessions/fileStorage.js:15:21: ERROR: Could not resolve "node:crypto"
 node_modules/@remix-run/node/dist/sessions/fileStorage.js:16:22: ERROR: Could not resolve "node:fs"
 node_modules/@remix-run/node/dist/sessions/fileStorage.js:17:19: ERROR: Could not resolve "node:path"
 node_modules/@remix-run/node/dist/stream.js:15:26: ERROR: Could not resolve "node:stream"
 node_modules/@remix-run/node/dist/upload/fileUploadHandler.js:15:21: ERROR: Could not resolve "node:crypto"
 ...

I've been trying to fix this for a couple hours now but have no clue how. I already tried installing the modules with yarn, setting build target to "node" in vite.config.js and adding the following to remix.config.js:

module.exports = {
serverNodeBuiltinsPolyfill: {
modules: {
crypto: true,
stream: true,
fs: true,
path: true,
"fs/promises": true,
os: true,
util: true,
}
},

but still get the same error.

 

Edit: Fixed it by deleting yarn.lock and node_modules and running yarn install. However, now I get

Uncaught (in promise) DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'ExtensionSandboxPostPurchase.latest.de.e953c1f6c2f63e67b5fd.worker.js'

which is triggered immediately when importing {authenticate} from "app/shopify.server";

Replies 3 (3)

Strydar
Shopify Partner
4 0 0

Hi @washingmachine, I'm stuck at the same place, were you able to fix it? If yes, It'll be great if you can add your solution to this thread.

 

washingmachine
Shopify Partner
4 0 1

Hi @Strydar , unfortunately I still have no idea why authenticate.admin doesn't work but sending HTTP requests to the admin API does work.

 

let response = await fetch(`https://${shopName}.myshopify.com/admin/api/${apiVersion}/graphql.json`, {
    method: "POST",
    headers: {
      "Content-Type": "application/graphql",
      "X-Shopify-Access-Token": <SHOPIFY-ACCESS-TOKEN>,
    },
    body: `query customers {
             customers(first: 5) {
               nodes {
                 addresses {
                   address1
                 }
               }
             }
           }`
  })

 

 HOWEVER, the Shopify-Access-Token, to my understanding (but I could be wrong), is not a permanent token and has to be regenerated every session. And I have no idea how to fetch the token during runtime (I only tried this request with a hardcoded token that I got after running npm run prisma studio). Moreover, I don't know how secure this approach is - I think anyone could see the access token upon inspection of the browser console (network requests)? Please let me know if you make any progress here!

Strydar
Shopify Partner
4 0 0

Hi @washingmachine , Is there any progress on this? 
I have some follow-up questions too:
1. Are you sending this HTTP request from index.jsx/tsx file in your extension or are you sending in through a route (i.e api-offers.jsx) 
2. Where can we get the access tokens from to send the request, is it the same as inputData.token?