Description
Symfony version(s) affected
6.4-RC1
Description
It seems there is a case that is not resolved properly by the JsDelivrEsmResolver
resolver, found in a project using @supabase/supabase-js
➜ https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2.38.4/+esm
How to reproduce
In a project using the AssetMapper component:
symfony console importmap:require @supabase/supabase-js
in your app.js
:
import { createClient } from '@supabase/supabase-js';
createClient('***', '***');
You'll get an error in your browser console:
GET http://localhost:15889/npm/@supabase/node-fetch@2.6.15/+esm net::ERR_ABORTED 404 (Not Found)
Possible Solution
The JsDelivrEsmResolver::IMPORT_REGEX
regex might be fixed to handle this module properly, by supporting import i,{Headers as a}from"/npm/@supabase/node-fetch@2.6.14/+esm"
- public const IMPORT_REGEX = '#(?:import\s*(?:(?:\{[^}]*\}|\w+|\*\s*as\s+\w+)\s*\bfrom\s*)?|export\s*(?:\{[^}]*\}|\*)\s*from\s*)("/npm/((?:@[^/]+/)?[^@]+?)(?:@([^/]+))?((?:/[^/]+)*?)/\+esm")#';
+ public const IMPORT_REGEX = '#(?:import\s*(?:\w+,)?(?:(?:\{[^}]*\}|\w+|\*\s*as\s+\w+)\s*\bfrom\s*)?|export\s*(?:\{[^}]*\}|\*)\s*from\s*)("/npm/((?:@[^/]+/)?[^@]+?)(?:@([^/]+))?((?:/[^/]+)*?)/\+esm")#';
The resulting file currently is:
/**
* Bundled by jsDelivr using Rollup v2.79.1 and Terser v5.19.2.
* Original file: /npm/@supabase/supabase-js@2.38.4/dist/module/index.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
import{FunctionsClient as e}from"@supabase/functions-js";export{FunctionsError,FunctionsFetchError,FunctionsHttpError,FunctionsRelayError}from"@supabase/functions-js";import{PostgrestClient as t}from"@supabase/postgrest-js";import{RealtimeClient as s}from"@supabase/realtime-js";export*from"@supabase/realtime-js";import{StorageClient as n}from"@supabase/storage-js";import i,{Headers as a}from"/npm/@supabase/node-fetch@2.6.15/+esm";import{GoTrueClient as r}from"@supabase/gotrue-js";export*from"@supabase/gotrue-js";let o="";o="undefined"!=typeof Deno?"deno":"undefined"!=typeof document?"web":"undefined"!=typeof navigator&&"ReactNative"===navigator.product?"react-native":"node";const h={"X-Client-Info":`supabase-js-${o}/2.38.4`};var u=function(e,t,s,n){return new(s||(s=Promise))((function(i,a){function r(e){try{h(n.next(e))}catch(e){a(e)}}function o(e){try{h(n.throw(e))}catch(e){a(e)}}function h(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,o)}h((n=n.apply(e,t||[])).next())}))};const l=e=>{let t;return t=e||("undefined"==typeof fetch?i:fetch),(...e)=>t(...e)},c=(e,t,s)=>{const n=l(s),i="undefined"==typeof Headers?a:Headers;return(s,a)=>u(void 0,void 0,void 0,(function*(){var r;const o=null!==(r=yield t())&&void 0!==r?r:e;let h=new i(null==a?void 0:a.headers);return h.has("apikey")||h.set("apikey",e),h.has("Authorization")||h.set("Authorization",`Bearer ${o}`),n(s,Object.assign(Object.assign({},a),{headers:h}))}))};class d extends r{constructor(e){super(e)}}var p=function(e,t,s,n){return new(s||(s=Promise))((function(i,a){function r(e){try{h(n.next(e))}catch(e){a(e)}}function o(e){try{h(n.throw(e))}catch(e){a(e)}}function h(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,o)}h((n=n.apply(e,t||[])).next())}))};const m={headers:h},f={schema:"public"},g={autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!0,flowType:"implicit"},b={};class v{constructor(e,s,n){var i,a,r,o,h,u,l,d;if(this.supabaseUrl=e,this.supabaseKey=s,!e)throw new Error("supabaseUrl is required.");if(!s)throw new Error("supabaseKey is required.");const p=e.replace(/\/$/,"");this.realtimeUrl=`${p}/realtime/v1`.replace(/^http/i,"ws"),this.authUrl=`${p}/auth/v1`,this.storageUrl=`${p}/storage/v1`,this.functionsUrl=`${p}/functions/v1`;const v=`sb-${new URL(this.authUrl).hostname.split(".")[0]}-auth-token`,y=function(e,t){const{db:s,auth:n,realtime:i,global:a}=e,{db:r,auth:o,realtime:h,global:u}=t;return{db:Object.assign(Object.assign({},r),s),auth:Object.assign(Object.assign({},o),n),realtime:Object.assign(Object.assign({},h),i),global:Object.assign(Object.assign({},u),a)}}(null!=n?n:{},{db:f,realtime:b,auth:Object.assign(Object.assign({},g),{storageKey:v}),global:m});this.storageKey=null!==(a=null===(i=y.auth)||void 0===i?void 0:i.storageKey)&&void 0!==a?a:"",this.headers=null!==(o=null===(r=y.global)||void 0===r?void 0:r.headers)&&void 0!==o?o:{},this.auth=this._initSupabaseAuthClient(null!==(h=y.auth)&&void 0!==h?h:{},this.headers,null===(u=y.global)||void 0===u?void 0:u.fetch),this.fetch=c(s,this._getAccessToken.bind(this),null===(l=y.global)||void 0===l?void 0:l.fetch),this.realtime=this._initRealtimeClient(Object.assign({headers:this.headers},y.realtime)),this.rest=new t(`${p}/rest/v1`,{headers:this.headers,schema:null===(d=y.db)||void 0===d?void 0:d.schema,fetch:this.fetch}),this._listenForAuthEvents()}get functions(){return new e(this.functionsUrl,{headers:this.headers,customFetch:this.fetch})}get storage(){return new n(this.storageUrl,this.headers,this.fetch)}from(e){return this.rest.from(e)}schema(e){return this.rest.schema(e)}rpc(e,t={},s){return this.rest.rpc(e,t,s)}channel(e,t={config:{}}){return this.realtime.channel(e,t)}getChannels(){return this.realtime.getChannels()}removeChannel(e){return this.realtime.removeChannel(e)}removeAllChannels(){return this.realtime.removeAllChannels()}_getAccessToken(){var e,t;return p(this,void 0,void 0,(function*(){const{data:s}=yield this.auth.getSession();return null!==(t=null===(e=s.session)||void 0===e?void 0:e.access_token)&&void 0!==t?t:null}))}_initSupabaseAuthClient({autoRefreshToken:e,persistSession:t,detectSessionInUrl:s,storage:n,storageKey:i,flowType:a,debug:r},o,h){const u={Authorization:`Bearer ${this.supabaseKey}`,apikey:`${this.supabaseKey}`};return new d({url:this.authUrl,headers:Object.assign(Object.assign({},u),o),storageKey:i,autoRefreshToken:e,persistSession:t,detectSessionInUrl:s,storage:n,flowType:a,debug:r,fetch:h})}_initRealtimeClient(e){return new s(this.realtimeUrl,Object.assign(Object.assign({},e),{params:Object.assign({apikey:this.supabaseKey},null==e?void 0:e.params)}))}_listenForAuthEvents(){return this.auth.onAuthStateChange(((e,t)=>{this._handleTokenChanged(e,"CLIENT",null==t?void 0:t.access_token)}))}_handleTokenChanged(e,t,s){"TOKEN_REFRESHED"!==e&&"SIGNED_IN"!==e||this.changedAccessToken===s?"SIGNED_OUT"===e&&(this.realtime.setAuth(this.supabaseKey),"STORAGE"==t&&this.auth.signOut(),this.changedAccessToken=void 0):(this.realtime.setAuth(null!=s?s:null),this.changedAccessToken=s)}}const y=(e,t,s)=>new v(e,t,s);export{v as SupabaseClient,y as createClient};export default null;
Caution
Note this part:
import i,{Headers as a}from"/npm/@supabase/node-fetch@2.6.15/+esm"
which seems not to be resolved properly and leads to the browser trying to fetch the module from http://localhost:15889/npm/@supabase/n
84D8
ode-fetch@2.6.15/+esm
➜ I guess it should have been parsed and transformed to
import i,{Headers as a}from"@supabase/node-fetch"
as for the other imports in this file (but the i,{Headers as a}
notation is not handled correctly by the regex).
Additional Context
Here is the generated importmap.php
file:
importmap.php
return [
'app' => [
'path' => './assets/app.js',
'entrypoint' => true,
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
'@symfony/stimulus-bundle' => [
'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
],
'@supabase/supabase-js' => [
'version' => '2.38.4',
],
'@supabase/functions-js' => [
'version' => '2.1.5',
],
'@supabase/postgrest-js' => [
'version' => '1.8.5',
],
'@supabase/realtime-js' => [
'version' => '2.8.4',
],
'@supabase/storage-js' => [
'version' => '2.5.4',
],
'@supabase/gotrue-js' => [
'version' => '2.57.0',
],
'@supabase/node-fetch' => [
'version' => '2.6.14',
],
'websocket' => [
'version' => '1.0.34',
],
];
and the resulting installed.php
file:
installed.php
<?php return array (
'@hotwired/stimulus' =>
array (
'version' => '3.2.2',
'dependencies' =>
array (
),
),
'@supabase/supabase-js' =>
array (
'version' => '2.38.4',
'dependencies' =>
array (
0 => '@supabase/functions-js',
1 => '@supabase/functions-js',
2 => '@supabase/postgrest-js',
3 => '@supabase/realtime-js',
4 => '@supabase/realtime-js',
5 => '@supabase/storage-js',
6 => '@supabase/gotrue-js',
7 => '@supabase/gotrue-js',
),
),
'@supabase/functions-js' =>
array (
'version' => '2.1.5',
'dependencies' =>
array (
),
),
'@supabase/postgrest-js' =>
array (
'version' => '1.8.5',
'dependencies' =>
array (
0 => '@supabase/node-fetch',
),
),
'@supabase/realtime-js' =>
array (
'version' => '2.8.4',
'dependencies' =>
array (
0 => 'websocket',
),
),
'@supabase/storage-js' =>
array (
'version' => '2.5.4',
'dependencies' =>
array (
),
),
'@supabase/gotrue-js' =>
array (
'version' => '2.57.0',
'dependencies' =>
array (
),
),
'@supabase/node-fetch' =>
array (
'version' => '2.6.14',
'dependencies' =>
array (
),
),
'websocket' =>
array (
'version' => '1.0.34',
'dependencies' =>
array (
),
),
);