{"version":3,"sources":["jsdelivr-header.js","/npm/@storecraft/core@1.3.0/index.js"],"names":[],"mappings":"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","file":"/npm/@storecraft/core@1.3.0/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@storecraft/core@1.3.0/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/** \n * @import { ENV, StorecraftConfig } from \"./types.public.js\";\n * @import { OrderData } from \"./api/types.public.js\";\n * @import { storage_driver } from \"./storage/types.public.js\";\n * @import { db_driver } from \"./database/types.public.js\";\n * @import { payment_gateway } from \"./payments/types.public.js\";\n * @import { extension } from \"./extensions/types.public.js\";\n * @import { \n *  InferPlatformContext, InferPlatformNativeRequest, \n *  InferPlatformNativeResponse, PlatformAdapter \n * } from \"./platform/types.public.js\";\n * @import { mailer } from \"./mailer/types.public.js\";\n * @import { tax_provider } from \"./tax/types.public.js\";\n * @import { \n *  events, PayloadForUpsert, PubSubEvent, \n *  PubSubSubscriber \n * } from \"./pubsub/types.public.js\";\n * @import { ChatAI, VectorStore } from \"./ai/core/types.private.js\";\n * @import { Agent } from \"./ai/agents/types.js\";\n * @import { AuthProvider } from \"./auth/types.js\";\n * @import { OmitAppBuild, InitializedStorecraftApp } from \"./types.public.js\";\n */\nimport { create_rest_api } from './rest/index.js';\nimport { create_api } from './api/index.js'\nimport { PubSub } from './pubsub/index.js';\nimport { UniformTaxes } from './tax/public.js';\nexport * from './api/types.api.enums.js'\nimport pkg from './package.json' with { type: \"json\" }\nimport { \n  NotificationsExtension \n} from './extensions/notifications/index.js';\nimport { StoreAgent } from './ai/agents/index.js';\nimport { \n  save_collection, save_discount, \n  save_product, save_shipping_method \n} from './ai/models/vector-stores/index.js';\nimport { assert } from './api/utils.func.js';\n\n/**\n * @typedef {{\n *  'notifications'?: NotificationsExtension,\n * }} BaseExtensions\n */\n\n/**\n * @typedef {{\n *  'store'?: StoreAgent<any>,\n* }} BaseAgents\n */\n\n/**\n * @description This is the main `storecraft` **App**\n * @template {PlatformAdapter} [Platform=PlatformAdapter]\n * @template {db_driver} [Database=db_driver]\n * @template {storage_driver} [Storage=storage_driver]\n * @template {mailer} [Mailer=mailer]\n * @template {Record<string, payment_gateway>} [PaymentMap=Record<string, payment_gateway>] \n * `payments` map type\n * @template {Record<string, extension<any>>} [ExtensionsMap=(Record<string, extension<any>> & BaseExtensions)]\n * `extensions` map type\n * @template {tax_provider} [Taxes=tax_provider]\n * @template {ChatAI} [AiProvider=ChatAI]\n * @template {VectorStore} [VectorStoreProvider=VectorStore]\n * @template {Record<string, Agent>} [AgentsMap=(Record<string, Agent> & BaseAgents)]\n * @template {Record<string, AuthProvider>} [AuthProvidersMap=Record<string, AuthProvider>]\n */\nexport class App {\n\n  /** @satisfies {ENV<StorecraftConfig>} */\n  static EnvConfig = /** @type{const} */ ({\n    auth_admins_emails: 'SC_AUTH_ADMIN_EMAILS',\n    auth_secret_access_token: 'SC_AUTH_SECRET_ACCESS_TOKEN',\n    auth_secret_refresh_token: 'SC_AUTH_SECRET_REFRESH_TOKEN',\n    auth_secret_forgot_password_token: 'SC_AUTH_SECRET_FORGOT_PASSWORD_TOKEN',\n    auth_secret_confirm_email_token: 'SC_AUTH_SECRET_CONFIRM_EMAIL_TOKEN',\n    checkout_reserve_stock_on: 'SC_CHECKOUT_RESERVE_STOCK_ON',\n    general_confirm_email_base_url: 'SC_GENERAL_STORE_CONFIRM_EMAIL_BASE_URL',\n    general_forgot_password_confirm_base_url: 'SC_GENERAL_STORE_FORGOT_PASSWORD_CONFIRM_BASE_URL',\n    general_store_description: 'SC_GENERAL_STORE_DESCRIPTION',\n    general_store_logo_url: 'SC_GENERAL_STORE_LOGO_URL',\n    general_store_name: 'SC_GENERAL_STORE_NAME',\n    general_store_support_email: 'SC_GENERAL_STORE_SUPPORT_EMAIL',\n    general_store_website: 'SC_GENERAL_STORE_WEBSITE',\n    storage_rewrite_urls: 'SC_STORAGE_REWRITE_URLS'\n  });\n\n  /** \n   * @type {Platform} \n   */\n  #platform;\n\n  /** \n   * @type {AgentsMap} \n   */\n  #agents;\n\n  /** \n   * @type {AiProvider} \n   */\n  #ai_chat_provider;\n\n  /**\n   * @type {AuthProvidersMap}\n   */\n  #auth_providers;\n\n  /** \n   * @type {VectorStoreProvider} \n   */\n  #vector_store;\n  \n  /** \n   * @description The private database driver\n   * @type {Database} \n   */ \n  #db_driver;\n\n  /** \n   * @description The private storage driver\n   * @type {Storage} \n   */ \n  #storage;\n\n  /** \n   * @description The mailer driver\n   * @type {Mailer} \n   */ \n  #mailer;\n\n  /** \n   * @description The taxes driver\n   * @type {Taxes} \n   */ \n  #taxes;\n\n  /** \n   * @description The payment gateways\n   * @type {PaymentMap} \n   */ \n  #payment_gateways;\n\n  /** \n   * @description The extensions\n   * @type {ExtensionsMap} \n   */ \n  #extensions;\n\n  /**\n   * @description The app's pubsub system\n   * @type {PubSub<App>}\n   */\n  #pubsub;\n\n  /** \n   * @description The Storecraft App Config\n   * @type {StorecraftConfig} \n   */ \n  #config;\n\n  /** \n   * @description The REST API controller\n   * @type {ReturnType<typeof create_rest_api>} \n   */ \n  #rest_controller;\n\n  /** \n   * @description Flag for app is ready \n   * @type {boolean} \n   */ \n  #is_ready;\n\n  /** @type {number} */\n  #ms_init_start;\n\n  /**\n   * @param {StorecraftConfig} [config] config The Storecraft Application config\n   */\n  constructor(\n    config={}\n  ) {\n    this.#ms_init_start = Date.now();\n    this.#config = config;\n    this.#is_ready = false;\n    // @ts-ignore\n    this.#taxes = new UniformTaxes(0);\n    // @ts-ignore\n    this.#extensions = {\n      'notifications': new NotificationsExtension()\n    }\n    \n    // @ts-ignore\n    this.#pubsub = new PubSub(this);\n    \n    // add extra events for orders state\n    this.#pubsub.on(\n      'orders/upsert',\n      async (event) => {\n        const order_before = event.payload.previous;\n        const order_after = event.payload.current;\n\n        // test if the checkout now has turned complete\n        const has_checkout_updated = (\n          order_before?.status?.checkout?.id!==order_after.status.checkout.id\n        );\n\n        const has_fulfillment_updated = (\n          order_before?.status?.fulfillment?.id!==order_after.status.fulfillment.id\n        );\n\n        const has_payment_updated = (\n          order_before?.status?.payment?.id!==order_after.status.payment.id\n        );\n\n        /** @type {PayloadForUpsert<OrderData>} */\n        const payload = {\n          previous: order_before,\n          current: order_after\n        }\n\n        // console.log('from app', event.payload.current.status)\n        // console.log('has_checkout_updated', has_checkout_updated)\n\n        if(has_checkout_updated) {\n          await this.#pubsub.dispatch(\n            `orders/checkout/${order_after.status.checkout.name2}`,\n            payload\n          );\n          await this.#pubsub.dispatch('orders/checkout/update', payload);\n        }\n\n        if(has_fulfillment_updated) {\n          await this.#pubsub.dispatch(\n            `orders/fulfillment/${order_after.status.fulfillment.name2}`,\n            payload\n          );\n          await this.#pubsub.dispatch('orders/fulfillment/update', payload);\n        }\n\n        if(has_payment_updated) {\n          await this.#pubsub.dispatch(\n            `orders/payments/${order_after.status.payment.name2}`,\n            payload\n          );\n          await this.#pubsub.dispatch('orders/payments/update', payload);\n        }\n      }\n    );\n\n  } \n\n  /**\n   * @description After init, we inspect for missing config values and try to \n   * find them in platform environment.\n   */\n  #settle_config_after_init() {\n    if(!this.#platform) {\n      throw new Error('Storecraft:: No Platform Found !!')\n    }\n\n    const env = this.#platform.env;\n\n    this.#config = {\n      auth_secret_access_token: env?.[App.EnvConfig.auth_secret_access_token],\n      auth_secret_refresh_token: env?.[App.EnvConfig.auth_secret_refresh_token],\n      auth_secret_confirm_email_token: env?.[App.EnvConfig.auth_secret_confirm_email_token],\n      auth_secret_forgot_password_token: env?.[App.EnvConfig.auth_secret_forgot_password_token],\n      auth_admins_emails: env?.[App.EnvConfig.auth_admins_emails]?.split(',')\n        .map(s => s.trim()).filter(Boolean) ?? [],\n      checkout_reserve_stock_on: (/** @type {StorecraftConfig[\"checkout_reserve_stock_on\"]} */(\n        env?.[App.EnvConfig.checkout_reserve_stock_on])) ?? 'never',\n      storage_rewrite_urls: env?.[App.EnvConfig.storage_rewrite_urls],\n      general_store_name: env?.[App.EnvConfig.general_store_name],\n      general_store_website: env?.[App.EnvConfig.general_store_website],\n      general_store_description: env?.[App.EnvConfig.general_store_description],\n      general_store_support_email: env?.[App.EnvConfig.general_store_support_email],\n      general_store_logo_url: env?.[App.EnvConfig.general_store_logo_url],\n      general_confirm_email_base_url: env?.[App.EnvConfig.general_confirm_email_base_url],\n      general_forgot_password_confirm_base_url: env?.[\n        App.EnvConfig.general_forgot_password_confirm_base_url\n      ],\n      dashboard_version: pkg.version,\n      chat_version: pkg.version,\n      ...this.#config,\n    }\n\n    assert(\n      this.#config.auth_secret_access_token,\n      'Storecraft:: Missing `auth_secret_access_token`'\n    );\n    assert(\n      this.#config.auth_secret_refresh_token,\n      'Storecraft:: Missing `auth_secret_refresh_token`'\n    );\n    assert(\n      this.#config.auth_secret_confirm_email_token,\n      'Storecraft:: Missing `auth_secret_confirm_email_token`'\n    );\n    assert(\n      this.#config.auth_secret_forgot_password_token,\n      'Storecraft:: Missing `auth_secret_forgot_password_token`'\n    );\n    assert(\n      this.#config.auth_admins_emails?.length,\n      'Storecraft:: Missing admin emails'\n    );\n\n  } \n\n  /**\n   * @description Initialize the Application\n   * @param {boolean} [print_banner=true] \n   * @returns {InitializedStorecraftApp<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  init(print_banner=false) {\n    if(this.isready) \n      return this;\n    \n    try{\n      // first let's settle config\n      this.#settle_config_after_init();\n\n      // settle database\n      this.#db_driver?.init?.(this);\n\n      // settle storage\n      this.#storage?.init?.(this);\n\n      // settle programmatic API\n      // we do not cast the app here, because we need to pass the original\n      // object to the API for some typescript tricks later.\n      this.api = create_api(this);\n\n      // settle REST-API\n      this.#rest_controller = create_rest_api(\n        this, this.#config\n      );\n  \n      // settle extensions\n      for(const ext_handle in this.#extensions) {\n        const ext = this.#extensions?.[ext_handle];\n        ext?.onInit?.(this);\n      }\n\n      // settle payment gateways\n      for(const handle in this.#payment_gateways) {\n        const gateway = this.#payment_gateways?.[handle];\n        gateway?.onInit?.(this);\n      }\n\n      // settle ai provider\n      if(this.#ai_chat_provider) {\n        this.#ai_chat_provider.onInit(this);\n      }\n\n      // settle base agents\n      if(this.#ai_chat_provider) {\n        // @ts-ignore\n        this.withAgents({\n          store: new StoreAgent({\n            chat_ai_provider: this.#ai_chat_provider\n          })\n        });\n\n        for(const handle in this.#agents) {\n          const ag = this.#agents[handle];\n          ag?.init?.(this);\n        }\n      }\n  \n      // settle payment gateways\n      for(const handle in this.#auth_providers) {\n        const ap = this.#auth_providers[handle];\n        ap?.init?.(this);\n      }\n\n      // settle vector store events\n      if(this.#vector_store) {\n        this.#vector_store.onInit(this);\n        this.#vector_store?.embedder?.onInit(this);\n        this.#pubsub.on(\n          'products/upsert',\n          async (evt) => {\n            await save_product(\n              evt.payload.current, this.#vector_store\n            );\n          }\n        );\n\n        this.#pubsub.on(\n          'collections/upsert',\n          async (evt) => {\n            await save_collection(\n              evt.payload.current, this.#vector_store\n            );\n          }\n        );\n\n        this.#pubsub.on(\n          'discounts/upsert',\n          async (evt) => {\n            await save_discount(\n              evt.payload.current, this.#vector_store\n            );\n          }\n        );\n\n        this.#pubsub.on(\n          'shipping/upsert',\n          async (evt) => {\n            await save_shipping_method(\n              evt.payload.current, this.#vector_store\n            );\n          }\n        );\n\n      }\n\n      // settle mailer\n      this.#mailer?.onInit?.(this);\n  \n      this.#is_ready = true;\n\n    } catch (e) {\n      this.#is_ready = false;\n\n      // console.log(e);\n      \n      throw e;\n    } finally {\n      print_banner && this.print_banner();\n    }\n    return this;\n  }\n\n  /** \n   * @description Update new payment gateways and rewrite types \n   * @template {PlatformAdapter} P\n   * @param {P} platform \n   * @returns {OmitAppBuild<App<\n   *  P, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withPlatform(platform) {\n    // @ts-ignore\n    this.#platform = platform;\n\n    // @ts-ignore\n    return this;\n  } \n\n  /** \n   * @description Update **AI** chat provider, some of the builtins\n   * @template {ChatAI} P\n   * @param {P} ai \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, P, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withAI(ai) {\n    // @ts-ignore\n    this.#ai_chat_provider = ai;\n\n    // @ts-ignore\n    return this;\n  } \n\n  /** \n   * @description Update `agents`\n   * @template {Record<string, Agent>} P\n   * @param {P} agents \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, VectorStoreProvider, P & BaseAgents\n   *  >>\n   * }\n   */\n  withAgents(agents) {\n    // @ts-ignore\n    this.#agents = {\n      ...(this.#agents ?? {}),\n      ...agents\n    };\n\n    // @ts-ignore\n    return this;\n  } \n  \n  /** \n   * @description Update new payment gateways and rewrite types \n   * @template {VectorStore} P\n   * @param {P} store \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, P, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withVectorStore(store) {\n    // @ts-ignore\n    this.#vector_store = store;\n\n    // @ts-ignore\n    return this;\n  } \n\n  /** \n   * @description Update new payment gateways and rewrite types \n   * @template {db_driver} D\n   * @param {D} database \n   * @returns {OmitAppBuild<App<\n   *  Platform, D, Storage, Mailer, PaymentMap, ExtensionsMap, Taxes, \n   *  AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withDatabase(database) {\n    // @ts-ignore\n    this.#db_driver = database;\n    // @ts-ignore\n    return this;\n  }   \n\n  /** \n   * @description Update new payment gateways and rewrite types \n   * @template {storage_driver} S\n   * @param {S} storage \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, S, Mailer, PaymentMap, ExtensionsMap, Taxes, \n   *  AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withStorage(storage) {\n    // @ts-ignore\n    this.#storage = storage;\n    // @ts-ignore\n    return this;\n  }   \n\n  /** \n   * @description Update new payment gateways and rewrite types \n   * @template {mailer} M\n   * @param {M} mailer \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, M, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withMailer(mailer) {\n    // @ts-ignore\n    this.#mailer = mailer;\n    // @ts-ignore\n    return this;\n  }   \n\n  /** \n   * @description Update new tax provider\n   * @template {tax_provider} T\n   * @param {T} taxes \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  T, AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withTaxes(taxes) {\n    // @ts-ignore\n    this.#taxes = taxes;\n    // @ts-ignore\n    return this;\n  }\n\n  /** \n   * @description Add payment gateways\n   * @template {Record<string, payment_gateway>} N\n   * @param {N} gateways \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, N, ExtensionsMap, Taxes, \n   *  AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withPaymentGateways(gateways) { \n    // @ts-ignore\n    this.#payment_gateways = gateways; \n    // @ts-ignore\n    return this;\n  }\n\n  /** \n   * @description Add custom extensions\n   * @template {Record<string, extension>} E\n   * @param {E} extensions \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, E & BaseExtensions, \n   *  Taxes, AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  withExtensions(extensions) { \n    // @ts-ignore\n    this.#extensions = {\n      ...this.#extensions,\n      ...extensions\n    }; \n    // @ts-ignore\n    return this;\n  }\n\n  /** \n   * @description Add Auth Providers for social login\n   * @template {Record<string, AuthProvider>} A\n   * @param {A} providers \n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, VectorStoreProvider, AgentsMap, A\n   *  >>\n   * }\n   */\n  withAuthProviders(providers) { \n    // @ts-ignore\n    this.#auth_providers = providers;\n    // @ts-ignore\n    return this;\n  }\n\n  /**\n   * @description Subscribe to a `storecraft` event\n   * @template {PubSubEvent | string} [E=PubSubEvent]\n   * @param {E} event\n   * @param {E extends PubSubEvent ? \n   *  PubSubSubscriber<events[E]> : \n   *  PubSubSubscriber<any>\n   * } callback\n   * @returns {OmitAppBuild<App<\n   *  Platform, Database, Storage, Mailer, PaymentMap, ExtensionsMap, \n   *  Taxes, AiProvider, VectorStoreProvider, AgentsMap, AuthProvidersMap\n   *  >>\n   * }\n   */\n  on = (event, callback) => {\n    this.#pubsub.on(event, callback);\n    return this;\n  }\n\n  /**\n   * @description Get the app's entire resources\n   * objects. Using this is not recommended, but it can be useful.\n   * using the database directly, for example, will not validate\n   * types with zod and the pubsub system will not be used.\n   * Use it to exploit the full power of the app.\n   */\n  get __show_me_everything() {\n    return {\n      app: this,\n      auth_providers: this.#auth_providers,\n      rest_controller: this.#rest_controller,\n      agents: this.#agents,\n      ai_chat_provider: this.#ai_chat_provider,\n      vector_store: this.#vector_store,\n      platform: this.#platform,\n      db: this.#db_driver,\n      storage: this.#storage,\n      mailer: this.#mailer,\n      taxes: this.#taxes,\n      gateways: this.#payment_gateways,\n      extensions: this.#extensions,\n      pubsub: this.#pubsub,\n      config: this.#config,\n    }\n  }\n\n  /**\n   * @description Get the app's entire resources\n   * objects. Using this is not recommended, but it can be useful.\n   * using the database directly, for example, will not validate\n   * types with zod and the pubsub system will not be used.\n   * Use it to exploit the full power of the app.\n   */\n  get _() {\n    return this.__show_me_everything;\n  }\n\n  /**\n   * @description Get `storecraft` app public information\n   */\n  get info() {\n    return {\n      core_version: pkg.version,\n      dashboard_default_version: this.#config.dashboard_version,\n      chat_default_version: this.#config.chat_version,\n      store_description: this.#config.general_store_description,\n      store_name: this.#config.general_store_name,\n      store_website: this.#config.general_store_website,\n      store_support_email: this.#config.general_store_support_email,\n      store_logo_url: this.#config.general_store_logo_url,\n      confirm_email_base_url: this.#config.general_confirm_email_base_url,\n      forgot_password_confirm_base_url: \n        this.#config.general_forgot_password_confirm_base_url,\n    }\n  }\n\n  print_banner(host='', version=(pkg.version ?? 'unknown-version')) {\n    const banner3 = '   _______________  ____  ______   __________  ___    ____________\\r\\n  \\/ ___\\/_  __\\/ __ \\\\\\/ __ \\\\\\/ ____\\/  \\/ ____\\/ __ \\\\\\/   |  \\/ ____\\/_  __\\/\\r\\n  \\\\__ \\\\ \\/ \\/ \\/ \\/ \\/ \\/ \\/_\\/ \\/ __\\/    \\/ \\/   \\/ \\/_\\/ \\/ \\/| | \\/ \\/_    \\/ \\/   \\r\\n ___\\/ \\/\\/ \\/ \\/ \\/_\\/ \\/ _, _\\/ \\/___   \\/ \\/___\\/ _, _\\/ ___ |\\/ __\\/   \\/ \\/    \\r\\n\\/____\\/\\/_\\/  \\\\____\\/_\\/ |_\\/_____\\/   \\\\____\\/_\\/ |_\\/_\\/  |_\\/_\\/     \\/_\\/     \\r\\n                                                                  '\n    const c = {\n      red: '\\x1b[1;31m',\n      magenta: `\\x1b[1;35m`,\n      yellow: `\\x1b[33m`,\n      reset: `\\x1b[0m`,\n    }\n  \n    let final = c.magenta + '\\n';\n    final += banner3;\n    final += `${c.red}\\nv${version}`\n    final += `\\n\n${c.reset + c.yellow}⟡ ${c.reset + c.red}Dashboard       ${c.reset + host}/dashboard    \n${c.reset + c.yellow}⟡ ${c.reset + c.red}AI Chat ✨      ${c.reset + host}/chat    \n${c.reset + c.yellow}⟡ ${c.reset + c.red}API Reference   ${c.reset + host}/api    \n${c.reset + c.yellow}⟡ ${c.reset + c.red}Website         ${c.reset}https://storecraft.app\n${c.reset + c.yellow}⟡ ${c.reset + c.red}GitHub          ${c.reset}https://github.com/store-craft/storecraft ⭐\n${c.yellow}⭑ ${c.reset + c.yellow}Statistics      ${c.reset}initialized in ${(Date.now() - this.#ms_init_start)}ms\n      `;\n\n    console.log(final);\n  }\n\n  /** \n   * @description Pub-Sub `events` module \n   */\n  get pubsub() { \n    return this.#pubsub; \n  }\n\n  /** \n   * @description Config \n   */\n  get config() { \n    return this.#config; \n  }\n\n  /**\n   * @description The app's platform environment variables\n   */\n  get env() {\n    return this.#platform?.env;\n  }\n\n  /**\n   * @description Is the app ready ?\n   */\n  get isready() { \n    return this.#is_ready; \n  }\n\n  /**\n   * @description Process a native platform request with \n   * context and pass it to the `rest-api` controller. \n   * This can be used in\n   * \n   * - `Node.createServer(..)` as handler\n   * - `Deno.serve(..)` as handler\n   * - `Bun.serve(..)` as handler\n   * - `GoogleFunctions` as handler\n   * - `Cloudflare Workers` as handler\n   * - `AWS API Gateway` as handler\n   * @param {InferPlatformNativeRequest<Platform>} native_request \n   * native platform `request` object\n   * @param {InferPlatformContext<Platform>} [context] \n   * (Optional )extra context object. \n   * In `node.js` for example, this is the `ServerReponse` object.\n   * @returns {Promise<InferPlatformNativeResponse<Platform>>}\n   */\n  handler = async (native_request, context) => {\n    // @ts-ignore\n    context = context ?? {};\n    const request = await this.#platform.encode(native_request, context);\n    const response_web = await this.#rest_controller.handler(request);\n    const response = await this.#platform.handleResponse(\n      response_web, context\n    );\n    return response;\n  }\n\n}\n"]}