hot-updater 0.5.7 → 0.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare const getSupabaseEnv: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const getPluginEnv: () => Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { SupabaseApi } from "@hot-updater/supabase";
2
+ export declare const selectOrCreateOrganization: () => Promise<void>;
3
+ export declare const selectProject: () => Promise<{
4
+ id: string;
5
+ name: string;
6
+ region: string;
7
+ }>;
8
+ export declare const selectBucket: (api: SupabaseApi) => Promise<string>;
package/dist/index.cjs CHANGED
@@ -15814,13 +15814,7 @@ var __webpack_exports__ = {};
15814
15814
  await databasePlugin.onUnmount?.();
15815
15815
  }
15816
15816
  };
15817
- const getPackageManager = ()=>{
15818
- const [packageManagerWithVersion] = process.env["npm_config_user_agent"]?.split(" ") ?? [];
15819
- if (!packageManagerWithVersion) return "npm";
15820
- const [packageManager] = packageManagerWithVersion.split("/");
15821
- if (!packageManager) return "npm";
15822
- return packageManager;
15823
- };
15817
+ const delay = (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
15824
15818
  function isPlainObject(value) {
15825
15819
  if ('object' != typeof value || null === value) return false;
15826
15820
  const prototype = Object.getPrototypeOf(value);
@@ -21841,112 +21835,6 @@ Instead, \`yield\` should either be called with a value, or not be called at all
21841
21835
  createExeca(mapNode);
21842
21836
  createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
21843
21837
  const { sendMessage: execa_sendMessage, getOneMessage: execa_getOneMessage, getEachMessage: execa_getEachMessage, getCancelSignal: execa_getCancelSignal } = getIpcExport();
21844
- const ensurePackageVersion = (pkg)=>{
21845
- if ("hot-updater" === pkg || pkg.startsWith("@hot-updater/")) return `${pkg}@${packageJson_version}`;
21846
- return pkg;
21847
- };
21848
- const ensureInstallPackages = async (buildPluginPackages)=>{
21849
- const packages = await readPackageUp({
21850
- cwd: (0, plugin_core_namespaceObject.getCwd)()
21851
- });
21852
- const dependenciesToInstall = buildPluginPackages.dependencies.filter((pkg)=>!packages?.packageJson?.dependencies?.[pkg]);
21853
- const devDependenciesToInstall = buildPluginPackages.devDependencies.filter((pkg)=>!packages?.packageJson?.devDependencies?.[pkg]);
21854
- const packageManager = getPackageManager();
21855
- await prompts_namespaceObject.tasks([
21856
- {
21857
- enabled: dependenciesToInstall.length > 0,
21858
- title: "Checking packages",
21859
- task: async (message)=>{
21860
- message(`Installing ${dependenciesToInstall.join(", ")}...`);
21861
- await execa(packageManager, [
21862
- "yarn" === packageManager ? "add" : "install",
21863
- ...dependenciesToInstall.map(ensurePackageVersion),
21864
- "yarn" === packageManager ? "--dev" : "--save-dev"
21865
- ]);
21866
- return `Installed ${dependenciesToInstall.join(", ")}`;
21867
- }
21868
- },
21869
- {
21870
- enabled: devDependenciesToInstall.length > 0,
21871
- title: "Installing dev dependencies",
21872
- task: async (message)=>{
21873
- message(`Installing ${devDependenciesToInstall.join(", ")}...`);
21874
- await execa(packageManager, [
21875
- "yarn" === packageManager ? "add" : "install",
21876
- ...devDependenciesToInstall.map(ensurePackageVersion),
21877
- "yarn" === packageManager ? "--dev" : "--save-dev"
21878
- ]);
21879
- return `Installed ${devDependenciesToInstall.join(", ")}`;
21880
- }
21881
- }
21882
- ]);
21883
- };
21884
- const delay = (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
21885
- const makeEnv = async (newEnvVars, filePath = ".env")=>{
21886
- try {
21887
- const existingContent = await promises_default().readFile(filePath, "utf-8").catch(()=>"");
21888
- const lines = existingContent.split("\n");
21889
- const envVars = new Map();
21890
- const updatedLines = [];
21891
- for (const line of lines){
21892
- const trimmedLine = line.trim();
21893
- if (!trimmedLine || trimmedLine.startsWith("#")) updatedLines.push(line);
21894
- else {
21895
- const [key, ...rest] = line.split("=");
21896
- const value = rest.join("=");
21897
- if (key) {
21898
- const trimmedKey = key.trim();
21899
- envVars.set(trimmedKey, value?.trim() ?? "");
21900
- updatedLines.push(`${trimmedKey}=${newEnvVars[trimmedKey] ?? value}`);
21901
- }
21902
- }
21903
- }
21904
- for (const [key, value] of Object.entries(newEnvVars))if (!envVars.has(key)) updatedLines.push(`${key}=${value}`);
21905
- const updatedContent = updatedLines.join("\n");
21906
- await promises_default().writeFile(filePath, updatedContent, "utf-8");
21907
- return updatedContent;
21908
- } catch (error) {
21909
- console.error("Error while updating .env file:", error);
21910
- throw error;
21911
- }
21912
- };
21913
- function transformTemplate(templateString, values) {
21914
- let result = templateString;
21915
- for(const key in values){
21916
- const placeholder = `%%${key}%%`;
21917
- result = result.replace(new RegExp(placeholder, "g"), values[key]);
21918
- }
21919
- return result;
21920
- }
21921
- const CONFIG_TEMPLATE = `
21922
- import { metro } from "@hot-updater/metro";
21923
- import { supabaseDatabase, supabaseStorage } from "@hot-updater/supabase";
21924
- import { defineConfig } from "hot-updater";
21925
- import "dotenv/config";
21926
-
21927
- export default defineConfig({
21928
- build: metro(),
21929
- storage: supabaseStorage({
21930
- supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
21931
- supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
21932
- bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!,
21933
- }),
21934
- database: supabaseDatabase({
21935
- supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
21936
- supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
21937
- }),
21938
- });
21939
- `;
21940
- const SOURCE_TEMPLATE = `// add this to your App.tsx
21941
- import { HotUpdater } from "@hot-updater/react-native";
21942
-
21943
- function App() {
21944
- return ...
21945
- }
21946
-
21947
- export default HotUpdater.wrap({
21948
- source: "%%source%%",
21949
- })(App);`;
21950
21838
  const selectOrCreateOrganization = async ()=>{
21951
21839
  const confirmed = await prompts_namespaceObject.confirm({
21952
21840
  message: "Do you already have a Supabase organization?",
@@ -22084,6 +21972,177 @@ export default HotUpdater.wrap({
22084
21972
  }
22085
21973
  return selectedBucketId;
22086
21974
  };
21975
+ function transformTemplate(templateString, values) {
21976
+ let result = templateString;
21977
+ for(const key in values){
21978
+ const placeholder = `%%${key}%%`;
21979
+ result = result.replace(new RegExp(placeholder, "g"), values[key]);
21980
+ }
21981
+ return result;
21982
+ }
21983
+ const CONFIG_TEMPLATE = `
21984
+ HOT_UPDATER_SUPABASE_URL=%%HOT_UPDATER_SUPABASE_URL%%
21985
+ HOT_UPDATER_SUPABASE_ANON_KEY=%%HOT_UPDATER_SUPABASE_ANON_KEY%%
21986
+ HOT_UPDATER_SUPABASE_BUCKET_NAME=%%HOT_UPDATER_SUPABASE_BUCKET_NAME%%
21987
+ `;
21988
+ const getSupabaseEnv = async ()=>{
21989
+ const project = await selectProject();
21990
+ const spinner = prompts_namespaceObject.spinner();
21991
+ spinner.start(`Getting API keys for ${project.name}...`);
21992
+ let apiKeys = [];
21993
+ try {
21994
+ const keysProcess = await execa("npx", [
21995
+ "-y",
21996
+ "supabase",
21997
+ "projects",
21998
+ "api-keys",
21999
+ "--project-ref",
22000
+ project.id,
22001
+ "--output",
22002
+ "json"
22003
+ ]);
22004
+ apiKeys = JSON.parse(keysProcess.stdout ?? "[]");
22005
+ } catch (err) {
22006
+ spinner.stop();
22007
+ console.error("Failed to get API keys:", err);
22008
+ process.exit(1);
22009
+ }
22010
+ spinner.stop();
22011
+ const serviceRoleKey = apiKeys.find((key)=>"service_role" === key.name);
22012
+ if (!serviceRoleKey) throw new Error("Service role key not found");
22013
+ const { supabaseApi } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "@hot-updater/supabase"));
22014
+ const api = supabaseApi(`https://${project.id}.supabase.co`, serviceRoleKey.api_key);
22015
+ const bucketId = await selectBucket(api);
22016
+ prompts_namespaceObject.log.message(transformTemplate(CONFIG_TEMPLATE, {
22017
+ HOT_UPDATER_SUPABASE_ANON_KEY: serviceRoleKey.api_key,
22018
+ HOT_UPDATER_SUPABASE_BUCKET_NAME: bucketId,
22019
+ HOT_UPDATER_SUPABASE_URL: `https://${project.id}.supabase.co`
22020
+ }));
22021
+ prompts_namespaceObject.outro("Please use these values for reference only and manage them through .env file.");
22022
+ };
22023
+ const getPluginEnv = async ()=>{
22024
+ printBanner();
22025
+ const provider = await (0, prompts_namespaceObject.select)({
22026
+ message: "Select a provider",
22027
+ options: [
22028
+ {
22029
+ value: "supabase",
22030
+ label: "Supabase"
22031
+ }
22032
+ ]
22033
+ });
22034
+ if ((0, prompts_namespaceObject.isCancel)(provider)) process.exit(0);
22035
+ switch(provider){
22036
+ case "supabase":
22037
+ await getSupabaseEnv();
22038
+ break;
22039
+ default:
22040
+ throw new Error("Invalid provider");
22041
+ }
22042
+ };
22043
+ const getPackageManager = ()=>{
22044
+ const [packageManagerWithVersion] = process.env["npm_config_user_agent"]?.split(" ") ?? [];
22045
+ if (!packageManagerWithVersion) return "npm";
22046
+ const [packageManager] = packageManagerWithVersion.split("/");
22047
+ if (!packageManager) return "npm";
22048
+ return packageManager;
22049
+ };
22050
+ const ensurePackageVersion = (pkg)=>{
22051
+ if ("hot-updater" === pkg || pkg.startsWith("@hot-updater/")) return `${pkg}@${packageJson_version}`;
22052
+ return pkg;
22053
+ };
22054
+ const ensureInstallPackages = async (buildPluginPackages)=>{
22055
+ const packages = await readPackageUp({
22056
+ cwd: (0, plugin_core_namespaceObject.getCwd)()
22057
+ });
22058
+ const dependenciesToInstall = buildPluginPackages.dependencies.filter((pkg)=>!packages?.packageJson?.dependencies?.[pkg]);
22059
+ const devDependenciesToInstall = buildPluginPackages.devDependencies.filter((pkg)=>!packages?.packageJson?.devDependencies?.[pkg]);
22060
+ const packageManager = getPackageManager();
22061
+ await prompts_namespaceObject.tasks([
22062
+ {
22063
+ enabled: dependenciesToInstall.length > 0,
22064
+ title: "Checking packages",
22065
+ task: async (message)=>{
22066
+ message(`Installing ${dependenciesToInstall.join(", ")}...`);
22067
+ await execa(packageManager, [
22068
+ "yarn" === packageManager ? "add" : "install",
22069
+ ...dependenciesToInstall.map(ensurePackageVersion)
22070
+ ]);
22071
+ return `Installed ${dependenciesToInstall.join(", ")}`;
22072
+ }
22073
+ },
22074
+ {
22075
+ enabled: devDependenciesToInstall.length > 0,
22076
+ title: "Installing dev dependencies",
22077
+ task: async (message)=>{
22078
+ message(`Installing ${devDependenciesToInstall.join(", ")}...`);
22079
+ await execa(packageManager, [
22080
+ "yarn" === packageManager ? "add" : "install",
22081
+ ...devDependenciesToInstall.map(ensurePackageVersion),
22082
+ "yarn" === packageManager ? "--dev" : "--save-dev"
22083
+ ]);
22084
+ return `Installed ${devDependenciesToInstall.join(", ")}`;
22085
+ }
22086
+ }
22087
+ ]);
22088
+ };
22089
+ const makeEnv = async (newEnvVars, filePath = ".env")=>{
22090
+ try {
22091
+ const existingContent = await promises_default().readFile(filePath, "utf-8").catch(()=>"");
22092
+ const lines = existingContent.split("\n");
22093
+ const envVars = new Map();
22094
+ const updatedLines = [];
22095
+ for (const line of lines){
22096
+ const trimmedLine = line.trim();
22097
+ if (!trimmedLine || trimmedLine.startsWith("#")) updatedLines.push(line);
22098
+ else {
22099
+ const [key, ...rest] = line.split("=");
22100
+ const value = rest.join("=");
22101
+ if (key) {
22102
+ const trimmedKey = key.trim();
22103
+ envVars.set(trimmedKey, value?.trim() ?? "");
22104
+ updatedLines.push(`${trimmedKey}=${newEnvVars[trimmedKey] ?? value}`);
22105
+ }
22106
+ }
22107
+ }
22108
+ for (const [key, value] of Object.entries(newEnvVars))if (!envVars.has(key)) updatedLines.push(`${key}=${value}`);
22109
+ const updatedContent = updatedLines.join("\n");
22110
+ await promises_default().writeFile(filePath, updatedContent, "utf-8");
22111
+ return updatedContent;
22112
+ } catch (error) {
22113
+ console.error("Error while updating .env file:", error);
22114
+ throw error;
22115
+ }
22116
+ };
22117
+ const initSupabase_CONFIG_TEMPLATE = `
22118
+ import { metro } from "@hot-updater/metro";
22119
+ import { supabaseDatabase, supabaseStorage } from "@hot-updater/supabase";
22120
+ import { defineConfig } from "hot-updater";
22121
+ import "dotenv/config";
22122
+
22123
+ export default defineConfig({
22124
+ build: metro(),
22125
+ storage: supabaseStorage({
22126
+ supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
22127
+ supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
22128
+ bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!,
22129
+ }),
22130
+ database: supabaseDatabase({
22131
+ supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
22132
+ supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
22133
+ }),
22134
+ });
22135
+ `;
22136
+ const SOURCE_TEMPLATE = `// add this to your App.tsx
22137
+ import { HotUpdater } from "@hot-updater/react-native";
22138
+
22139
+ function App() {
22140
+ return ...
22141
+ }
22142
+
22143
+ export default HotUpdater.wrap({
22144
+ source: "%%source%%",
22145
+ })(App);`;
22087
22146
  const linkSupabase = async (supabasePath, projectId)=>{
22088
22147
  const spinner = prompts_namespaceObject.spinner();
22089
22148
  spinner.start("Linking Supabase...");
@@ -22193,13 +22252,14 @@ export default HotUpdater.wrap({
22193
22252
  await linkSupabase(supabasePath, project.id);
22194
22253
  await pushDB(supabasePath);
22195
22254
  await deployEdgeFunction(supabasePath, project.id);
22196
- await promises_default().writeFile("hot-updater.config.ts", CONFIG_TEMPLATE);
22255
+ await promises_default().writeFile("hot-updater.config.ts", initSupabase_CONFIG_TEMPLATE);
22197
22256
  await makeEnv({
22198
22257
  HOT_UPDATER_SUPABASE_ANON_KEY: serviceRoleKey.api_key,
22199
22258
  HOT_UPDATER_SUPABASE_BUCKET_NAME: bucketId,
22200
22259
  HOT_UPDATER_SUPABASE_URL: `https://${project.id}.supabase.co`
22201
22260
  });
22202
- prompts_namespaceObject.log.success("Generated hot-updater.config.ts with Supabase settings.");
22261
+ prompts_namespaceObject.log.success("Generated '.env' file with Supabase settings.");
22262
+ prompts_namespaceObject.log.success("Generated 'hot-updater.config.ts' file with Supabase settings.");
22203
22263
  prompts_namespaceObject.note(transformTemplate(SOURCE_TEMPLATE, {
22204
22264
  source: `https://${project.id}.supabase.co/functions/v1/update-server`
22205
22265
  }));
@@ -22236,10 +22296,10 @@ export default HotUpdater.wrap({
22236
22296
  options: [
22237
22297
  {
22238
22298
  value: {
22239
- dependencies: [
22299
+ dependencies: [],
22300
+ devDependencies: [
22240
22301
  "@hot-updater/metro"
22241
- ],
22242
- devDependencies: []
22302
+ ]
22243
22303
  },
22244
22304
  label: "Metro"
22245
22305
  }
@@ -22318,6 +22378,7 @@ export default HotUpdater.wrap({
22318
22378
  const program = new external_commander_namespaceObject.Command();
22319
22379
  program.name("hot-updater").description(banner).version(packageJson_version);
22320
22380
  program.command("init").description("Initialize Hot Updater").action(init_init);
22381
+ program.command("get-plugin-env").description("Get the environment variables for the plugin").action(getPluginEnv);
22321
22382
  program.command("deploy").description("deploy a new version").addOption(new external_commander_namespaceObject.Option("-p, --platform <platform>", "specify the platform").choices([
22322
22383
  "ios",
22323
22384
  "android"
package/dist/index.js CHANGED
@@ -15717,13 +15717,7 @@ const deploy = async (options)=>{
15717
15717
  await databasePlugin.onUnmount?.();
15718
15718
  }
15719
15719
  };
15720
- const getPackageManager = ()=>{
15721
- const [packageManagerWithVersion] = process.env["npm_config_user_agent"]?.split(" ") ?? [];
15722
- if (!packageManagerWithVersion) return "npm";
15723
- const [packageManager] = packageManagerWithVersion.split("/");
15724
- if (!packageManager) return "npm";
15725
- return packageManager;
15726
- };
15720
+ const delay = (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
15727
15721
  function isPlainObject(value) {
15728
15722
  if ('object' != typeof value || null === value) return false;
15729
15723
  const prototype = Object.getPrototypeOf(value);
@@ -21738,112 +21732,6 @@ createExeca(mapCommandSync);
21738
21732
  createExeca(mapNode);
21739
21733
  createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
21740
21734
  const { sendMessage: execa_sendMessage, getOneMessage: execa_getOneMessage, getEachMessage: execa_getEachMessage, getCancelSignal: execa_getCancelSignal } = getIpcExport();
21741
- const ensurePackageVersion = (pkg)=>{
21742
- if ("hot-updater" === pkg || pkg.startsWith("@hot-updater/")) return `${pkg}@${packageJson_version}`;
21743
- return pkg;
21744
- };
21745
- const ensureInstallPackages = async (buildPluginPackages)=>{
21746
- const packages = await readPackageUp({
21747
- cwd: (0, __WEBPACK_EXTERNAL_MODULE__hot_updater_plugin_core__.getCwd)()
21748
- });
21749
- const dependenciesToInstall = buildPluginPackages.dependencies.filter((pkg)=>!packages?.packageJson?.dependencies?.[pkg]);
21750
- const devDependenciesToInstall = buildPluginPackages.devDependencies.filter((pkg)=>!packages?.packageJson?.devDependencies?.[pkg]);
21751
- const packageManager = getPackageManager();
21752
- await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.tasks([
21753
- {
21754
- enabled: dependenciesToInstall.length > 0,
21755
- title: "Checking packages",
21756
- task: async (message)=>{
21757
- message(`Installing ${dependenciesToInstall.join(", ")}...`);
21758
- await execa(packageManager, [
21759
- "yarn" === packageManager ? "add" : "install",
21760
- ...dependenciesToInstall.map(ensurePackageVersion),
21761
- "yarn" === packageManager ? "--dev" : "--save-dev"
21762
- ]);
21763
- return `Installed ${dependenciesToInstall.join(", ")}`;
21764
- }
21765
- },
21766
- {
21767
- enabled: devDependenciesToInstall.length > 0,
21768
- title: "Installing dev dependencies",
21769
- task: async (message)=>{
21770
- message(`Installing ${devDependenciesToInstall.join(", ")}...`);
21771
- await execa(packageManager, [
21772
- "yarn" === packageManager ? "add" : "install",
21773
- ...devDependenciesToInstall.map(ensurePackageVersion),
21774
- "yarn" === packageManager ? "--dev" : "--save-dev"
21775
- ]);
21776
- return `Installed ${devDependenciesToInstall.join(", ")}`;
21777
- }
21778
- }
21779
- ]);
21780
- };
21781
- const delay = (ms)=>new Promise((resolve)=>setTimeout(resolve, ms));
21782
- const makeEnv = async (newEnvVars, filePath = ".env")=>{
21783
- try {
21784
- const existingContent = await __WEBPACK_EXTERNAL_MODULE_fs_promises__["default"].readFile(filePath, "utf-8").catch(()=>"");
21785
- const lines = existingContent.split("\n");
21786
- const envVars = new Map();
21787
- const updatedLines = [];
21788
- for (const line of lines){
21789
- const trimmedLine = line.trim();
21790
- if (!trimmedLine || trimmedLine.startsWith("#")) updatedLines.push(line);
21791
- else {
21792
- const [key, ...rest] = line.split("=");
21793
- const value = rest.join("=");
21794
- if (key) {
21795
- const trimmedKey = key.trim();
21796
- envVars.set(trimmedKey, value?.trim() ?? "");
21797
- updatedLines.push(`${trimmedKey}=${newEnvVars[trimmedKey] ?? value}`);
21798
- }
21799
- }
21800
- }
21801
- for (const [key, value] of Object.entries(newEnvVars))if (!envVars.has(key)) updatedLines.push(`${key}=${value}`);
21802
- const updatedContent = updatedLines.join("\n");
21803
- await __WEBPACK_EXTERNAL_MODULE_fs_promises__["default"].writeFile(filePath, updatedContent, "utf-8");
21804
- return updatedContent;
21805
- } catch (error) {
21806
- console.error("Error while updating .env file:", error);
21807
- throw error;
21808
- }
21809
- };
21810
- function transformTemplate(templateString, values) {
21811
- let result = templateString;
21812
- for(const key in values){
21813
- const placeholder = `%%${key}%%`;
21814
- result = result.replace(new RegExp(placeholder, "g"), values[key]);
21815
- }
21816
- return result;
21817
- }
21818
- const CONFIG_TEMPLATE = `
21819
- import { metro } from "@hot-updater/metro";
21820
- import { supabaseDatabase, supabaseStorage } from "@hot-updater/supabase";
21821
- import { defineConfig } from "hot-updater";
21822
- import "dotenv/config";
21823
-
21824
- export default defineConfig({
21825
- build: metro(),
21826
- storage: supabaseStorage({
21827
- supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
21828
- supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
21829
- bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!,
21830
- }),
21831
- database: supabaseDatabase({
21832
- supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
21833
- supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
21834
- }),
21835
- });
21836
- `;
21837
- const SOURCE_TEMPLATE = `// add this to your App.tsx
21838
- import { HotUpdater } from "@hot-updater/react-native";
21839
-
21840
- function App() {
21841
- return ...
21842
- }
21843
-
21844
- export default HotUpdater.wrap({
21845
- source: "%%source%%",
21846
- })(App);`;
21847
21735
  const selectOrCreateOrganization = async ()=>{
21848
21736
  const confirmed = await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.confirm({
21849
21737
  message: "Do you already have a Supabase organization?",
@@ -21981,6 +21869,177 @@ const selectBucket = async (api)=>{
21981
21869
  }
21982
21870
  return selectedBucketId;
21983
21871
  };
21872
+ function transformTemplate(templateString, values) {
21873
+ let result = templateString;
21874
+ for(const key in values){
21875
+ const placeholder = `%%${key}%%`;
21876
+ result = result.replace(new RegExp(placeholder, "g"), values[key]);
21877
+ }
21878
+ return result;
21879
+ }
21880
+ const CONFIG_TEMPLATE = `
21881
+ HOT_UPDATER_SUPABASE_URL=%%HOT_UPDATER_SUPABASE_URL%%
21882
+ HOT_UPDATER_SUPABASE_ANON_KEY=%%HOT_UPDATER_SUPABASE_ANON_KEY%%
21883
+ HOT_UPDATER_SUPABASE_BUCKET_NAME=%%HOT_UPDATER_SUPABASE_BUCKET_NAME%%
21884
+ `;
21885
+ const getSupabaseEnv = async ()=>{
21886
+ const project = await selectProject();
21887
+ const spinner = __WEBPACK_EXTERNAL_MODULE__clack_prompts__.spinner();
21888
+ spinner.start(`Getting API keys for ${project.name}...`);
21889
+ let apiKeys = [];
21890
+ try {
21891
+ const keysProcess = await execa("npx", [
21892
+ "-y",
21893
+ "supabase",
21894
+ "projects",
21895
+ "api-keys",
21896
+ "--project-ref",
21897
+ project.id,
21898
+ "--output",
21899
+ "json"
21900
+ ]);
21901
+ apiKeys = JSON.parse(keysProcess.stdout ?? "[]");
21902
+ } catch (err) {
21903
+ spinner.stop();
21904
+ console.error("Failed to get API keys:", err);
21905
+ process.exit(1);
21906
+ }
21907
+ spinner.stop();
21908
+ const serviceRoleKey = apiKeys.find((key)=>"service_role" === key.name);
21909
+ if (!serviceRoleKey) throw new Error("Service role key not found");
21910
+ const { supabaseApi } = await import("@hot-updater/supabase");
21911
+ const api = supabaseApi(`https://${project.id}.supabase.co`, serviceRoleKey.api_key);
21912
+ const bucketId = await selectBucket(api);
21913
+ __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.message(transformTemplate(CONFIG_TEMPLATE, {
21914
+ HOT_UPDATER_SUPABASE_ANON_KEY: serviceRoleKey.api_key,
21915
+ HOT_UPDATER_SUPABASE_BUCKET_NAME: bucketId,
21916
+ HOT_UPDATER_SUPABASE_URL: `https://${project.id}.supabase.co`
21917
+ }));
21918
+ __WEBPACK_EXTERNAL_MODULE__clack_prompts__.outro("Please use these values for reference only and manage them through .env file.");
21919
+ };
21920
+ const getPluginEnv = async ()=>{
21921
+ printBanner();
21922
+ const provider = await (0, __WEBPACK_EXTERNAL_MODULE__clack_prompts__.select)({
21923
+ message: "Select a provider",
21924
+ options: [
21925
+ {
21926
+ value: "supabase",
21927
+ label: "Supabase"
21928
+ }
21929
+ ]
21930
+ });
21931
+ if ((0, __WEBPACK_EXTERNAL_MODULE__clack_prompts__.isCancel)(provider)) process.exit(0);
21932
+ switch(provider){
21933
+ case "supabase":
21934
+ await getSupabaseEnv();
21935
+ break;
21936
+ default:
21937
+ throw new Error("Invalid provider");
21938
+ }
21939
+ };
21940
+ const getPackageManager = ()=>{
21941
+ const [packageManagerWithVersion] = process.env["npm_config_user_agent"]?.split(" ") ?? [];
21942
+ if (!packageManagerWithVersion) return "npm";
21943
+ const [packageManager] = packageManagerWithVersion.split("/");
21944
+ if (!packageManager) return "npm";
21945
+ return packageManager;
21946
+ };
21947
+ const ensurePackageVersion = (pkg)=>{
21948
+ if ("hot-updater" === pkg || pkg.startsWith("@hot-updater/")) return `${pkg}@${packageJson_version}`;
21949
+ return pkg;
21950
+ };
21951
+ const ensureInstallPackages = async (buildPluginPackages)=>{
21952
+ const packages = await readPackageUp({
21953
+ cwd: (0, __WEBPACK_EXTERNAL_MODULE__hot_updater_plugin_core__.getCwd)()
21954
+ });
21955
+ const dependenciesToInstall = buildPluginPackages.dependencies.filter((pkg)=>!packages?.packageJson?.dependencies?.[pkg]);
21956
+ const devDependenciesToInstall = buildPluginPackages.devDependencies.filter((pkg)=>!packages?.packageJson?.devDependencies?.[pkg]);
21957
+ const packageManager = getPackageManager();
21958
+ await __WEBPACK_EXTERNAL_MODULE__clack_prompts__.tasks([
21959
+ {
21960
+ enabled: dependenciesToInstall.length > 0,
21961
+ title: "Checking packages",
21962
+ task: async (message)=>{
21963
+ message(`Installing ${dependenciesToInstall.join(", ")}...`);
21964
+ await execa(packageManager, [
21965
+ "yarn" === packageManager ? "add" : "install",
21966
+ ...dependenciesToInstall.map(ensurePackageVersion)
21967
+ ]);
21968
+ return `Installed ${dependenciesToInstall.join(", ")}`;
21969
+ }
21970
+ },
21971
+ {
21972
+ enabled: devDependenciesToInstall.length > 0,
21973
+ title: "Installing dev dependencies",
21974
+ task: async (message)=>{
21975
+ message(`Installing ${devDependenciesToInstall.join(", ")}...`);
21976
+ await execa(packageManager, [
21977
+ "yarn" === packageManager ? "add" : "install",
21978
+ ...devDependenciesToInstall.map(ensurePackageVersion),
21979
+ "yarn" === packageManager ? "--dev" : "--save-dev"
21980
+ ]);
21981
+ return `Installed ${devDependenciesToInstall.join(", ")}`;
21982
+ }
21983
+ }
21984
+ ]);
21985
+ };
21986
+ const makeEnv = async (newEnvVars, filePath = ".env")=>{
21987
+ try {
21988
+ const existingContent = await __WEBPACK_EXTERNAL_MODULE_fs_promises__["default"].readFile(filePath, "utf-8").catch(()=>"");
21989
+ const lines = existingContent.split("\n");
21990
+ const envVars = new Map();
21991
+ const updatedLines = [];
21992
+ for (const line of lines){
21993
+ const trimmedLine = line.trim();
21994
+ if (!trimmedLine || trimmedLine.startsWith("#")) updatedLines.push(line);
21995
+ else {
21996
+ const [key, ...rest] = line.split("=");
21997
+ const value = rest.join("=");
21998
+ if (key) {
21999
+ const trimmedKey = key.trim();
22000
+ envVars.set(trimmedKey, value?.trim() ?? "");
22001
+ updatedLines.push(`${trimmedKey}=${newEnvVars[trimmedKey] ?? value}`);
22002
+ }
22003
+ }
22004
+ }
22005
+ for (const [key, value] of Object.entries(newEnvVars))if (!envVars.has(key)) updatedLines.push(`${key}=${value}`);
22006
+ const updatedContent = updatedLines.join("\n");
22007
+ await __WEBPACK_EXTERNAL_MODULE_fs_promises__["default"].writeFile(filePath, updatedContent, "utf-8");
22008
+ return updatedContent;
22009
+ } catch (error) {
22010
+ console.error("Error while updating .env file:", error);
22011
+ throw error;
22012
+ }
22013
+ };
22014
+ const initSupabase_CONFIG_TEMPLATE = `
22015
+ import { metro } from "@hot-updater/metro";
22016
+ import { supabaseDatabase, supabaseStorage } from "@hot-updater/supabase";
22017
+ import { defineConfig } from "hot-updater";
22018
+ import "dotenv/config";
22019
+
22020
+ export default defineConfig({
22021
+ build: metro(),
22022
+ storage: supabaseStorage({
22023
+ supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
22024
+ supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
22025
+ bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!,
22026
+ }),
22027
+ database: supabaseDatabase({
22028
+ supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
22029
+ supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
22030
+ }),
22031
+ });
22032
+ `;
22033
+ const SOURCE_TEMPLATE = `// add this to your App.tsx
22034
+ import { HotUpdater } from "@hot-updater/react-native";
22035
+
22036
+ function App() {
22037
+ return ...
22038
+ }
22039
+
22040
+ export default HotUpdater.wrap({
22041
+ source: "%%source%%",
22042
+ })(App);`;
21984
22043
  const linkSupabase = async (supabasePath, projectId)=>{
21985
22044
  const spinner = __WEBPACK_EXTERNAL_MODULE__clack_prompts__.spinner();
21986
22045
  spinner.start("Linking Supabase...");
@@ -22090,13 +22149,14 @@ const initSupabase = async ()=>{
22090
22149
  await linkSupabase(supabasePath, project.id);
22091
22150
  await pushDB(supabasePath);
22092
22151
  await deployEdgeFunction(supabasePath, project.id);
22093
- await __WEBPACK_EXTERNAL_MODULE_fs_promises__["default"].writeFile("hot-updater.config.ts", CONFIG_TEMPLATE);
22152
+ await __WEBPACK_EXTERNAL_MODULE_fs_promises__["default"].writeFile("hot-updater.config.ts", initSupabase_CONFIG_TEMPLATE);
22094
22153
  await makeEnv({
22095
22154
  HOT_UPDATER_SUPABASE_ANON_KEY: serviceRoleKey.api_key,
22096
22155
  HOT_UPDATER_SUPABASE_BUCKET_NAME: bucketId,
22097
22156
  HOT_UPDATER_SUPABASE_URL: `https://${project.id}.supabase.co`
22098
22157
  });
22099
- __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.success("Generated hot-updater.config.ts with Supabase settings.");
22158
+ __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.success("Generated '.env' file with Supabase settings.");
22159
+ __WEBPACK_EXTERNAL_MODULE__clack_prompts__.log.success("Generated 'hot-updater.config.ts' file with Supabase settings.");
22100
22160
  __WEBPACK_EXTERNAL_MODULE__clack_prompts__.note(transformTemplate(SOURCE_TEMPLATE, {
22101
22161
  source: `https://${project.id}.supabase.co/functions/v1/update-server`
22102
22162
  }));
@@ -22133,10 +22193,10 @@ const init_init = async ()=>{
22133
22193
  options: [
22134
22194
  {
22135
22195
  value: {
22136
- dependencies: [
22196
+ dependencies: [],
22197
+ devDependencies: [
22137
22198
  "@hot-updater/metro"
22138
- ],
22139
- devDependencies: []
22199
+ ]
22140
22200
  },
22141
22201
  label: "Metro"
22142
22202
  }
@@ -22214,6 +22274,7 @@ const prune = async ()=>{
22214
22274
  const program = new __WEBPACK_EXTERNAL_MODULE_commander__.Command();
22215
22275
  program.name("hot-updater").description(banner).version(packageJson_version);
22216
22276
  program.command("init").description("Initialize Hot Updater").action(init_init);
22277
+ program.command("get-plugin-env").description("Get the environment variables for the plugin").action(getPluginEnv);
22217
22278
  program.command("deploy").description("deploy a new version").addOption(new __WEBPACK_EXTERNAL_MODULE_commander__.Option("-p, --platform <platform>", "specify the platform").choices([
22218
22279
  "ios",
22219
22280
  "android"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hot-updater",
3
3
  "type": "module",
4
- "version": "0.5.7",
4
+ "version": "0.5.9",
5
5
  "bin": {
6
6
  "hot-updater": "./dist/index.js"
7
7
  },
@@ -39,9 +39,9 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@clack/prompts": "^0.9.0",
42
- "@hot-updater/console": "0.5.7",
43
- "@hot-updater/core": "0.5.7",
44
- "@hot-updater/plugin-core": "0.5.7",
42
+ "@hot-updater/console": "0.5.9",
43
+ "@hot-updater/core": "0.5.9",
44
+ "@hot-updater/plugin-core": "0.5.9",
45
45
  "commander": "^11.1.0",
46
46
  "cosmiconfig": "^9.0.0",
47
47
  "cosmiconfig-typescript-loader": "^5.0.0"