refactor(updater): app update based own server
Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
parent
cff58df175
commit
c8c789f4fd
|
|
@ -0,0 +1,2 @@
|
|||
provider: custom
|
||||
channel: latest
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import { env } from "@follow/shared/env.desktop"
|
||||
import { createDesktopAPIHeaders } from "@follow/utils/headers"
|
||||
import { FollowClient } from "@follow-app/client-sdk"
|
||||
import PKG from "@pkg"
|
||||
import PKG, { mainHash, version as appVersion } from "@pkg"
|
||||
import { gte } from "semver"
|
||||
|
||||
import { BETTER_AUTH_COOKIE_NAME_SESSION_TOKEN } from "~/constants/app"
|
||||
import { WindowManager } from "~/manager/window"
|
||||
import { getCurrentRendererManifest } from "~/updater/hot-updater"
|
||||
|
||||
import { logger } from "../logger"
|
||||
|
||||
|
|
@ -20,13 +22,17 @@ export const followClient = new FollowClient({
|
|||
}),
|
||||
})
|
||||
|
||||
export const followApi = followClient.api
|
||||
export const apiClient = followClient.api
|
||||
|
||||
followClient.addRequestInterceptor(async (ctx) => {
|
||||
const { options } = ctx
|
||||
const header = options.headers || {}
|
||||
|
||||
const apiHeader = createDesktopAPIHeaders({ version: PKG.version })
|
||||
const rendererManifest = getCurrentRendererManifest()
|
||||
const rendererVersion = gte(rendererManifest?.version ?? appVersion, appVersion)
|
||||
? (rendererManifest?.version ?? appVersion)
|
||||
: appVersion
|
||||
|
||||
// Get cookies for authentication
|
||||
const window = WindowManager.getMainWindow()
|
||||
|
|
@ -44,10 +50,14 @@ followClient.addRequestInterceptor(async (ctx) => {
|
|||
...apiHeader,
|
||||
Cookie: headerCookie,
|
||||
"User-Agent": userAgent,
|
||||
|
||||
"X-Follow-Main-Hash": mainHash,
|
||||
"X-Follow-Renderer-Version": rendererVersion,
|
||||
"X-Follow-App-Version": appVersion,
|
||||
"X-Follow-Platform": process.platform,
|
||||
}
|
||||
return ctx
|
||||
})
|
||||
|
||||
followClient.addResponseInterceptor(({ response }) => {
|
||||
logger.info(`API Response: ${response.status} ${response.statusText}`)
|
||||
return response
|
||||
|
|
@ -67,14 +77,10 @@ followClient.addResponseInterceptor(async ({ response }) => {
|
|||
}
|
||||
|
||||
try {
|
||||
const json = await response.clone().json()
|
||||
logger.error("API Error details:", json)
|
||||
} catch {
|
||||
// ignore JSON parsing errors
|
||||
await response.clone().json()
|
||||
} catch (error) {
|
||||
logger.error("API Error details:", error)
|
||||
}
|
||||
|
||||
return response
|
||||
})
|
||||
|
||||
// Legacy export for compatibility
|
||||
export const apiClient = followApi
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import type { GetLatestReleaseQuery, LatestReleasePayload } from "@follow-app/client-sdk"
|
||||
|
||||
import { apiClient } from "~/lib/api-client"
|
||||
|
||||
let cachedLatestRelease: LatestReleasePayload | null = null
|
||||
|
||||
export const getUpdateInfo = async (
|
||||
query: GetLatestReleaseQuery = {},
|
||||
): Promise<LatestReleasePayload> => {
|
||||
const response = await apiClient.updates.getLatestRelease(query)
|
||||
cachedLatestRelease = response.data
|
||||
return cachedLatestRelease
|
||||
}
|
||||
|
||||
export const getCachedUpdateInfo = () => cachedLatestRelease
|
||||
|
|
@ -1,413 +0,0 @@
|
|||
// credits: migrated from https://github.com/toeverything/AFFiNE/blob/a802dc4fd6aa720f7a7a995816c78c0b24c514f5/packages/frontend/electron/src/main/updater/custom-github-provider.ts
|
||||
|
||||
import { URL } from "node:url"
|
||||
|
||||
import type {
|
||||
CustomPublishOptions,
|
||||
GithubOptions,
|
||||
ReleaseNoteInfo,
|
||||
XElement,
|
||||
} from "builder-util-runtime"
|
||||
import { HttpError, newError, parseXml } from "builder-util-runtime"
|
||||
import type { AppUpdater, ResolvedUpdateFileInfo, UpdateInfo } from "electron-updater"
|
||||
import { CancellationToken } from "electron-updater"
|
||||
import { BaseGitHubProvider } from "electron-updater/out/providers/GitHubProvider"
|
||||
import type { ProviderRuntimeOptions } from "electron-updater/out/providers/Provider"
|
||||
import { parseUpdateInfo, resolveFiles } from "electron-updater/out/providers/Provider"
|
||||
import * as semver from "semver"
|
||||
|
||||
import { isWindows } from "../env"
|
||||
import { githubProviderLogger as logger, logObject } from "./logger"
|
||||
import { isSquirrelBuild } from "./utils"
|
||||
|
||||
interface GithubUpdateInfo extends UpdateInfo {
|
||||
tag: string
|
||||
}
|
||||
|
||||
interface GithubRelease {
|
||||
id: number
|
||||
tag_name: string
|
||||
target_commitish: string
|
||||
name: string
|
||||
draft: boolean
|
||||
prerelease: boolean
|
||||
created_at: string
|
||||
published_at: string
|
||||
}
|
||||
|
||||
const hrefRegExp = /\/tag\/([^/]+)$/
|
||||
|
||||
export class CustomGitHubProvider extends BaseGitHubProvider<GithubUpdateInfo> {
|
||||
constructor(
|
||||
options: CustomPublishOptions,
|
||||
private readonly updater: AppUpdater,
|
||||
runtimeOptions: ProviderRuntimeOptions,
|
||||
) {
|
||||
super(options as unknown as GithubOptions, "github.com", runtimeOptions)
|
||||
}
|
||||
|
||||
async getLatestVersion(): Promise<GithubUpdateInfo> {
|
||||
logger.info("Starting getLatestVersion")
|
||||
logObject(logger, "Provider Configuration", {
|
||||
"Base URL": this.baseUrl.href,
|
||||
"Base Path": this.basePath,
|
||||
"Current Version": this.updater.currentVersion,
|
||||
"Allow Prerelease": this.updater.allowPrerelease,
|
||||
})
|
||||
|
||||
const cancellationToken = new CancellationToken()
|
||||
|
||||
const feedUrl = newUrlFromBase(`${this.basePath}.atom`, this.baseUrl)
|
||||
logger.info(`Fetching feed from: ${feedUrl.href}`)
|
||||
|
||||
const feedXml = await this.httpRequest(
|
||||
feedUrl,
|
||||
{
|
||||
accept: "application/xml, application/atom+xml, text/xml, */*",
|
||||
},
|
||||
cancellationToken,
|
||||
)
|
||||
|
||||
if (!feedXml) {
|
||||
throw new Error(`Cannot find feed in the remote server (${this.baseUrl.href})`)
|
||||
}
|
||||
|
||||
logger.info(`Feed fetched successfully, length: ${feedXml.length} bytes`)
|
||||
|
||||
const feed = parseXml(feedXml)
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
let latestRelease = feed.element("entry", false, `No published versions on GitHub`)
|
||||
let tag: string | null = null
|
||||
try {
|
||||
const currentChannel =
|
||||
this.options.channel ||
|
||||
this.updater?.channel ||
|
||||
(semver.prerelease(this.updater.currentVersion)?.[0] as string) ||
|
||||
null
|
||||
|
||||
logger.info(`Current Channel: ${currentChannel}`)
|
||||
|
||||
if (currentChannel === null) {
|
||||
throw newError(
|
||||
`Cannot parse channel from version: ${this.updater.currentVersion}`,
|
||||
"ERR_UPDATER_INVALID_VERSION",
|
||||
)
|
||||
}
|
||||
|
||||
logger.info(`Fetching latest tag by release API for channel: ${currentChannel}`)
|
||||
const releaseTag = await this.getLatestTagByRelease(currentChannel, cancellationToken)
|
||||
logger.info(`Release tag from API: ${releaseTag || "null (will use feed matching)"}`)
|
||||
logger.info("Iterating through feed entries to find matching release")
|
||||
let entryCount = 0
|
||||
for (const element of feed.getElements("entry")) {
|
||||
entryCount++
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
const href = element.element("link").attribute("href")
|
||||
const hrefElement = hrefRegExp.exec(href)
|
||||
|
||||
// If this is null then something is wrong and skip this release
|
||||
if (hrefElement === null) {
|
||||
logger.warn(`Entry #${entryCount}: Invalid href format: ${href}`)
|
||||
continue
|
||||
}
|
||||
|
||||
// This Release's Tag
|
||||
const hrefTag = decodeURIComponent(hrefElement[1]!)
|
||||
logger.debug(`Entry #${entryCount}: Processing tag: ${hrefTag}`)
|
||||
|
||||
// Get Channel from this release's tag
|
||||
// Handle new format: desktop/v1.2.3 or mobile/v1.2.3
|
||||
let hrefChannel = "stable"
|
||||
if (hrefTag.startsWith("desktop/")) {
|
||||
// For desktop tags, extract the version and check if it's a prerelease
|
||||
const version = hrefTag.replace("desktop/", "")
|
||||
hrefChannel = (semver.prerelease(version)?.[0] as string) || "stable"
|
||||
logger.debug(
|
||||
`Entry #${entryCount}: Desktop tag detected, version: ${version}, channel: ${hrefChannel}`,
|
||||
)
|
||||
} else if (hrefTag.startsWith("mobile/")) {
|
||||
// Skip mobile releases for desktop updater
|
||||
logger.debug(`Entry #${entryCount}: Skipping mobile tag`)
|
||||
continue
|
||||
} else {
|
||||
// Legacy format: check for prerelease directly
|
||||
hrefChannel = (semver.prerelease(hrefTag)?.[0] as string) || "stable"
|
||||
logger.debug(`Entry #${entryCount}: Legacy tag format, channel: ${hrefChannel}`)
|
||||
}
|
||||
|
||||
let isNextPreRelease = false
|
||||
if (releaseTag) {
|
||||
isNextPreRelease = releaseTag === hrefTag
|
||||
logger.debug(`Entry #${entryCount}: Matching by release tag: ${releaseTag === hrefTag}`)
|
||||
} else {
|
||||
isNextPreRelease = hrefChannel === currentChannel
|
||||
logger.debug(
|
||||
`Entry #${entryCount}: Matching by channel: ${hrefChannel} === ${currentChannel} = ${isNextPreRelease}`,
|
||||
)
|
||||
}
|
||||
|
||||
if (isNextPreRelease) {
|
||||
tag = hrefTag
|
||||
latestRelease = element
|
||||
logger.info(`✓ Found matching release at entry #${entryCount}: ${hrefTag}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
logger.info(`Processed ${entryCount} feed entries total`)
|
||||
} catch (e: any) {
|
||||
logger.error(`Failed to parse releases feed: ${e.stack || e.message}`)
|
||||
throw newError(
|
||||
`Cannot parse releases feed: ${e.stack || e.message},\nXML:\n${feedXml}`,
|
||||
"ERR_UPDATER_INVALID_RELEASE_FEED",
|
||||
)
|
||||
}
|
||||
|
||||
if (tag === null || tag === undefined) {
|
||||
logger.error("No matching published versions found on GitHub")
|
||||
throw newError(`No published versions on GitHub`, "ERR_UPDATER_NO_PUBLISHED_VERSIONS")
|
||||
}
|
||||
|
||||
let rawData: string | null = null
|
||||
let channelFile = ""
|
||||
let channelFileUrl: any = ""
|
||||
const fetchData = async (channelName: string) => {
|
||||
channelFile = getChannelFilename(channelName)
|
||||
channelFileUrl = newUrlFromBase(
|
||||
this.getBaseDownloadPath(String(tag), channelFile),
|
||||
this.baseUrl,
|
||||
)
|
||||
logger.info(`Fetching channel file: ${channelFile} from ${channelFileUrl}`)
|
||||
const requestOptions = this.createRequestOptions(channelFileUrl)
|
||||
try {
|
||||
const data = await this.executor.request(requestOptions, cancellationToken)
|
||||
logger.info(`Successfully fetched ${channelFile}`)
|
||||
return data
|
||||
} catch (e: any) {
|
||||
if (e instanceof HttpError && e.statusCode === 404) {
|
||||
logger.warn(`Channel file not found: ${channelFile} (404)`)
|
||||
throw newError(
|
||||
`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${
|
||||
e.stack || e.message
|
||||
}`,
|
||||
"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND",
|
||||
)
|
||||
}
|
||||
logger.error(`Failed to fetch channel file: ${e.message}`)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const channel = this.updater.allowPrerelease
|
||||
? this.getCustomChannelName(String(semver.prerelease(tag)?.[0] || "latest"))
|
||||
: this.getDefaultChannelName()
|
||||
logger.info(`Attempting to fetch channel: ${channel}`)
|
||||
rawData = await fetchData(channel)
|
||||
} catch (e: any) {
|
||||
if (this.updater.allowPrerelease) {
|
||||
// Allow fallback to `latest.yml`
|
||||
logger.info("Falling back to default channel (latest.yml)")
|
||||
rawData = await fetchData(this.getDefaultChannelName())
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const result = parseUpdateInfo(rawData, channelFile, channelFileUrl)
|
||||
if (result.releaseName == null) {
|
||||
result.releaseName = latestRelease.elementValueOrEmpty("title")
|
||||
}
|
||||
|
||||
if (result.releaseNotes == null) {
|
||||
result.releaseNotes = computeReleaseNotes(
|
||||
this.updater.currentVersion,
|
||||
this.updater.fullChangelog,
|
||||
feed,
|
||||
latestRelease,
|
||||
)
|
||||
}
|
||||
|
||||
logger.info(`Update info parsed successfully`)
|
||||
logObject(logger, "Update Result", {
|
||||
Tag: tag,
|
||||
Version: result.version,
|
||||
"Release Name": result.releaseName || "N/A",
|
||||
"Release Date": result.releaseDate || "N/A",
|
||||
Files: result.files?.length || 0,
|
||||
})
|
||||
|
||||
return {
|
||||
tag,
|
||||
...result,
|
||||
}
|
||||
}
|
||||
|
||||
private get basePath(): string {
|
||||
return `/${this.options.owner}/${this.options.repo}/releases`
|
||||
}
|
||||
|
||||
/**
|
||||
* Use release api to get latest version to filter draft version.
|
||||
* But this api have low request limit 60-times/1-hour, use this to help, not depend on it
|
||||
* https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28
|
||||
* https://api.github.com/repos/toeverything/affine/releases
|
||||
* https://docs.github.com/en/rest/rate-limit/rate-limit?apiVersion=2022-11-28#about-rate-limits
|
||||
*/
|
||||
private async getLatestTagByRelease(
|
||||
currentChannel: string,
|
||||
cancellationToken: CancellationToken,
|
||||
) {
|
||||
try {
|
||||
const apiUrl = newUrlFromBase(`/repos${this.basePath}`, this.baseApiUrl)
|
||||
logger.debug(`Fetching releases from GitHub API: ${apiUrl}`)
|
||||
|
||||
const releasesStr = await this.httpRequest(
|
||||
apiUrl,
|
||||
{
|
||||
accept: "Accept: application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
cancellationToken,
|
||||
)
|
||||
|
||||
if (!releasesStr) {
|
||||
logger.warn("GitHub API returned empty response")
|
||||
return null
|
||||
}
|
||||
|
||||
const releases: GithubRelease[] = JSON.parse(releasesStr)
|
||||
logger.debug(`Received ${releases.length} releases from GitHub API`)
|
||||
|
||||
let checkedCount = 0
|
||||
for (const release of releases) {
|
||||
if (release.draft) {
|
||||
logger.debug(`Skipping draft release: ${release.tag_name}`)
|
||||
continue
|
||||
}
|
||||
|
||||
checkedCount++
|
||||
const releaseTag = release.tag_name
|
||||
|
||||
// Handle new format: desktop/v1.2.3 or mobile/v1.2.3
|
||||
let releaseChannel = "stable"
|
||||
if (releaseTag.startsWith("desktop/")) {
|
||||
// For desktop tags, extract the version and check if it's a prerelease
|
||||
const version = releaseTag.replace("desktop/", "")
|
||||
releaseChannel = (semver.prerelease(version)?.[0] as string) || "stable"
|
||||
logger.debug(`API Release: ${releaseTag} (desktop, channel: ${releaseChannel})`)
|
||||
} else if (releaseTag.startsWith("mobile/")) {
|
||||
// Skip mobile releases for desktop updater
|
||||
logger.debug(`Skipping mobile release: ${releaseTag}`)
|
||||
continue
|
||||
} else {
|
||||
// Legacy format: check for prerelease directly
|
||||
releaseChannel = (semver.prerelease(releaseTag)?.[0] as string) || "stable"
|
||||
logger.debug(`API Release: ${releaseTag} (legacy, channel: ${releaseChannel})`)
|
||||
}
|
||||
|
||||
if (releaseChannel === currentChannel) {
|
||||
logger.info(`✓ Found matching release via API: ${release.tag_name}`)
|
||||
return release.tag_name
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`No matching release found via API (checked ${checkedCount} non-draft releases)`)
|
||||
} catch (e: any) {
|
||||
logger.warn(`Cannot parse release from API: ${e.message}`)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
resolveFiles(updateInfo: GithubUpdateInfo): Array<ResolvedUpdateFileInfo> {
|
||||
logger.info(`Resolving files for tag: ${updateInfo.tag}`)
|
||||
logger.debug(`Total files in update info: ${updateInfo.files.length}`)
|
||||
|
||||
const filteredUpdateInfo = structuredClone(updateInfo)
|
||||
// for windows, we need to determine its installer type (nsis or squirrel)
|
||||
if (isWindows && updateInfo.files.length > 1) {
|
||||
const isSquirrel = isSquirrelBuild()
|
||||
logger.info(`Windows build detected, installer type: ${isSquirrel ? "Squirrel" : "NSIS"}`)
|
||||
|
||||
// @ts-expect-error we should be able to modify the object
|
||||
filteredUpdateInfo.files = updateInfo.files.filter((file) =>
|
||||
isSquirrel ? !file.url.includes("nsis.exe") : file.url.includes("nsis.exe"),
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
`Filtered to ${filteredUpdateInfo.files.length} files after Windows installer type filtering`,
|
||||
)
|
||||
}
|
||||
|
||||
// still replace space to - due to backward compatibility
|
||||
const resolved = resolveFiles(filteredUpdateInfo, this.baseUrl, (p) =>
|
||||
this.getBaseDownloadPath(filteredUpdateInfo.tag, p.replaceAll(" ", "-")),
|
||||
)
|
||||
|
||||
logger.info(`Resolved ${resolved.length} file(s) for download`)
|
||||
resolved.forEach((file, index) => {
|
||||
logger.debug(` File ${index + 1}: ${file.url}`)
|
||||
})
|
||||
|
||||
return resolved
|
||||
}
|
||||
|
||||
private getBaseDownloadPath(tag: string, fileName: string): string {
|
||||
return `${this.basePath}/download/${tag}/${fileName}`
|
||||
}
|
||||
}
|
||||
|
||||
export interface CustomGitHubOptions {
|
||||
channel: string
|
||||
repo: string
|
||||
owner: string
|
||||
releaseType: "release" | "prerelease"
|
||||
}
|
||||
|
||||
function getNoteValue(parent: XElement): string {
|
||||
const result = parent.elementValueOrEmpty("content")
|
||||
// GitHub reports empty notes as <content>No content.</content>
|
||||
return result === "No content." ? "" : result
|
||||
}
|
||||
|
||||
export function computeReleaseNotes(
|
||||
currentVersion: semver.SemVer,
|
||||
isFullChangelog: boolean,
|
||||
feed: XElement,
|
||||
latestRelease: any,
|
||||
): string | Array<ReleaseNoteInfo> | null {
|
||||
if (!isFullChangelog) {
|
||||
return getNoteValue(latestRelease)
|
||||
}
|
||||
|
||||
const releaseNotes: Array<ReleaseNoteInfo> = []
|
||||
for (const release of feed.getElements("entry")) {
|
||||
// noinspection TypeScriptValidateJSTypes
|
||||
const versionRelease = /\/tag\/v?([^/]+)$/.exec(release.element("link").attribute("href"))?.[1]
|
||||
if (versionRelease && semver.lt(currentVersion, versionRelease)) {
|
||||
releaseNotes.push({
|
||||
version: versionRelease,
|
||||
note: getNoteValue(release),
|
||||
})
|
||||
}
|
||||
}
|
||||
return releaseNotes.sort((a, b) => semver.rcompare(a.version, b.version))
|
||||
}
|
||||
|
||||
// addRandomQueryToAvoidCaching is false by default because in most cases URL already contains version number,
|
||||
// so, it makes sense only for Generic Provider for channel files
|
||||
function newUrlFromBase(pathname: string, baseUrl: URL, addRandomQueryToAvoidCaching = false): URL {
|
||||
const result = new URL(pathname, baseUrl)
|
||||
// search is not propagated (search is an empty string if not specified)
|
||||
const { search } = baseUrl
|
||||
if (search != null && search.length > 0) {
|
||||
result.search = search
|
||||
} else if (addRandomQueryToAvoidCaching) {
|
||||
result.search = `noCache=${Date.now().toString(32)}`
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function getChannelFilename(channel: string): string {
|
||||
return `${channel}.yml`
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
import { URL } from "node:url"
|
||||
|
||||
import type {
|
||||
AppUpdate,
|
||||
LatestReleasePayload,
|
||||
PlatformUpdate,
|
||||
PlatformUpdateFile,
|
||||
} from "@follow-app/client-sdk"
|
||||
import type { UpdateFileInfo, UpdateInfo } from "builder-util-runtime"
|
||||
import { newError } from "builder-util-runtime"
|
||||
import type { AppUpdater } from "electron-updater"
|
||||
import type { ProviderRuntimeOptions } from "electron-updater/out/providers/Provider"
|
||||
import { Provider } from "electron-updater/out/providers/Provider"
|
||||
import type { ResolvedUpdateFileInfo } from "electron-updater/out/types"
|
||||
|
||||
import { logger } from "../logger"
|
||||
import { getUpdateInfo } from "./api"
|
||||
|
||||
interface FollowProviderOptions {
|
||||
provider: "custom"
|
||||
}
|
||||
|
||||
type FollowProviderContext = {
|
||||
payload: LatestReleasePayload
|
||||
platform: PlatformUpdate
|
||||
}
|
||||
|
||||
export class FollowUpdateProvider extends Provider<UpdateInfo> {
|
||||
private static context: FollowProviderContext | null = null
|
||||
|
||||
static setContext(context: FollowProviderContext) {
|
||||
FollowUpdateProvider.context = context
|
||||
}
|
||||
|
||||
static clearContext() {
|
||||
FollowUpdateProvider.context = null
|
||||
}
|
||||
|
||||
static getContext() {
|
||||
return FollowUpdateProvider.context
|
||||
}
|
||||
|
||||
constructor(
|
||||
_options: FollowProviderOptions,
|
||||
_updater: AppUpdater,
|
||||
runtimeOptions: ProviderRuntimeOptions,
|
||||
) {
|
||||
super(runtimeOptions)
|
||||
}
|
||||
|
||||
async getLatestVersion(): Promise<UpdateInfo> {
|
||||
const context = await this.ensureContext()
|
||||
return this.buildUpdateInfo(context)
|
||||
}
|
||||
|
||||
resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo> {
|
||||
return updateInfo.files.map((file) => ({
|
||||
info: file,
|
||||
url: new URL(file.url),
|
||||
}))
|
||||
}
|
||||
|
||||
private buildUpdateInfo(context: FollowProviderContext): UpdateInfo {
|
||||
const { payload, platform } = context
|
||||
const files = this.mapFiles(platform.files)
|
||||
|
||||
if (files.length === 0) {
|
||||
throw newError(
|
||||
`No downloadable files found for platform ${platform.platform}`,
|
||||
"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND",
|
||||
)
|
||||
}
|
||||
|
||||
const primaryFile = files[0]
|
||||
if (!primaryFile) {
|
||||
throw newError(
|
||||
`Platform ${platform.platform} provides no downloadable file`,
|
||||
"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND",
|
||||
)
|
||||
}
|
||||
|
||||
let primaryPath = primaryFile.url
|
||||
const primaryUrl = this.safeParseUrl(primaryFile.url)
|
||||
if (primaryUrl) {
|
||||
const filename = primaryUrl.pathname.split("/").pop()
|
||||
if (filename) {
|
||||
primaryPath = filename
|
||||
}
|
||||
}
|
||||
|
||||
const { release } = payload
|
||||
|
||||
return {
|
||||
version: platform.version,
|
||||
files,
|
||||
path: primaryPath,
|
||||
sha512: primaryFile.sha512,
|
||||
releaseName: release.name,
|
||||
releaseNotes: release.body,
|
||||
releaseDate: platform.releaseDate || release.publishedAt || new Date().toISOString(),
|
||||
}
|
||||
}
|
||||
|
||||
private mapFiles(files: PlatformUpdate["files"]): UpdateFileInfo[] {
|
||||
if (!files) return []
|
||||
|
||||
return files
|
||||
.map((file) => this.mapFile(file))
|
||||
.filter((file): file is UpdateFileInfo => file !== null)
|
||||
}
|
||||
|
||||
private mapFile(file: PlatformUpdateFile): UpdateFileInfo | null {
|
||||
if (!file.downloadUrl || !file.sha512) {
|
||||
logger.warn("Skip platform file without downloadUrl or sha512", file)
|
||||
return null
|
||||
}
|
||||
|
||||
const mapped: UpdateFileInfo = {
|
||||
url: file.downloadUrl,
|
||||
sha512: file.sha512,
|
||||
}
|
||||
|
||||
if (typeof file.size === "number") {
|
||||
mapped.size = file.size
|
||||
}
|
||||
|
||||
return mapped
|
||||
}
|
||||
|
||||
private safeParseUrl(value: string): URL | null {
|
||||
try {
|
||||
return new URL(value)
|
||||
} catch (error) {
|
||||
logger.debug?.("Unable to parse update file URL", error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private async ensureContext(): Promise<FollowProviderContext> {
|
||||
const context = FollowUpdateProvider.getContext()
|
||||
if (context) return context
|
||||
|
||||
const fetched = await this.fetchContext()
|
||||
FollowUpdateProvider.setContext(fetched)
|
||||
return fetched
|
||||
}
|
||||
|
||||
private async fetchContext(): Promise<FollowProviderContext> {
|
||||
const payload = await getUpdateInfo({})
|
||||
const { decision } = payload
|
||||
|
||||
if (!decision || decision.type !== "app" || !decision.app) {
|
||||
throw newError(
|
||||
"No app update metadata available from provider",
|
||||
"ERR_UPDATER_NO_PUBLISHED_VERSIONS",
|
||||
)
|
||||
}
|
||||
|
||||
const platform = this.pickPlatform(decision.app)
|
||||
if (!platform) {
|
||||
throw newError(
|
||||
`No matching platform update for ${process.platform}/${process.arch}`,
|
||||
"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND",
|
||||
)
|
||||
}
|
||||
|
||||
return { payload, platform }
|
||||
}
|
||||
|
||||
private pickPlatform(appDecision: AppUpdate): PlatformUpdate | null {
|
||||
const platforms = appDecision.platforms ?? []
|
||||
const selected = appDecision.selectedPlatform
|
||||
if (selected) {
|
||||
return selected
|
||||
}
|
||||
|
||||
const candidates = this.resolvePlatformCandidates()
|
||||
const matched = platforms.find((platform) =>
|
||||
candidates.includes(platform.platform.toLowerCase()),
|
||||
)
|
||||
|
||||
return matched ?? platforms[0] ?? null
|
||||
}
|
||||
|
||||
private resolvePlatformCandidates(): string[] {
|
||||
const base = new Set<string>()
|
||||
base.add(process.platform)
|
||||
base.add(`${process.platform}-${process.arch}`)
|
||||
base.add(process.arch)
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
base.add("mac")
|
||||
base.add("macos")
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
base.add("windows")
|
||||
base.add("win")
|
||||
}
|
||||
|
||||
return Array.from(base).map((value) => value.toLowerCase())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,271 +1,282 @@
|
|||
/**
|
||||
* @description This file handles hot updates for the electron renderer layer
|
||||
*/
|
||||
import { existsSync, readFileSync } from "node:fs"
|
||||
import { mkdir, readdir, rename, rm, stat, writeFile } from "node:fs/promises"
|
||||
import os from "node:os"
|
||||
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import type { LatestReleasePayload, RendererUpdate } from "@follow-app/client-sdk"
|
||||
import { mainHash, version as appVersion } from "@pkg"
|
||||
import log from "electron-log"
|
||||
import { load } from "js-yaml"
|
||||
import { dump, load } from "js-yaml"
|
||||
import path from "pathe"
|
||||
import { x } from "tar"
|
||||
|
||||
import { GITHUB_OWNER, GITHUB_REPO, HOTUPDATE_RENDER_ENTRY_DIR } from "~/constants/app"
|
||||
import { HOTUPDATE_RENDER_ENTRY_DIR } from "~/constants/app"
|
||||
import { downloadFileWithProgress } from "~/lib/download"
|
||||
import { WindowManager } from "~/manager/window"
|
||||
|
||||
import { appUpdaterConfig } from "./configs"
|
||||
|
||||
const logger = log.scope("hot-updater")
|
||||
declare const GIT_COMMIT_HASH: string | undefined
|
||||
|
||||
const url = `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}`
|
||||
const releasesUrl = `${url}/releases`
|
||||
const releaseApiUrl = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases`
|
||||
export type RendererManifest = RendererUpdate & {
|
||||
downloadUrl: string
|
||||
downloadedAt?: string
|
||||
}
|
||||
|
||||
const getLatestReleaseTag = async () => {
|
||||
// First try to get the latest release
|
||||
try {
|
||||
const latestRes = await fetch(`${releaseApiUrl}/latest`)
|
||||
if (latestRes.ok) {
|
||||
const latestRelease = await latestRes.json()
|
||||
// Check if the latest release is a desktop release
|
||||
if (
|
||||
latestRelease.tag_name &&
|
||||
latestRelease.tag_name.startsWith("desktop/") &&
|
||||
!latestRelease.draft
|
||||
) {
|
||||
return latestRelease.tag_name
|
||||
export enum RendererEligibilityStatus {
|
||||
NoManifest,
|
||||
RequiresFullAppUpdate,
|
||||
AlreadyCurrent,
|
||||
Eligible,
|
||||
}
|
||||
|
||||
export interface RendererEligibilityResult {
|
||||
status: RendererEligibilityStatus
|
||||
manifest?: RendererManifest
|
||||
reason?: string
|
||||
}
|
||||
|
||||
class RendererHotUpdater {
|
||||
private readonly logger = log.scope("updater:renderer")
|
||||
private readonly tempDir = path.resolve(os.tmpdir(), "follow-render-update")
|
||||
private readonly manifestPath = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, "manifest.yml")
|
||||
|
||||
extractManifest(payload: LatestReleasePayload | null): RendererManifest | null {
|
||||
if (!payload) return null
|
||||
|
||||
const { decision } = payload
|
||||
if (!decision || decision.type !== "renderer") {
|
||||
return null
|
||||
}
|
||||
|
||||
const { renderer } = decision
|
||||
if (!renderer) {
|
||||
this.logger.debug("Renderer decision payload missing renderer field")
|
||||
return null
|
||||
}
|
||||
|
||||
if (!renderer.downloadUrl) {
|
||||
this.logger.warn("Renderer decision missing downloadUrl, skip renderer hot update")
|
||||
return null
|
||||
}
|
||||
|
||||
if (!renderer.filename) {
|
||||
this.logger.warn("Renderer decision missing filename, skip renderer hot update")
|
||||
return null
|
||||
}
|
||||
|
||||
if (!renderer.hash) {
|
||||
this.logger.warn("Renderer decision missing hash, skip renderer hot update")
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
...renderer,
|
||||
downloadUrl: renderer.downloadUrl,
|
||||
}
|
||||
}
|
||||
|
||||
evaluateManifest(manifest: RendererManifest | null): RendererEligibilityResult {
|
||||
if (!manifest) {
|
||||
return { status: RendererEligibilityStatus.NoManifest }
|
||||
}
|
||||
|
||||
if (manifest.mainHash && manifest.mainHash !== mainHash) {
|
||||
return {
|
||||
status: RendererEligibilityStatus.RequiresFullAppUpdate,
|
||||
manifest,
|
||||
reason: `Renderer payload requires main hash ${manifest.mainHash}, current main hash is ${mainHash}`,
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn("Failed to fetch latest release, falling back to all releases", error)
|
||||
|
||||
if (manifest.version === appVersion) {
|
||||
return {
|
||||
status: RendererEligibilityStatus.AlreadyCurrent,
|
||||
reason: "Renderer version matches current app version",
|
||||
}
|
||||
}
|
||||
|
||||
if (manifest.commit && GIT_COMMIT_HASH && manifest.commit === GIT_COMMIT_HASH) {
|
||||
return {
|
||||
status: RendererEligibilityStatus.AlreadyCurrent,
|
||||
reason: "Renderer commit matches current main commit",
|
||||
}
|
||||
}
|
||||
|
||||
const installedManifest = this.getCurrentManifest()
|
||||
if (installedManifest) {
|
||||
if (installedManifest.version === manifest.version) {
|
||||
return {
|
||||
status: RendererEligibilityStatus.AlreadyCurrent,
|
||||
reason: "Installed renderer manifest already at target version",
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
installedManifest.commit &&
|
||||
manifest.commit &&
|
||||
installedManifest.commit === manifest.commit
|
||||
) {
|
||||
return {
|
||||
status: RendererEligibilityStatus.AlreadyCurrent,
|
||||
reason: "Installed renderer manifest commit matches target commit",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
status: RendererEligibilityStatus.Eligible,
|
||||
manifest,
|
||||
}
|
||||
}
|
||||
|
||||
// If latest release is not a desktop release or fetch failed, get all releases
|
||||
const res = await fetch(releaseApiUrl)
|
||||
async applyManifest(manifest: RendererManifest): Promise<void> {
|
||||
if (!appUpdaterConfig.enableRenderHotUpdate) {
|
||||
this.logger.info("Renderer hot update skipped because it is disabled in config")
|
||||
return
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`GitHub API request failed: ${res.status} ${res.statusText}`)
|
||||
const archivePath = await this.downloadArchive(manifest)
|
||||
|
||||
await mkdir(HOTUPDATE_RENDER_ENTRY_DIR, { recursive: true })
|
||||
this.logger.info(`Extracting renderer bundle to ${HOTUPDATE_RENDER_ENTRY_DIR}`)
|
||||
|
||||
await x({
|
||||
f: archivePath,
|
||||
cwd: HOTUPDATE_RENDER_ENTRY_DIR,
|
||||
})
|
||||
|
||||
const extractedDir = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, "renderer")
|
||||
const targetDir = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, manifest.version)
|
||||
|
||||
const extractedStats = await stat(extractedDir).catch(() => null)
|
||||
if (!extractedStats) {
|
||||
throw new Error(`Extracted renderer directory not found at ${extractedDir}`)
|
||||
}
|
||||
|
||||
await rm(targetDir, { recursive: true, force: true })
|
||||
await rename(extractedDir, targetDir)
|
||||
|
||||
await this.writeManifest({ ...manifest, downloadedAt: new Date().toISOString() })
|
||||
|
||||
try {
|
||||
await rm(archivePath, { force: true })
|
||||
} catch (error) {
|
||||
this.logger.warn("Failed to clean renderer archive", error)
|
||||
}
|
||||
|
||||
this.logger.info(`Renderer hot update applied successfully: ${manifest.version}`)
|
||||
|
||||
const mainWindow = WindowManager.getMainWindow()
|
||||
if (mainWindow) {
|
||||
callWindowExpose(mainWindow).readyToUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
const releases = await res.json()
|
||||
getCurrentManifest(): RendererManifest | null {
|
||||
if (!existsSync(this.manifestPath)) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Check if the response contains an error message
|
||||
if (releases.message) {
|
||||
throw new Error(`GitHub API error: ${releases.message}`)
|
||||
}
|
||||
try {
|
||||
const content = readFileSync(this.manifestPath, "utf-8")
|
||||
const parsed = load(content)
|
||||
if (parsed && typeof parsed === "object") {
|
||||
return parsed as RendererManifest
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.warn("Failed to read renderer manifest from disk", error)
|
||||
}
|
||||
|
||||
// Ensure releases is an array
|
||||
if (!Array.isArray(releases)) {
|
||||
throw new TypeError("Invalid response format from GitHub API")
|
||||
}
|
||||
|
||||
// Filter for desktop releases and find the latest one
|
||||
const desktopReleases = releases.filter(
|
||||
(release: any) => release.tag_name && release.tag_name.startsWith("desktop/") && !release.draft,
|
||||
)
|
||||
|
||||
if (desktopReleases.length === 0) {
|
||||
throw new Error("No desktop releases found")
|
||||
}
|
||||
|
||||
// Sort by created_at date in descending order to get the most recent first
|
||||
desktopReleases.sort((a: any, b: any) => {
|
||||
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
||||
})
|
||||
|
||||
// Return the most recent desktop release
|
||||
return desktopReleases[0].tag_name
|
||||
}
|
||||
|
||||
const getFileDownloadUrl = async (filename: string) => {
|
||||
const tag = await getLatestReleaseTag()
|
||||
|
||||
return `${releasesUrl}/download/${tag}/${filename}`
|
||||
}
|
||||
|
||||
type Manifest = {
|
||||
/** Render version */
|
||||
version: string
|
||||
hash: string
|
||||
commit: string
|
||||
filename: string
|
||||
/** Only electron main hash equal to this value, renderer will can be updated */
|
||||
mainHash: string
|
||||
}
|
||||
const getLatestReleaseManifest = async () => {
|
||||
const url = await getFileDownloadUrl("manifest.yml")
|
||||
logger.info(`Fetching manifest from ${url}`)
|
||||
const res = await fetch(url)
|
||||
|
||||
if (!res.ok) {
|
||||
logger.error(`Failed to fetch manifest: ${res.status} ${res.statusText}`)
|
||||
return null
|
||||
}
|
||||
|
||||
const text = await res.text()
|
||||
const manifest = load(text) as Manifest
|
||||
if (typeof manifest !== "object") {
|
||||
logger.error("Invalid manifest", text)
|
||||
return null
|
||||
}
|
||||
return manifest
|
||||
}
|
||||
const downloadTempDir = path.resolve(os.tmpdir(), "follow-render-update")
|
||||
|
||||
export enum CanUpdateRenderState {
|
||||
// If version is equal, no need to update
|
||||
NO_NEEDED,
|
||||
// Can be only update render layer, not fully upgrade app
|
||||
NEEDED,
|
||||
// App not support, should trigger app force update
|
||||
APP_NOT_SUPPORT,
|
||||
// Network error, can fetch manifest
|
||||
NETWORK_ERROR,
|
||||
}
|
||||
export const canUpdateRender = async (): Promise<[CanUpdateRenderState, Manifest | null]> => {
|
||||
const manifest = await getLatestReleaseManifest()
|
||||
|
||||
logger.info("fetched manifest", manifest)
|
||||
|
||||
if (!manifest) return [CanUpdateRenderState.NETWORK_ERROR, null]
|
||||
|
||||
const appSupport = mainHash === manifest.mainHash
|
||||
if (!appSupport) {
|
||||
logger.info("app not support, should trigger app force update, app version: ", appVersion)
|
||||
|
||||
return [CanUpdateRenderState.APP_NOT_SUPPORT, null]
|
||||
}
|
||||
|
||||
const isVersionEqual = appVersion === manifest.version
|
||||
if (isVersionEqual) {
|
||||
logger.info("version is equal, skip update")
|
||||
return [CanUpdateRenderState.NO_NEEDED, null]
|
||||
}
|
||||
const isCommitEqual = GIT_COMMIT_HASH === manifest.commit
|
||||
if (isCommitEqual) {
|
||||
logger.info("commit is equal, skip update")
|
||||
return [CanUpdateRenderState.NO_NEEDED, null]
|
||||
}
|
||||
|
||||
const manifestFilePath = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, "manifest.yml")
|
||||
const manifestExist = existsSync(manifestFilePath)
|
||||
|
||||
const oldManifest: Manifest | null = manifestExist
|
||||
? (load(readFileSync(manifestFilePath, "utf-8")) as Manifest)
|
||||
: null
|
||||
|
||||
if (oldManifest) {
|
||||
if (oldManifest.version === manifest.version) {
|
||||
logger.info("manifest version is equal, skip update")
|
||||
return [CanUpdateRenderState.NO_NEEDED, null]
|
||||
async cleanup(): Promise<void> {
|
||||
const manifest = this.getCurrentManifest()
|
||||
if (!manifest) {
|
||||
await rm(HOTUPDATE_RENDER_ENTRY_DIR, { recursive: true, force: true })
|
||||
return
|
||||
}
|
||||
if (oldManifest.commit === manifest.commit) {
|
||||
logger.info("manifest commit is equal, skip update")
|
||||
return [CanUpdateRenderState.NO_NEEDED, null]
|
||||
|
||||
const keepDir = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, manifest.version)
|
||||
let entries: string[] = []
|
||||
|
||||
try {
|
||||
entries = await readdir(HOTUPDATE_RENDER_ENTRY_DIR)
|
||||
} catch (error) {
|
||||
this.logger.warn("Failed to read renderer directory for cleanup", error)
|
||||
return
|
||||
}
|
||||
}
|
||||
return [CanUpdateRenderState.NEEDED, manifest]
|
||||
}
|
||||
const downloadRenderAsset = async (manifest: Manifest) => {
|
||||
const { filename } = manifest
|
||||
const url = await getFileDownloadUrl(filename)
|
||||
const filePath = path.resolve(downloadTempDir, filename)
|
||||
|
||||
logger.info(`Downloading ${url}, Save to ${filePath}`)
|
||||
|
||||
const success = await downloadFileWithProgress({
|
||||
url,
|
||||
outputPath: filePath,
|
||||
expectedHash: manifest.hash,
|
||||
|
||||
onLog: (message) => {
|
||||
logger.info(message)
|
||||
},
|
||||
})
|
||||
if (!success) throw new Error("Download hot update render asset failed")
|
||||
return filePath
|
||||
}
|
||||
export const hotUpdateRender = async (manifest: Manifest) => {
|
||||
if (!appUpdaterConfig.enableRenderHotUpdate) return false
|
||||
|
||||
if (!manifest) return false
|
||||
|
||||
const filePath = await downloadRenderAsset(manifest)
|
||||
logger.info(`Downloaded render asset to ${filePath}`)
|
||||
if (!filePath) return false
|
||||
|
||||
// Extract the tar.gz file
|
||||
await mkdir(HOTUPDATE_RENDER_ENTRY_DIR, { recursive: true })
|
||||
logger.info(`Extracting render asset to ${HOTUPDATE_RENDER_ENTRY_DIR}`)
|
||||
await x({
|
||||
f: filePath,
|
||||
cwd: HOTUPDATE_RENDER_ENTRY_DIR,
|
||||
})
|
||||
|
||||
logger.info(
|
||||
`Extracted render asset to ${HOTUPDATE_RENDER_ENTRY_DIR}, rename to ${manifest.version}`,
|
||||
)
|
||||
|
||||
// Rename `renderer` folder to `manifest.version`
|
||||
await rename(
|
||||
path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, "renderer"),
|
||||
path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, manifest.version),
|
||||
)
|
||||
|
||||
const manifestPath = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, "manifest.yml")
|
||||
logger.info(`Write manifest to ${manifestPath}`)
|
||||
|
||||
await writeFile(manifestPath, JSON.stringify(manifest))
|
||||
logger.info(`Hot update render success, update to ${manifest.version}`)
|
||||
|
||||
const mainWindow = WindowManager.getMainWindow()
|
||||
if (!mainWindow) return false
|
||||
const caller = callWindowExpose(mainWindow)
|
||||
caller.readyToUpdate()
|
||||
return true
|
||||
}
|
||||
|
||||
export const getCurrentRenderManifest = () => {
|
||||
const manifestFilePath = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, "manifest.yml")
|
||||
const manifestExist = existsSync(manifestFilePath)
|
||||
if (!manifestExist) return null
|
||||
return load(readFileSync(manifestFilePath, "utf-8")) as Manifest
|
||||
}
|
||||
export const cleanupOldRender = async () => {
|
||||
const manifest = getCurrentRenderManifest()
|
||||
if (!manifest) {
|
||||
// Empty the directory
|
||||
await rm(HOTUPDATE_RENDER_ENTRY_DIR, { recursive: true, force: true })
|
||||
return
|
||||
await Promise.all(
|
||||
entries.map(async (entryName) => {
|
||||
const entryPath = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, entryName)
|
||||
const entryStat = await stat(entryPath).catch(() => null)
|
||||
if (!entryStat?.isDirectory()) return
|
||||
if (entryPath === keepDir) return
|
||||
await rm(entryPath, { recursive: true, force: true })
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const currentRenderVersion = manifest.version
|
||||
// Clean all not current version
|
||||
const dirs = await readdir(HOTUPDATE_RENDER_ENTRY_DIR)
|
||||
for (const dir of dirs) {
|
||||
const isDir = (await stat(path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, dir))).isDirectory()
|
||||
if (!isDir) continue
|
||||
if (dir === currentRenderVersion) continue
|
||||
await rm(path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, dir), { recursive: true, force: true })
|
||||
loadDynamicEntry() {
|
||||
if (!appUpdaterConfig.enableRenderHotUpdate) return
|
||||
|
||||
const manifest = this.getCurrentManifest()
|
||||
if (!manifest) return
|
||||
if (manifest.mainHash && manifest.mainHash !== mainHash) return
|
||||
|
||||
const dir = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, manifest.version)
|
||||
const entryFile = path.resolve(dir, "index.html")
|
||||
if (!existsSync(entryFile)) return
|
||||
|
||||
return entryFile
|
||||
}
|
||||
|
||||
private async downloadArchive(manifest: RendererManifest) {
|
||||
const archivePath = path.resolve(this.tempDir, manifest.filename)
|
||||
|
||||
this.logger.info(
|
||||
`Downloading renderer bundle ${manifest.filename} from ${manifest.downloadUrl}`,
|
||||
)
|
||||
|
||||
const success = await downloadFileWithProgress({
|
||||
url: manifest.downloadUrl,
|
||||
outputPath: archivePath,
|
||||
expectedHash: manifest.hash,
|
||||
onLog: (message) => this.logger.info(message),
|
||||
})
|
||||
|
||||
if (!success) {
|
||||
throw new Error("Failed to download renderer bundle")
|
||||
}
|
||||
|
||||
return archivePath
|
||||
}
|
||||
|
||||
private async writeManifest(manifest: RendererManifest) {
|
||||
await writeFile(this.manifestPath, dump(manifest), "utf-8")
|
||||
}
|
||||
}
|
||||
|
||||
export const loadDynamicRenderEntry = () => {
|
||||
if (!appUpdaterConfig.enableRenderHotUpdate) return
|
||||
const manifest = getCurrentRenderManifest()
|
||||
if (!manifest) return
|
||||
// check main hash is equal to manifest.mainHash
|
||||
const appSupport = mainHash === manifest.mainHash
|
||||
if (!appSupport) return
|
||||
export const rendererUpdater = new RendererHotUpdater()
|
||||
|
||||
const currentRenderVersion = manifest.version
|
||||
const dir = path.resolve(HOTUPDATE_RENDER_ENTRY_DIR, currentRenderVersion)
|
||||
const entryFile = path.resolve(dir, "index.html")
|
||||
const entryFileExists = existsSync(entryFile)
|
||||
export const extractRendererManifest = (payload: LatestReleasePayload | null) =>
|
||||
rendererUpdater.extractManifest(payload)
|
||||
|
||||
if (!entryFileExists) return
|
||||
return entryFile
|
||||
export const evaluateRendererUpdate = (manifest: RendererManifest | null) =>
|
||||
rendererUpdater.evaluateManifest(manifest)
|
||||
|
||||
export const applyRendererUpdate = async (manifest: RendererManifest) => {
|
||||
await rendererUpdater.applyManifest(manifest)
|
||||
}
|
||||
|
||||
export const getCurrentRendererManifest = () => rendererUpdater.getCurrentManifest()
|
||||
|
||||
export const cleanupOldRenderer = async () => {
|
||||
await rendererUpdater.cleanup()
|
||||
}
|
||||
|
||||
export const cleanupOldRender = cleanupOldRenderer
|
||||
|
||||
export const loadDynamicRenderEntry = () => rendererUpdater.loadDynamicEntry()
|
||||
|
|
|
|||
|
|
@ -1,189 +1,352 @@
|
|||
import { fileURLToPath } from "node:url"
|
||||
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import { DEV } from "@follow/shared/constants"
|
||||
import type { LatestReleasePayload, PlatformUpdate } from "@follow-app/client-sdk"
|
||||
import type { AppUpdater } from "electron-updater"
|
||||
import { autoUpdater as defaultAutoUpdater } from "electron-updater"
|
||||
import { join } from "pathe"
|
||||
|
||||
import { GITHUB_OWNER, GITHUB_REPO } from "~/constants/app"
|
||||
import { WindowManager } from "~/manager/window"
|
||||
import { canUpdateRender, CanUpdateRenderState, hotUpdateRender } from "~/updater/hot-updater"
|
||||
import type { RendererManifest } from "~/updater/hot-updater"
|
||||
import { RendererEligibilityStatus, rendererUpdater } from "~/updater/hot-updater"
|
||||
|
||||
import { channel, isWindows } from "../env"
|
||||
import { logger } from "../logger"
|
||||
import { getUpdateInfo } from "./api"
|
||||
import { appUpdaterConfig } from "./configs"
|
||||
import { CustomGitHubProvider } from "./custom-github-provider"
|
||||
import { FollowUpdateProvider } from "./follow-update-provider"
|
||||
import { WindowsUpdater } from "./windows-updater"
|
||||
|
||||
// skip auto update in dev mode
|
||||
// const disabled = DEV
|
||||
const disabled = !appUpdaterConfig.enableAppUpdate
|
||||
|
||||
const autoUpdater = isWindows ? new WindowsUpdater() : defaultAutoUpdater
|
||||
|
||||
export const quitAndInstall = () => {
|
||||
const mainWindow = WindowManager.getMainWindow()
|
||||
logger.info("Quit and install update, close main window, ", mainWindow?.id)
|
||||
WindowManager.destroyMainWindow()
|
||||
|
||||
setTimeout(() => {
|
||||
logger.info("Window is closed, quit and install update")
|
||||
autoUpdater.quitAndInstall()
|
||||
}, 1000)
|
||||
type UpdateCheckOptions = {
|
||||
refresh?: boolean
|
||||
}
|
||||
|
||||
let downloading = false
|
||||
let checkingUpdate = false
|
||||
|
||||
const checkRenderUpdateAvailable = async () => {
|
||||
const [state, manifest] = await canUpdateRender()
|
||||
if (state === CanUpdateRenderState.NEEDED && manifest) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
type UpdateCheckResult = {
|
||||
hasUpdate: boolean
|
||||
error?: string
|
||||
}
|
||||
|
||||
const upgradeRenderIfNeeded = async () => {
|
||||
const [state, manifest] = await canUpdateRender()
|
||||
if (state === CanUpdateRenderState.NO_NEEDED) {
|
||||
return { upgraded: false }
|
||||
}
|
||||
if (state === CanUpdateRenderState.NEEDED && manifest) {
|
||||
await hotUpdateRender(manifest)
|
||||
return { upgraded: true }
|
||||
}
|
||||
return { upgraded: false }
|
||||
}
|
||||
export const checkForAppUpdates = async (): Promise<{ hasUpdate: boolean; error?: string }> => {
|
||||
if (disabled || checkingUpdate) {
|
||||
return { hasUpdate: false }
|
||||
class FollowUpdater {
|
||||
private readonly disabled: boolean
|
||||
private checkingUpdate = false
|
||||
private downloadingUpdate = false
|
||||
|
||||
private pollingTimer: NodeJS.Timeout | null = null
|
||||
|
||||
constructor(
|
||||
private readonly autoUpdater: AppUpdater,
|
||||
private readonly renderer = rendererUpdater,
|
||||
) {
|
||||
this.disabled = !appUpdaterConfig.enableAppUpdate
|
||||
}
|
||||
|
||||
checkingUpdate = true
|
||||
try {
|
||||
let hasUpdate = false
|
||||
|
||||
if (appUpdaterConfig.enableRenderHotUpdate) {
|
||||
const hasRenderUpdate = await checkRenderUpdateAvailable()
|
||||
if (hasRenderUpdate) {
|
||||
hasUpdate = true
|
||||
|
||||
// Auto upgrade renderer
|
||||
upgradeRenderIfNeeded()
|
||||
return { hasUpdate }
|
||||
}
|
||||
register() {
|
||||
if (this.disabled) {
|
||||
logger.info("App auto-update disabled; updater not registered")
|
||||
return
|
||||
}
|
||||
|
||||
// Check for core app updates
|
||||
if (appUpdaterConfig.enableCoreUpdate) {
|
||||
const result = await autoUpdater.checkForUpdates()
|
||||
if (result !== null && result.updateInfo !== null) {
|
||||
hasUpdate = true
|
||||
}
|
||||
this.autoUpdater.autoDownload = false
|
||||
this.autoUpdater.allowPrerelease = channel !== "stable"
|
||||
this.autoUpdater.autoInstallOnAppQuit = true
|
||||
this.autoUpdater.autoRunAppAfterInstall = true
|
||||
this.autoUpdater.forceDevUpdateConfig = DEV
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url))
|
||||
this.autoUpdater.updateConfigPath = join(__dirname, "../../dev-only/dev-app-update.yml")
|
||||
}
|
||||
|
||||
return { hasUpdate }
|
||||
} catch (e) {
|
||||
logger.error("Error checking for updates", e)
|
||||
return { hasUpdate: false, error: e instanceof Error ? e.message : "Unknown error" }
|
||||
} finally {
|
||||
checkingUpdate = false
|
||||
}
|
||||
}
|
||||
this.autoUpdater.setFeedURL({
|
||||
provider: "custom",
|
||||
updateProvider: FollowUpdateProvider,
|
||||
})
|
||||
|
||||
export const downloadAppUpdate = async () => {
|
||||
if (disabled || downloading) {
|
||||
return
|
||||
}
|
||||
downloading = true
|
||||
autoUpdater.downloadUpdate().catch((e) => {
|
||||
downloading = false
|
||||
logger.error("Failed to download update", e)
|
||||
})
|
||||
logger.info("Update available, downloading...")
|
||||
return
|
||||
}
|
||||
this.registerAutoUpdaterEvents()
|
||||
|
||||
export const registerUpdater = async () => {
|
||||
if (disabled) {
|
||||
return
|
||||
}
|
||||
if (appUpdaterConfig.app.autoCheckUpdate) {
|
||||
void this.checkForUpdates().catch((error) =>
|
||||
logger.error("Initial update check failed", error),
|
||||
)
|
||||
}
|
||||
|
||||
// Disable there, control this in event
|
||||
autoUpdater.autoDownload = false
|
||||
autoUpdater.allowPrerelease = channel !== "stable"
|
||||
autoUpdater.autoInstallOnAppQuit = true
|
||||
autoUpdater.autoRunAppAfterInstall = true
|
||||
if (this.pollingTimer) {
|
||||
clearInterval(this.pollingTimer)
|
||||
}
|
||||
|
||||
const feedUrl: Exclude<Parameters<typeof autoUpdater.setFeedURL>[0], string> = {
|
||||
channel,
|
||||
// hack for custom provider
|
||||
provider: "custom" as "github",
|
||||
repo: GITHUB_REPO,
|
||||
owner: GITHUB_OWNER,
|
||||
releaseType: channel === "stable" ? "release" : "prerelease",
|
||||
// @ts-expect-error hack for custom provider
|
||||
updateProvider: CustomGitHubProvider,
|
||||
}
|
||||
|
||||
logger.debug("auto-updater feed config", {
|
||||
...feedUrl,
|
||||
updateProvider: undefined,
|
||||
})
|
||||
|
||||
autoUpdater.setFeedURL(feedUrl)
|
||||
|
||||
// register events for checkForUpdates
|
||||
autoUpdater.on("checking-for-update", () => {
|
||||
logger.info("Checking for update")
|
||||
})
|
||||
autoUpdater.on("update-available", async (info) => {
|
||||
logger.info("Update available", info)
|
||||
|
||||
// The app hotfix strategy is as follows:
|
||||
// Determine whether the app should be updated in full or only the renderer layer based on the version number.
|
||||
// https://www.notion.so/rss3/Follow-Hotfix-Electron-Renderer-layer-RFC-fe2444b9ac194c2cb38f9fa0bb1ef3c1?pvs=4#12e35ea049b480f1b268f1e605d86a62
|
||||
if (appUpdaterConfig.enableRenderHotUpdate) {
|
||||
const renderResult = await upgradeRenderIfNeeded()
|
||||
if (renderResult.upgraded) {
|
||||
this.pollingTimer = setInterval(() => {
|
||||
if (!appUpdaterConfig.app.autoCheckUpdate) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (appUpdaterConfig.app.autoDownloadUpdate && appUpdaterConfig.enableCoreUpdate) {
|
||||
downloadAppUpdate().catch((err) => {
|
||||
logger.error(err)
|
||||
void this.checkForUpdates().catch((error) => {
|
||||
logger.error("Scheduled update check failed", error)
|
||||
})
|
||||
}
|
||||
})
|
||||
autoUpdater.on("update-not-available", (info) => {
|
||||
logger.info("Update not available", info)
|
||||
})
|
||||
autoUpdater.on("download-progress", (e) => {
|
||||
logger.info(`Download progress: ${e.percent}`)
|
||||
})
|
||||
autoUpdater.on("update-downloaded", () => {
|
||||
downloading = false
|
||||
logger.info("Update downloaded, ready to install")
|
||||
}, appUpdaterConfig.app.checkUpdateInterval)
|
||||
}
|
||||
|
||||
async checkForUpdates(options: UpdateCheckOptions = {}): Promise<UpdateCheckResult> {
|
||||
if (this.disabled) {
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
if (this.checkingUpdate) {
|
||||
logger.info("Update check already in progress, skipping")
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
this.checkingUpdate = true
|
||||
|
||||
try {
|
||||
const payload = await getUpdateInfo(options.refresh ? { refresh: true } : {})
|
||||
const { decision } = payload
|
||||
|
||||
if (!decision || decision.type === "none") {
|
||||
logger.info("Update decision: none")
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
if (decision.type === "renderer") {
|
||||
logger.info("Update decision: renderer")
|
||||
return await this.handleRendererDecision(payload)
|
||||
}
|
||||
|
||||
if (decision.type === "app") {
|
||||
logger.info("Update decision: app")
|
||||
return await this.handleAppDecision(payload)
|
||||
}
|
||||
|
||||
logger.warn("Unknown update decision type", { type: decision.type })
|
||||
return { hasUpdate: false }
|
||||
} catch (error) {
|
||||
logger.error("Failed to check for updates", error)
|
||||
return { hasUpdate: false, error: error instanceof Error ? error.message : "Unknown error" }
|
||||
} finally {
|
||||
this.checkingUpdate = false
|
||||
}
|
||||
}
|
||||
|
||||
async downloadAppUpdate(): Promise<void> {
|
||||
if (this.disabled || this.downloadingUpdate) {
|
||||
return
|
||||
}
|
||||
|
||||
this.downloadingUpdate = true
|
||||
|
||||
try {
|
||||
await this.autoUpdater.downloadUpdate()
|
||||
logger.info("App update download requested")
|
||||
} catch (error) {
|
||||
this.downloadingUpdate = false
|
||||
logger.error("Failed to download app update", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
quitAndInstall() {
|
||||
const mainWindow = WindowManager.getMainWindow()
|
||||
if (!mainWindow) return
|
||||
const handlers = callWindowExpose(mainWindow)
|
||||
logger.info("Quit and install triggered", { windowId: mainWindow?.id })
|
||||
WindowManager.destroyMainWindow()
|
||||
|
||||
handlers.updateDownloaded()
|
||||
})
|
||||
autoUpdater.on("error", (e) => {
|
||||
logger.error("Error while updating client", e)
|
||||
})
|
||||
autoUpdater.forceDevUpdateConfig = DEV
|
||||
setTimeout(() => {
|
||||
logger.info("Main window closed, quitting to install update")
|
||||
this.autoUpdater.quitAndInstall()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
if (appUpdaterConfig.app.autoCheckUpdate) {
|
||||
checkForAppUpdates().catch((err) => {
|
||||
logger.error("Error checking for updates", err)
|
||||
})
|
||||
private resolvePlatformCandidates() {
|
||||
const base = new Set<string>()
|
||||
base.add(process.platform)
|
||||
base.add(`${process.platform}-${process.arch}`)
|
||||
base.add(process.arch)
|
||||
|
||||
if (process.platform === "darwin") {
|
||||
base.add("mac")
|
||||
base.add("macos")
|
||||
}
|
||||
}, appUpdaterConfig.app.checkUpdateInterval)
|
||||
if (appUpdaterConfig.app.autoCheckUpdate) {
|
||||
checkForAppUpdates().catch((err) => {
|
||||
logger.error("Error checking for updates", err)
|
||||
|
||||
if (process.platform === "win32") {
|
||||
base.add("windows")
|
||||
base.add("win")
|
||||
}
|
||||
|
||||
return Array.from(base).map((value) => value.toLowerCase())
|
||||
}
|
||||
|
||||
private pickPlatformUpdate(
|
||||
platforms: PlatformUpdate[] | null | undefined,
|
||||
selected?: PlatformUpdate | null,
|
||||
): PlatformUpdate | null {
|
||||
if (!platforms || platforms.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
return selected
|
||||
}
|
||||
|
||||
const candidates = this.resolvePlatformCandidates()
|
||||
|
||||
const matched = platforms.find((platform) =>
|
||||
candidates.includes(platform.platform.toLowerCase()),
|
||||
)
|
||||
|
||||
return matched ?? platforms[0] ?? null
|
||||
}
|
||||
|
||||
private async handleAppDecision(payload: LatestReleasePayload): Promise<UpdateCheckResult> {
|
||||
const appDecision = payload.decision.app
|
||||
if (!appUpdaterConfig.enableCoreUpdate) {
|
||||
logger.info("Core app update disabled by configuration")
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
if (!appDecision) {
|
||||
logger.warn("App update decision missing app payload")
|
||||
return { hasUpdate: false, error: "App update metadata unavailable" }
|
||||
}
|
||||
|
||||
const platformUpdate = this.pickPlatformUpdate(
|
||||
appDecision.platforms,
|
||||
appDecision.selectedPlatform,
|
||||
)
|
||||
if (!platformUpdate) {
|
||||
logger.warn("No matching platform update found", {
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
})
|
||||
return { hasUpdate: false, error: "No installer available for this platform" }
|
||||
}
|
||||
|
||||
FollowUpdateProvider.setContext({ payload, platform: platformUpdate })
|
||||
logger.info("FollowUpdateProvider context set", { platform: platformUpdate.platform })
|
||||
|
||||
try {
|
||||
await this.autoUpdater.checkForUpdates()
|
||||
} catch (error) {
|
||||
logger.warn(
|
||||
"autoUpdater.checkForUpdates failed after preparing FollowUpdateProvider context",
|
||||
error,
|
||||
)
|
||||
return {
|
||||
hasUpdate: false,
|
||||
error: error instanceof Error ? error.message : "Failed to check app update",
|
||||
}
|
||||
} finally {
|
||||
FollowUpdateProvider.clearContext()
|
||||
}
|
||||
|
||||
return { hasUpdate: true }
|
||||
}
|
||||
|
||||
private async handleRendererDecision(payload: LatestReleasePayload): Promise<UpdateCheckResult> {
|
||||
if (!appUpdaterConfig.enableRenderHotUpdate) {
|
||||
logger.info("Renderer hot update disabled; falling back to app decision if present")
|
||||
if (payload.decision.app) {
|
||||
return this.handleAppDecision(payload)
|
||||
}
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
const manifest = this.renderer.extractManifest(payload)
|
||||
const eligibility = this.renderer.evaluateManifest(manifest)
|
||||
|
||||
switch (eligibility.status) {
|
||||
case RendererEligibilityStatus.NoManifest: {
|
||||
return { hasUpdate: false, error: eligibility.reason }
|
||||
}
|
||||
|
||||
case RendererEligibilityStatus.AlreadyCurrent: {
|
||||
if (eligibility.reason) {
|
||||
logger.info(eligibility.reason)
|
||||
}
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
case RendererEligibilityStatus.RequiresFullAppUpdate: {
|
||||
logger.info(
|
||||
eligibility.reason ||
|
||||
"Renderer payload requires main process update, delegating to app updater",
|
||||
)
|
||||
if (payload.decision.app) {
|
||||
return this.handleAppDecision(payload)
|
||||
}
|
||||
logger.warn("Renderer update requested full app upgrade but no app payload provided")
|
||||
return { hasUpdate: false, error: "Renderer update requires full app upgrade" }
|
||||
}
|
||||
|
||||
case RendererEligibilityStatus.Eligible: {
|
||||
const manifestToApply = eligibility.manifest as RendererManifest | undefined
|
||||
if (!manifestToApply) {
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
|
||||
try {
|
||||
await this.renderer.applyManifest(manifestToApply)
|
||||
return { hasUpdate: true }
|
||||
} catch (error) {
|
||||
logger.error("Renderer hot update failed", error)
|
||||
return {
|
||||
hasUpdate: false,
|
||||
error: error instanceof Error ? error.message : "Renderer hot update failed",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
return { hasUpdate: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private registerAutoUpdaterEvents() {
|
||||
this.autoUpdater.on("checking-for-update", () => {
|
||||
logger.info("autoUpdater: checking for update")
|
||||
})
|
||||
|
||||
this.autoUpdater.on("update-available", (info) => {
|
||||
logger.info("autoUpdater: update available", info)
|
||||
|
||||
if (appUpdaterConfig.app.autoDownloadUpdate && appUpdaterConfig.enableCoreUpdate) {
|
||||
void this.downloadAppUpdate().catch((error) =>
|
||||
logger.error("Automatic download failed", error),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
this.autoUpdater.on("update-not-available", (info) => {
|
||||
logger.info("autoUpdater: update not available", info)
|
||||
})
|
||||
|
||||
this.autoUpdater.on("download-progress", (progress) => {
|
||||
logger.info(`autoUpdater: download progress ${progress.percent.toFixed(2)}%`)
|
||||
})
|
||||
|
||||
this.autoUpdater.on("update-downloaded", () => {
|
||||
this.downloadingUpdate = false
|
||||
logger.info("autoUpdater: update downloaded")
|
||||
|
||||
const mainWindow = WindowManager.getMainWindow()
|
||||
if (!mainWindow) return
|
||||
|
||||
callWindowExpose(mainWindow).updateDownloaded()
|
||||
})
|
||||
|
||||
this.autoUpdater.on("error", (error) => {
|
||||
logger.error("autoUpdater: error", error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const autoUpdater = isWindows ? new WindowsUpdater() : defaultAutoUpdater
|
||||
const followUpdater = new FollowUpdater(autoUpdater)
|
||||
|
||||
export const registerUpdater = () => {
|
||||
followUpdater.register()
|
||||
}
|
||||
|
||||
export const checkForAppUpdates = (options: UpdateCheckOptions = {}) =>
|
||||
followUpdater.checkForUpdates(options)
|
||||
|
||||
export const quitAndInstall = () => followUpdater.quitAndInstall()
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
export interface GitHubReleasesItem {
|
||||
url: string
|
||||
assets_url: string
|
||||
upload_url: string
|
||||
html_url: string
|
||||
id: number
|
||||
author: Author
|
||||
node_id: string
|
||||
tag_name: string
|
||||
target_commitish: string
|
||||
name: string
|
||||
draft: boolean
|
||||
prerelease: boolean
|
||||
created_at: string
|
||||
published_at: string
|
||||
assets: AssetsItem[]
|
||||
tarball_url: string
|
||||
zipball_url: string
|
||||
body: string
|
||||
reactions?: Reactions
|
||||
mentions_count?: number
|
||||
}
|
||||
interface Author {
|
||||
login: string
|
||||
id: number
|
||||
node_id: string
|
||||
avatar_url: string
|
||||
gravatar_id: string
|
||||
url: string
|
||||
html_url: string
|
||||
followers_url: string
|
||||
following_url: string
|
||||
gists_url: string
|
||||
starred_url: string
|
||||
subscriptions_url: string
|
||||
organizations_url: string
|
||||
repos_url: string
|
||||
events_url: string
|
||||
received_events_url: string
|
||||
type: string
|
||||
user_view_type: string
|
||||
site_admin: boolean
|
||||
}
|
||||
interface AssetsItem {
|
||||
url: string
|
||||
id: number
|
||||
node_id: string
|
||||
name: string
|
||||
label: string | null
|
||||
uploader: Uploader
|
||||
content_type: string
|
||||
state: string
|
||||
size: number
|
||||
download_count: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
browser_download_url: string
|
||||
}
|
||||
interface Uploader {
|
||||
login: string
|
||||
id: number
|
||||
node_id: string
|
||||
avatar_url: string
|
||||
gravatar_id: string
|
||||
url: string
|
||||
html_url: string
|
||||
followers_url: string
|
||||
following_url: string
|
||||
gists_url: string
|
||||
starred_url: string
|
||||
subscriptions_url: string
|
||||
organizations_url: string
|
||||
repos_url: string
|
||||
events_url: string
|
||||
received_events_url: string
|
||||
type: string
|
||||
user_view_type: string
|
||||
site_admin: boolean
|
||||
}
|
||||
interface Reactions {
|
||||
url: string
|
||||
total_count: number
|
||||
"+1": number
|
||||
"-1": number
|
||||
laugh: number
|
||||
hooray: number
|
||||
confused: number
|
||||
heart: number
|
||||
rocket: number
|
||||
eyes: number
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import fs from "node:fs"
|
||||
|
||||
import { app } from "electron"
|
||||
import path from "pathe"
|
||||
import { major, minor } from "semver"
|
||||
|
||||
let _isSquirrelBuild: boolean | null = null
|
||||
export function isSquirrelBuild() {
|
||||
if (typeof _isSquirrelBuild === "boolean") {
|
||||
return _isSquirrelBuild
|
||||
}
|
||||
|
||||
// if it is squirrel build, there will be 'squirrel.exe'
|
||||
// otherwise it is in nsis web mode
|
||||
const files = fs.readdirSync(path.dirname(app.getPath("exe")))
|
||||
_isSquirrelBuild = files.some((it) => it.includes("squirrel.exe"))
|
||||
|
||||
return _isSquirrelBuild
|
||||
}
|
||||
|
||||
// The following scenario only requires updating the renderer, so the app update is skipped:
|
||||
// In x.y.z, the update of z will only trigger renderer hotfix, while the update of y requires updating the entire app.
|
||||
// The hotfix version of x.y.z-beta.0 adds a suffix number. It triggers renderer update. If the main code is modified and the entire app update needs to be triggered, the hotfix version adds a suffix like x.y.z-beta.0.app.
|
||||
// For subsequent minor versions that require updating the main code, the suffix .app needs to be added.
|
||||
|
||||
export const shouldUpdateApp = (currentVersion: string, nextVersion: string) => {
|
||||
if (nextVersion.includes("app")) {
|
||||
return true
|
||||
}
|
||||
// x.y.z 's y or x not equal, need update app
|
||||
const [x1, x2] = [safeMajor(currentVersion), safeMajor(nextVersion)]
|
||||
const [y1, y2] = [safeMinor(currentVersion), safeMinor(nextVersion)]
|
||||
|
||||
// Here, it is not determined whether it is a problem of version number downgrade; the updater will handle it automatically.
|
||||
if (x1 !== x2 || y1 !== y2) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const safeMajor = (version: string) => {
|
||||
try {
|
||||
return major(version)
|
||||
} catch {
|
||||
return "0.0.0"
|
||||
}
|
||||
}
|
||||
const safeMinor = (version: string) => {
|
||||
try {
|
||||
return minor(version)
|
||||
} catch {
|
||||
return "0.0.0"
|
||||
}
|
||||
}
|
||||
335
pnpm-lock.yaml
335
pnpm-lock.yaml
|
|
@ -7,8 +7,8 @@ settings:
|
|||
catalogs:
|
||||
default:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 0.3.78
|
||||
version: 0.3.78
|
||||
specifier: 0.3.79
|
||||
version: 0.3.79
|
||||
tailwindcss-uikit-colors:
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
|
|
@ -339,7 +339,7 @@ importers:
|
|||
version: 4.3.0
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow-app/readability':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/readability
|
||||
|
|
@ -457,7 +457,7 @@ importers:
|
|||
version: 3.0.2(electron@38.3.0)
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/database':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/internal/database
|
||||
|
|
@ -812,7 +812,7 @@ importers:
|
|||
version: 4.1.1(react@19.0.0)
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/components':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/components
|
||||
|
|
@ -1193,7 +1193,7 @@ importers:
|
|||
version: 6.2.1
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/tracker':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/internal/tracker
|
||||
|
|
@ -1688,7 +1688,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/configs':
|
||||
specifier: workspace:*
|
||||
version: link:../../configs
|
||||
|
|
@ -1700,7 +1700,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/constants':
|
||||
specifier: workspace:*
|
||||
version: link:../constants
|
||||
|
|
@ -1772,7 +1772,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/constants':
|
||||
specifier: workspace:*
|
||||
version: link:../constants
|
||||
|
|
@ -1803,7 +1803,7 @@ importers:
|
|||
version: 2.0.0(@types/node@24.8.1)
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@folo-services/drizzle':
|
||||
specifier: 0.1.34
|
||||
version: 0.1.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
|
|
@ -1833,7 +1833,7 @@ importers:
|
|||
dependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/configs':
|
||||
specifier: workspace:*
|
||||
version: link:../../configs
|
||||
|
|
@ -1882,7 +1882,7 @@ importers:
|
|||
devDependencies:
|
||||
'@follow-app/client-sdk':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@follow/configs':
|
||||
specifier: workspace:*
|
||||
version: link:../../configs
|
||||
|
|
@ -4358,32 +4358,29 @@ packages:
|
|||
'@floating-ui/utils@0.2.10':
|
||||
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
||||
|
||||
'@follow-app/client-sdk@0.3.78':
|
||||
resolution: {integrity: sha512-I8SPfimOqNcQZrN03wolVxj7IrOje3IuIxA9CA7ulS9i2K0GNhw8k64bhSjTGutkATstdzxTkCJYfS7wn9F0dQ==}
|
||||
'@follow-app/client-sdk@0.3.79':
|
||||
resolution: {integrity: sha512-w3EQEPjZMI638vzdB/klrldYvoh1LYWX6+5pMpkeLzC48hARUOfGi7dC8sVBM20/EXgvP/Wjkve637tjB7mKeg==}
|
||||
|
||||
'@folo-services/ai-tools@0.2.49':
|
||||
resolution: {integrity: sha512-QsKTW8N18812Thkdcc7wDTff3QkQxxTYHxHi1RM321jk4DbCq+mHlAr10Krwj0mRtKuULtqFHPm13udmfIv1Bw==}
|
||||
|
||||
'@folo-services/constants@0.1.41':
|
||||
resolution: {integrity: sha512-fXJ5DVWMgc4czW8i9JmVx3WckKhUksiwXkzzOClH0GePEOeS+DQ08o21UfZl1pBvhvhZm0pS+klHLljeBaRb1g==}
|
||||
|
||||
'@folo-services/constants@0.1.42':
|
||||
resolution: {integrity: sha512-GoHKg4Wdr+rGYGQauOhVFz+VyHZSiW1/9AGpIUa173a+HM5btvFN6e+Tu8ZNKl6Mu8J5M5GKIL0ditROp9Xv+A==}
|
||||
'@folo-services/constants@0.1.43':
|
||||
resolution: {integrity: sha512-vBauScJcR97H7uus0UdQ+g4rLFksRfWTjzIg8GcV3HDHBJOqISE5fxGUYzqkbEpbD6QqofNguVYQQrcXcIPWfQ==}
|
||||
|
||||
'@folo-services/drizzle@0.1.34':
|
||||
resolution: {integrity: sha512-p6dsveNwXwNxmy+8+FHHKiFjVFXwc7yx7c4902k13hd1vcBihxiWUD4MdCwAcQTAPSJ3dYx1UZojHSdyiXwqnw==}
|
||||
|
||||
'@folo-services/drizzle@0.1.35':
|
||||
resolution: {integrity: sha512-b+5OPwjKW3gnf0lkLj7PuhjLCldD9TItXNWRwIvJrPYmIGlrQmUiKgQIuLR8dsksF9L7w8IcIi4Vt40Qppx7nQ==}
|
||||
'@folo-services/drizzle@0.1.36':
|
||||
resolution: {integrity: sha512-7BTGJXDPE7m5cs9mZIiYbpHluqPPrUVV0MtZxxkmbve9BlIWDij1Yga4r43CpiFCOK/a0JqMcmkqmokRJfKVxw==}
|
||||
|
||||
'@folo-services/exceptions@0.1.19':
|
||||
resolution: {integrity: sha512-rXgLssE3r3w2WzC3knCX9nYe0cszHXpYwAllrYOsPpzjQSHWRwJ6LuJyt0xlvdeX/9i8KQ/UYgf4to6Abt2whg==}
|
||||
|
||||
'@folo-services/exceptions@0.1.20':
|
||||
resolution: {integrity: sha512-iuV6F22XI6kvSSVQRTCoS/wfJnPGvI3XQbA3YQGgXa8fT28SE+8LBGCyAj0rqbfnXlXdpxZE/IooXdpJyxkp0Q==}
|
||||
'@folo-services/exceptions@0.1.21':
|
||||
resolution: {integrity: sha512-bEgKOFKAf0INIJUMSHqdiOvEE3KV096fYk+DeO5em3YkGfPY/l4Fcy0XeOOKJJZJQbQak4Sry7extFbfSmlb/Q==}
|
||||
|
||||
'@folo-services/shared@0.0.34':
|
||||
resolution: {integrity: sha512-T0gZRBlDVP9WLG0Dg8tLgWdk+TVjbdKfSvRHEyBY+YioQ1LO4vulN8ddCv1oBvMQxl0iESY9mnmB4ua9iGGkyQ==}
|
||||
'@folo-services/shared@0.0.35':
|
||||
resolution: {integrity: sha512-pvcuDEg82ZxgaUlwtx16DBV3TRsZuFI4g4DuNaRejnZTLnW8XswG56TZloe+OwsbHUUzh4mOZBVM3PYUVpeayA==}
|
||||
|
||||
'@fontsource/sn-pro@5.2.5':
|
||||
resolution: {integrity: sha512-rBdBv/0ygj6bkO7xDMMFpwobLdSrcQ2Jncb6DIwdeYGoAgeWkQRwVYhGDKasfLjEYCNYxrqr6wsXsM9+aU39RA==}
|
||||
|
|
@ -4926,9 +4923,6 @@ packages:
|
|||
'@napi-rs/wasm-runtime@0.2.12':
|
||||
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==}
|
||||
|
||||
'@napi-rs/wasm-runtime@1.0.7':
|
||||
resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==}
|
||||
|
||||
'@noble/ciphers@2.0.1':
|
||||
resolution: {integrity: sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
|
@ -5272,8 +5266,12 @@ packages:
|
|||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.1.0
|
||||
|
||||
'@oxc-project/types@0.95.0':
|
||||
resolution: {integrity: sha512-vACy7vhpMPhjEJhULNxrdR0D943TkA/MigMpJCHmBHvMXxRStRi/dPtTlfQ3uDwWSzRpT8z+7ImjZVf8JWBocQ==}
|
||||
'@oxc-project/runtime@0.71.0':
|
||||
resolution: {integrity: sha512-QwoF5WUXIGFQ+hSxWEib4U/aeLoiDN9JlP18MnBgx9LLPRDfn1iICtcow7Jgey6HLH4XFceWXQD5WBJ39dyJcw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@oxc-project/types@0.71.0':
|
||||
resolution: {integrity: sha512-5CwQ4MI+P4MQbjLWXgNurA+igGwu/opNetIE13LBs9+V93R64MLvDKOOLZIXSzEfovU3Zef3q3GjPnMTgJTn2w==}
|
||||
|
||||
'@peculiar/asn1-android@2.5.0':
|
||||
resolution: {integrity: sha512-t8A83hgghWQkcneRsgGs2ebAlRe54ns88p7ouv8PW2tzF1nAW4yHcL4uZKrFpIU+uszIRzTkcCuie37gpkId0A==}
|
||||
|
|
@ -6231,98 +6229,75 @@ packages:
|
|||
resolution: {integrity: sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-bfgKYhFiXJALeA/riil908+2vlyWGdwa7Ju5S+JgWZYdR4jtiPOGdM6WLfso1dojCh+4ZWeiTwPeV9IKQEX+4g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-xjCv4CRVsSnnIxTuyH1RDJl5OEQ1c9JYOwfDAHddjJDxCw46ZX9q80+xq7Eok7KC4bRSZudMJllkvOKv0T9SeA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-Mp0/gqiPdepHjjVm7e0yL1acWvI0rJVVFQEADSezvAjon9sjQ7CEg9JnXICD4B1YrPmN9qV/e7cQZCp87tTV4w==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-ddcO9TD3D/CLUa/l8GO8LHzBOaZqWg5ClMy3jICoxwCuoz47h9dtqPsIeTiB6yR501LQTeDsjA4lIFd7u3Ljfw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-40re4rMNrsi57oavRzIOpRGmg3QRlW6Ea8Q3znaqgOuJuKVrrm2bIQInTfkZJG7a4/5YMX7T951d0+toGLTdCA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-MBTWdrzW9w+UMYDUvnEuh0pQvLENkl2Sis15fHTfHVW7ClbGuez+RWopZudIDEGkpZXdeI4CkRXk+vdIIebrmg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-8BDM939bbMariZupiHp3OmP5N+LXPT4mULA0hZjDaq970PCxv4krZOSMG+HkWUUwmuQROtV+/00xw39EO0P+8g==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-4YgoCFiki1HR6oSg+GxxfzfnVCesQxLF1LEnw9uXS/MpBmuog0EOO2rYfy69rWP4tFZL9IWp6KEfGZLrZ7aUog==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-sntsPaPgrECpBB/+2xrQzVUt0r493TMPI+4kWRMhvMsmrxOqH1Ep5lM0Wua/ZdbfZNwm1aVa5pcESQfNfM4Fhw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-LE1gjAwQRrbCOorJJ7LFr10s5vqYf5a00V5Ea9wXcT2+56n5YosJkcp8eQ12FxRBv2YX8dsdQJb+ZTtYJwb6XQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-5clBW/I+er9F2uM1OFjJFWX86y7Lcy0M+NqsN4s3o07W+8467Zk8oQa4B45vdaXoNUF/yqIAgKkA/OEdQDxZqA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-tdy8ThO/fPp40B81v0YK3QC+KODOmzJzSUOO37DinQxzlTJ026gqUSOM8tzlVixRbQJltgVDCTYF8HNPRErQTA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-wv+rnAfQDk9p/CheX8/Kmqk2o1WaFa4xhWI9gOyDMk/ljvOX0u0ubeM8nI1Qfox7Tnh71eV5AjzSePXUhFOyOg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-lS082ROBWdmOyVY/0YB3JmsiClaWoxvC+dA8/rbhyB9VLkvVEaihLEOr4CYmrMse151C4+S6hCw6oa1iewox7g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-gxD0/xhU4Py47IH3bKZbWtvB99tMkUPGPJFRfSc5UB9Osoje0l0j1PPbxpUtXIELurYCqwLBKXIMTQGifox1BQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-Hi73aYY0cBkr1/SvNQqH8Cd+rSV6S9RB5izCv0ySBcRnd/Wfn5plguUoGYwBnhHgFbh6cPw9m2dUVBR6BG1gxA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-HotuVe3XUjDwqqEMbm3o3IRkP9gdm8raY/btd/6KE3JGLF/cv4+3ff1l6nOhAZI8wulWDPEXPtE7v+HQEaTXnA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-fljEqbO7RHHogNDxYtTzr+GNjlfOx21RUyGmF+NrkebZ8emYYiIqzPxsaMZuRx0rgZmVmliOzEp86/CQFDKhJQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-ZJDB7lkuZE9XUnWQSYrBObZxczut+8FZ5pdanm8nNS1DAo8zsrPuvGwn+U3fwU98WaiFsNrA4XHngesCGr8tEQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-8Cx+ucbd8n2dIr21FqBh6rUvTVL0uTgEtKR7l+MUZ5BgY4dFh1e4mPVX8oqmoYwOxBiXrsD2JIOCz4AyKLKxWA==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-zyzAjItHPUmxg6Z8SyRhLdXlJn3/D9KL5b9mObUrBHhWS/GwRH4665xCiFqeuktAhhWutqfc+rOV2LjK4VYQGQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-Vhq5vikrVDxAa75fxsyqj0c0Y/uti/TwshXI71Xb8IeUQJOBnmLUsn5dgYf5ljpYYkNa0z9BPAvUDIDMmyDi+w==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-wODcGzlfxqS6D7BR0srkJk3drPwXYLu7jPHN27ce2c4PUnVVmJnp9mJzUQGT4LpmHmmVdMZ+P6hKvyTGBzc1CA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-lN7RIg9Iugn08zP2aZN9y/MIdG8iOOCE93M1UrFlrxMTqPf8X+fDzmR/OKhTSd1A2pYNipZHjyTcb5H8kyQSow==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-wiU40G1nQo9rtfvF9jLbl79lUgjfaD/LTyUEw2Wg/gdF5OhjzpKMVugZQngO+RNdwYaNj+Fs+kWBWfp4VXPMHA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-7/7cLIn48Y+EpQ4CePvf8reFl63F15yPUlg4ZAhl+RXJIfydkdak1WD8Ir3AwAO+bJBXzrfNL+XQbxm0mcQZmw==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.38':
|
||||
resolution: {integrity: sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==}
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.45':
|
||||
resolution: {integrity: sha512-Le9ulGCrD8ggInzWw/k2J8QcbPz7eGIOWqfJ2L+1R0Opm7n6J37s2hiDWlh6LJN0Lk9L5sUzMvRHKW7UxBZsQA==}
|
||||
'@rolldown/pluginutils@1.0.0-beta.9-commit.d91dfb5':
|
||||
resolution: {integrity: sha512-8sExkWRK+zVybw3+2/kBkYBFeLnEUWz1fT7BLHplpzmtqkOfTbAQ9gkt4pzwGIIZmg4Qn5US5ACjUBenrhezwQ==}
|
||||
|
||||
'@rollup/plugin-babel@5.3.1':
|
||||
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
||||
|
|
@ -14840,9 +14815,8 @@ packages:
|
|||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
rolldown@1.0.0-beta.45:
|
||||
resolution: {integrity: sha512-iMmuD72XXLf26Tqrv1cryNYLX6NNPLhZ3AmNkSf8+xda0H+yijjGJ+wVT9UdBUHOpKzq9RjKtQKRCWoEKQQBZQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
rolldown@1.0.0-beta.9-commit.d91dfb5:
|
||||
resolution: {integrity: sha512-FHkj6gGEiEgmAXQchglofvUUdwj2Oiw603Rs+zgFAnn9Cb7T7z3fiaEc0DbN3ja4wYkW6sF2rzMEtC1V4BGx/g==}
|
||||
hasBin: true
|
||||
|
||||
rollup@2.79.2:
|
||||
|
|
@ -21348,12 +21322,12 @@ snapshots:
|
|||
|
||||
'@floating-ui/utils@0.2.10': {}
|
||||
|
||||
'@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@follow-app/client-sdk@0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.42
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@folo-services/shared': 0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
zod: 4.1.12
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -21397,12 +21371,12 @@ snapshots:
|
|||
- svelte
|
||||
- vue
|
||||
|
||||
'@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@follow-app/client-sdk@0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.42
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@folo-services/shared': 0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
zod: 4.1.12
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -21446,12 +21420,12 @@ snapshots:
|
|||
- svelte
|
||||
- vue
|
||||
|
||||
'@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@follow-app/client-sdk@0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.42
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@folo-services/shared': 0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
zod: 4.1.12
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -21495,12 +21469,12 @@ snapshots:
|
|||
- svelte
|
||||
- vue
|
||||
|
||||
'@follow-app/client-sdk@0.3.78(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@follow-app/client-sdk@0.3.79(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.42
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/shared': 0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@folo-services/shared': 0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)
|
||||
better-auth: 1.3.28(better-sqlite3@12.4.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
zod: 4.1.12
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -21584,11 +21558,7 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/constants@0.1.41':
|
||||
dependencies:
|
||||
zod: 4.1.12
|
||||
|
||||
'@folo-services/constants@0.1.42':
|
||||
'@folo-services/constants@0.1.43':
|
||||
dependencies:
|
||||
zod: 4.1.12
|
||||
|
||||
|
|
@ -21674,9 +21644,9 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
'@folo-services/drizzle@0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
dependencies:
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21715,9 +21685,9 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
'@folo-services/drizzle@0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
dependencies:
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21756,9 +21726,9 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
'@folo-services/drizzle@0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
dependencies:
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21797,9 +21767,9 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/drizzle@0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
'@folo-services/drizzle@0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)':
|
||||
dependencies:
|
||||
'@folo-services/exceptions': 0.1.20
|
||||
'@folo-services/exceptions': 0.1.21
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21840,12 +21810,12 @@ snapshots:
|
|||
|
||||
'@folo-services/exceptions@0.1.19': {}
|
||||
|
||||
'@folo-services/exceptions@0.1.20': {}
|
||||
'@folo-services/exceptions@0.1.21': {}
|
||||
|
||||
'@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
'@folo-services/shared@0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.41
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.0)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.0)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21883,10 +21853,10 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
'@folo-services/shared@0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.41
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.4)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.15.0(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.4)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21924,10 +21894,10 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
'@folo-services/shared@0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.41
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0)(utf-8-validate@6.0.5))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@6.0.5))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -21965,10 +21935,10 @@ snapshots:
|
|||
- sql.js
|
||||
- sqlite3
|
||||
|
||||
'@folo-services/shared@0.0.34(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
'@folo-services/shared@0.0.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)(pg@8.16.3)':
|
||||
dependencies:
|
||||
'@folo-services/constants': 0.1.41
|
||||
'@folo-services/drizzle': 0.1.35(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@folo-services/constants': 0.1.43
|
||||
'@folo-services/drizzle': 0.1.36(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(hono@4.9.8)(kysely@0.28.8)
|
||||
'@hono/zod-openapi': 1.1.4(hono@4.9.8)(zod@4.1.12)
|
||||
drizzle-orm: 0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3)
|
||||
drizzle-zod: 0.8.3(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(better-sqlite3@12.4.1)(expo-sqlite@15.2.12(expo@53.0.12(@babel/core@7.28.5)(@expo/metro-runtime@5.0.4(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0)))(bufferutil@4.0.9)(graphql@16.8.1)(react-native-webview@13.16.0(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(react-native@0.79.6(@babel/core@7.28.5)(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.0.0))(react@19.0.0))(kysely@0.28.8)(pg@8.16.3))(zod@4.1.12)
|
||||
|
|
@ -22732,13 +22702,6 @@ snapshots:
|
|||
'@tybys/wasm-util': 0.10.1
|
||||
optional: true
|
||||
|
||||
'@napi-rs/wasm-runtime@1.0.7':
|
||||
dependencies:
|
||||
'@emnapi/core': 1.6.0
|
||||
'@emnapi/runtime': 1.6.0
|
||||
'@tybys/wasm-util': 0.10.1
|
||||
optional: true
|
||||
|
||||
'@noble/ciphers@2.0.1': {}
|
||||
|
||||
'@noble/hashes@2.0.1': {}
|
||||
|
|
@ -23212,7 +23175,9 @@ snapshots:
|
|||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0)
|
||||
|
||||
'@oxc-project/types@0.95.0': {}
|
||||
'@oxc-project/runtime@0.71.0': {}
|
||||
|
||||
'@oxc-project/types@0.71.0': {}
|
||||
|
||||
'@peculiar/asn1-android@2.5.0':
|
||||
dependencies:
|
||||
|
|
@ -24368,7 +24333,7 @@ snapshots:
|
|||
debug: 2.6.9
|
||||
invariant: 2.2.4
|
||||
metro: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
metro-config: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
metro-config: 0.82.4(bufferutil@4.0.9)
|
||||
metro-core: 0.82.4
|
||||
semver: 7.7.3
|
||||
transitivePeerDependencies:
|
||||
|
|
@ -24535,53 +24500,47 @@ snapshots:
|
|||
'@resvg/resvg-js-win32-ia32-msvc': 2.6.2
|
||||
'@resvg/resvg-js-win32-x64-msvc': 2.6.2
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.45':
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.0.0-beta.45':
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.0.0-beta.45':
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.0.0-beta.45':
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.45':
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.0.0-beta.45':
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.45':
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.45':
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.0.0-beta.45':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.0.0-beta.45':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.45':
|
||||
'@rolldown/binding-wasm32-wasi@1.0.0-beta.9-commit.d91dfb5':
|
||||
dependencies:
|
||||
'@napi-rs/wasm-runtime': 1.0.7
|
||||
'@napi-rs/wasm-runtime': 0.2.12
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.45':
|
||||
'@rolldown/binding-win32-arm64-msvc@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.45':
|
||||
'@rolldown/binding-win32-ia32-msvc@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.45':
|
||||
'@rolldown/binding-win32-x64-msvc@1.0.0-beta.9-commit.d91dfb5':
|
||||
optional: true
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.38': {}
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.45': {}
|
||||
'@rolldown/pluginutils@1.0.0-beta.9-commit.d91dfb5': {}
|
||||
|
||||
'@rollup/plugin-babel@5.3.1(@babel/core@7.28.4)(@types/babel__core@7.20.5)(rollup@2.79.2)':
|
||||
dependencies:
|
||||
|
|
@ -32503,22 +32462,6 @@ snapshots:
|
|||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
metro-config@0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5):
|
||||
dependencies:
|
||||
connect: 3.7.0
|
||||
cosmiconfig: 5.2.1
|
||||
flow-enums-runtime: 0.0.6
|
||||
jest-validate: 29.7.0
|
||||
metro: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
metro-cache: 0.82.4
|
||||
metro-core: 0.82.4
|
||||
metro-runtime: 0.82.4
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
optional: true
|
||||
|
||||
metro-core@0.82.4:
|
||||
dependencies:
|
||||
flow-enums-runtime: 0.0.6
|
||||
|
|
@ -32704,7 +32647,7 @@ snapshots:
|
|||
metro-babel-transformer: 0.82.4
|
||||
metro-cache: 0.82.4
|
||||
metro-cache-key: 0.82.4
|
||||
metro-config: 0.82.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)
|
||||
metro-config: 0.82.4(bufferutil@4.0.9)
|
||||
metro-core: 0.82.4
|
||||
metro-file-map: 0.82.4
|
||||
metro-resolver: 0.82.4
|
||||
|
|
@ -35274,7 +35217,7 @@ snapshots:
|
|||
sprintf-js: 1.1.3
|
||||
optional: true
|
||||
|
||||
rolldown-plugin-dts@0.16.12(rolldown@1.0.0-beta.45)(typescript@5.9.3):
|
||||
rolldown-plugin-dts@0.16.12(rolldown@1.0.0-beta.9-commit.d91dfb5)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/generator': 7.28.3
|
||||
'@babel/parser': 7.28.4
|
||||
|
|
@ -35285,32 +35228,32 @@ snapshots:
|
|||
dts-resolver: 2.1.2
|
||||
get-tsconfig: 4.12.0
|
||||
magic-string: 0.30.19
|
||||
rolldown: 1.0.0-beta.45
|
||||
rolldown: 1.0.0-beta.9-commit.d91dfb5
|
||||
optionalDependencies:
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- oxc-resolver
|
||||
- supports-color
|
||||
|
||||
rolldown@1.0.0-beta.45:
|
||||
rolldown@1.0.0-beta.9-commit.d91dfb5:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.95.0
|
||||
'@rolldown/pluginutils': 1.0.0-beta.45
|
||||
'@oxc-project/runtime': 0.71.0
|
||||
'@oxc-project/types': 0.71.0
|
||||
'@rolldown/pluginutils': 1.0.0-beta.9-commit.d91dfb5
|
||||
ansis: 4.2.0
|
||||
optionalDependencies:
|
||||
'@rolldown/binding-android-arm64': 1.0.0-beta.45
|
||||
'@rolldown/binding-darwin-arm64': 1.0.0-beta.45
|
||||
'@rolldown/binding-darwin-x64': 1.0.0-beta.45
|
||||
'@rolldown/binding-freebsd-x64': 1.0.0-beta.45
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.45
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.45
|
||||
'@rolldown/binding-linux-arm64-musl': 1.0.0-beta.45
|
||||
'@rolldown/binding-linux-x64-gnu': 1.0.0-beta.45
|
||||
'@rolldown/binding-linux-x64-musl': 1.0.0-beta.45
|
||||
'@rolldown/binding-openharmony-arm64': 1.0.0-beta.45
|
||||
'@rolldown/binding-wasm32-wasi': 1.0.0-beta.45
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.45
|
||||
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.45
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.45
|
||||
'@rolldown/binding-darwin-arm64': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-darwin-x64': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-freebsd-x64': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-linux-arm64-musl': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-linux-x64-gnu': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-linux-x64-musl': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-wasm32-wasi': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.9-commit.d91dfb5
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.9-commit.d91dfb5
|
||||
|
||||
rollup@2.79.2:
|
||||
optionalDependencies:
|
||||
|
|
@ -36441,8 +36384,8 @@ snapshots:
|
|||
diff: 8.0.2
|
||||
empathic: 2.0.0
|
||||
hookable: 5.5.3
|
||||
rolldown: 1.0.0-beta.45
|
||||
rolldown-plugin-dts: 0.16.12(rolldown@1.0.0-beta.45)(typescript@5.9.3)
|
||||
rolldown: 1.0.0-beta.9-commit.d91dfb5
|
||||
rolldown-plugin-dts: 0.16.12(rolldown@1.0.0-beta.9-commit.d91dfb5)(typescript@5.9.3)
|
||||
semver: 7.7.3
|
||||
tinyexec: 1.0.1
|
||||
tinyglobby: 0.2.15
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ packages:
|
|||
- "!**/example/**"
|
||||
|
||||
catalog:
|
||||
"@follow-app/client-sdk": 0.3.78
|
||||
"@follow-app/client-sdk": 0.3.79
|
||||
tailwindcss-uikit-colors: 1.0.0
|
||||
typescript: 5.9.3
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue