@stacksjs/actions 0.75.177 → 0.75.178

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@ export declare function validateAndroidMobileConfig(config: AndroidMobileConfig)
16
16
  export declare const CRAFT_ANDROID_FLOORS: {
17
17
  /** The native app shell: tabs, paths to screens, the app script, synchronous stores. */
18
18
  nativeShell: '0.0.169';
19
+ bluetooth: '0.0.178';
19
20
  /** Health Connect for native screens (workouts, sleep, heart rate, mindful, nutrition). */
20
21
  healthConnect: '0.0.169';
21
22
  /** WorkManager background refresh for the app script. */
@@ -40,6 +41,7 @@ export declare interface CraftAndroidConfig {
40
41
  urlSchemes?: string[]
41
42
  appIconPath?: string
42
43
  googleServicesFile?: string
44
+ enableBluetooth?: boolean
43
45
  enableHealthConnect?: boolean
44
46
  renderer?: AndroidMobileConfig['renderer']
45
47
  nativeScreens?: Record<string, string>
@@ -1 +1 @@
1
- import{NATIVE_APP_ROUTE,normalizeMobileUrl}from"./ios-config";const CAPABILITY_KEYS={speechRecognition:"enableSpeechRecognition",haptics:"enableHaptics",share:"enableShare",camera:"enableCamera",biometric:"enableBiometric",pushNotifications:"enablePushNotifications",secureStorage:"enableSecureStorage",geolocation:"enableGeolocation",backgroundLocation:"enableBackgroundLocation",keepAwake:"enableKeepAwake",deepLinks:"enableDeepLinks",healthConnect:"enableHealthConnect",localNetwork:"enableLocalNetwork"};export const CRAFT_ANDROID_FLOORS={nativeShell:"0.0.169",healthConnect:"0.0.169",backgroundRefresh:"0.0.169",appBundle:"0.0.169"};export function androidCraftFeatures(config,options={}){const features=[];if(config.renderer==="native"&&Object.keys(config.nativeScreens??{}).length)features.push("nativeShell");if(config.capabilities?.healthConnect&&config.renderer==="native")features.push("healthConnect");if(config.backgroundRefresh?.enabled)features.push("backgroundRefresh");if(options.appBundle)features.push("appBundle");return features}export function assertCraftSupportsAndroid(config,version,source,options={}){const missing=androidCraftFeatures(config,options).filter((feature)=>!Bun.semver.satisfies(version,`>=${CRAFT_ANDROID_FLOORS[feature]}`));if(!missing.length)return;const needed=missing.map((feature)=>CRAFT_ANDROID_FLOORS[feature]).reduce((max,next)=>Bun.semver.order(next,max)>0?next:max,"0.0.0");throw Error(`The Craft Android builder is craft-native ${version} (${source}), which would build the app without ${missing.map((feature)=>`${feature} (needs >= ${CRAFT_ANDROID_FLOORS[feature]})`).join(", ")}. Install craft-native >= ${needed}: look for an older copy nested under @stacksjs/mobile in bun.lock, or raise the app's own craft-native pin.`)}export function toCraftAndroidConfig(config){const devServerURL=normalizeMobileUrl(config.url),trustedOrigins=new Set(config.trustedOrigins??[]);if(devServerURL)trustedOrigins.add(new URL(devServerURL).origin);const native=config.renderer==="native",craft={appName:config.appName,packageName:config.packageName,version:config.version,versionCode:config.versionCode,minSdk:config.minSdk,targetSdk:config.targetSdk,darkMode:config.darkMode,appearance:config.appearance,backgroundColor:config.backgroundColor,backgroundColorDark:config.backgroundColorDark,devServerURL,trustedOrigins:[...trustedOrigins],urlSchemes:config.urlSchemes,appIconPath:config.appIcon,googleServicesFile:config.googleServicesFile,renderer:config.renderer,nativeScreens:native?config.nativeScreens:void 0,nativeApp:native&&config.nativeApp?NATIVE_APP_ROUTE:void 0,tabs:native?config.tabs:void 0,backgroundRefresh:native?config.backgroundRefresh:void 0,healthConnect:config.capabilities?.healthConnect?config.healthConnect:void 0,privacyPolicyURL:config.privacyPolicyUrl};for(const[key,nativeKey]of Object.entries(CAPABILITY_KEYS)){const enabled=config.capabilities?.[key];if(enabled!==void 0)craft[nativeKey]=enabled}if(config.capabilities?.backgroundLocation)craft.enableGeolocation=!0;for(const key of Object.keys(craft))if(craft[key]===void 0)delete craft[key];return craft}export function validateAndroidMobileConfig(config){if(!config.appName?.trim())throw Error("config/mobile.ts must define android.appName");if(!/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/.test(config.packageName))throw Error(`Invalid Android package name: ${config.packageName}`);if(config.renderer!==void 0&&config.renderer!=="web"&&config.renderer!=="native")throw Error(`android.renderer must be 'web' or 'native', not ${String(config.renderer)}`);if(config.renderer==="native"){if(!Object.keys(config.nativeScreens??{}).length)throw Error("android.renderer 'native' draws every screen natively: list them in android.nativeScreens");if(config.webAssets)throw Error("android.renderer 'native' has no web view to show android.webAssets in: set android.url to the app's site instead");if(config.fallbackWebAssets)throw Error("android.fallbackWebAssets is the web view's offline page; android.renderer 'native' has no web view");if(!config.url)throw Error("android.renderer 'native' needs android.url: the app's site, where its API answers")}else{if(config.url&&config.webAssets)throw Error("Choose either android.url or android.webAssets in config/mobile.ts, not both");if(!config.url&&!config.webAssets)throw Error("config/mobile.ts must define android.url or android.webAssets");if(config.fallbackWebAssets&&!config.url)throw Error("android.fallbackWebAssets requires android.url")}if(config.nativeApp&&config.renderer!=="native")throw Error("android.nativeApp runs beside native screens: set android.renderer to 'native'");for(const tab of config.tabs??[])if(!tab.id?.startsWith("/"))throw Error(`An android.tabs entry needs an id that is an app path, like /m (got ${String(tab.id)})`);if(config.url){const normalized=normalizeMobileUrl(config.url),url=new URL(normalized),isLocal=["localhost","127.0.0.1","10.0.2.2"].includes(url.hostname);if(url.protocol!=="https:"&&!isLocal)throw Error("android.url must use HTTPS outside local development")}if(config.capabilities?.healthConnect&&(config.minSdk??26)<26)throw Error("Android Health Connect requires android.minSdk 26 or newer");if(config.healthConnect&&!config.capabilities?.healthConnect)throw Error("android.healthConnect lists Health Connect data, but android.capabilities.healthConnect is off");const minutes=config.backgroundRefresh?.minimumIntervalMinutes;if(minutes!==void 0&&(!Number.isFinite(minutes)||minutes<15))throw Error("android.backgroundRefresh.minimumIntervalMinutes is at least 15 (WorkManager's shortest period)");for(const scheme of config.urlSchemes??[])if(!/^[a-z][a-z0-9+.-]*$/i.test(scheme))throw Error(`Invalid Android URL scheme: ${scheme}`)}
1
+ import{NATIVE_APP_ROUTE,normalizeMobileUrl}from"./ios-config";const CAPABILITY_KEYS={speechRecognition:"enableSpeechRecognition",haptics:"enableHaptics",share:"enableShare",camera:"enableCamera",biometric:"enableBiometric",pushNotifications:"enablePushNotifications",secureStorage:"enableSecureStorage",geolocation:"enableGeolocation",backgroundLocation:"enableBackgroundLocation",keepAwake:"enableKeepAwake",deepLinks:"enableDeepLinks",healthConnect:"enableHealthConnect",bluetooth:"enableBluetooth",localNetwork:"enableLocalNetwork"};export const CRAFT_ANDROID_FLOORS={nativeShell:"0.0.169",bluetooth:"0.0.178",healthConnect:"0.0.169",backgroundRefresh:"0.0.169",appBundle:"0.0.169"};export function androidCraftFeatures(config,options={}){const features=[];if(config.renderer==="native"&&Object.keys(config.nativeScreens??{}).length)features.push("nativeShell");if(config.capabilities?.bluetooth)features.push("bluetooth");if(config.capabilities?.healthConnect&&config.renderer==="native")features.push("healthConnect");if(config.backgroundRefresh?.enabled)features.push("backgroundRefresh");if(options.appBundle)features.push("appBundle");return features}export function assertCraftSupportsAndroid(config,version,source,options={}){const missing=androidCraftFeatures(config,options).filter((feature)=>!Bun.semver.satisfies(version,`>=${CRAFT_ANDROID_FLOORS[feature]}`));if(!missing.length)return;const needed=missing.map((feature)=>CRAFT_ANDROID_FLOORS[feature]).reduce((max,next)=>Bun.semver.order(next,max)>0?next:max,"0.0.0");throw Error(`The Craft Android builder is craft-native ${version} (${source}), which would build the app without ${missing.map((feature)=>`${feature} (needs >= ${CRAFT_ANDROID_FLOORS[feature]})`).join(", ")}. Install craft-native >= ${needed}: look for an older copy nested under @stacksjs/mobile in bun.lock, or raise the app's own craft-native pin.`)}export function toCraftAndroidConfig(config){const devServerURL=normalizeMobileUrl(config.url),trustedOrigins=new Set(config.trustedOrigins??[]);if(devServerURL)trustedOrigins.add(new URL(devServerURL).origin);const native=config.renderer==="native",craft={appName:config.appName,packageName:config.packageName,version:config.version,versionCode:config.versionCode,minSdk:config.minSdk,targetSdk:config.targetSdk,darkMode:config.darkMode,appearance:config.appearance,backgroundColor:config.backgroundColor,backgroundColorDark:config.backgroundColorDark,devServerURL,trustedOrigins:[...trustedOrigins],urlSchemes:config.urlSchemes,appIconPath:config.appIcon,googleServicesFile:config.googleServicesFile,renderer:config.renderer,nativeScreens:native?config.nativeScreens:void 0,nativeApp:native&&config.nativeApp?NATIVE_APP_ROUTE:void 0,tabs:native?config.tabs:void 0,backgroundRefresh:native?config.backgroundRefresh:void 0,healthConnect:config.capabilities?.healthConnect?config.healthConnect:void 0,privacyPolicyURL:config.privacyPolicyUrl};for(const[key,nativeKey]of Object.entries(CAPABILITY_KEYS)){const enabled=config.capabilities?.[key];if(enabled!==void 0)craft[nativeKey]=enabled}if(config.capabilities?.backgroundLocation)craft.enableGeolocation=!0;for(const key of Object.keys(craft))if(craft[key]===void 0)delete craft[key];return craft}export function validateAndroidMobileConfig(config){if(!config.appName?.trim())throw Error("config/mobile.ts must define android.appName");if(!/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/.test(config.packageName))throw Error(`Invalid Android package name: ${config.packageName}`);if(config.renderer!==void 0&&config.renderer!=="web"&&config.renderer!=="native")throw Error(`android.renderer must be 'web' or 'native', not ${String(config.renderer)}`);if(config.renderer==="native"){if(!Object.keys(config.nativeScreens??{}).length)throw Error("android.renderer 'native' draws every screen natively: list them in android.nativeScreens");if(config.webAssets)throw Error("android.renderer 'native' has no web view to show android.webAssets in: set android.url to the app's site instead");if(config.fallbackWebAssets)throw Error("android.fallbackWebAssets is the web view's offline page; android.renderer 'native' has no web view");if(!config.url)throw Error("android.renderer 'native' needs android.url: the app's site, where its API answers")}else{if(config.url&&config.webAssets)throw Error("Choose either android.url or android.webAssets in config/mobile.ts, not both");if(!config.url&&!config.webAssets)throw Error("config/mobile.ts must define android.url or android.webAssets");if(config.fallbackWebAssets&&!config.url)throw Error("android.fallbackWebAssets requires android.url")}if(config.nativeApp&&config.renderer!=="native")throw Error("android.nativeApp runs beside native screens: set android.renderer to 'native'");for(const tab of config.tabs??[])if(!tab.id?.startsWith("/"))throw Error(`An android.tabs entry needs an id that is an app path, like /m (got ${String(tab.id)})`);if(config.url){const normalized=normalizeMobileUrl(config.url),url=new URL(normalized),isLocal=["localhost","127.0.0.1","10.0.2.2"].includes(url.hostname);if(url.protocol!=="https:"&&!isLocal)throw Error("android.url must use HTTPS outside local development")}if(config.capabilities?.healthConnect&&(config.minSdk??26)<26)throw Error("Android Health Connect requires android.minSdk 26 or newer");if(config.healthConnect&&!config.capabilities?.healthConnect)throw Error("android.healthConnect lists Health Connect data, but android.capabilities.healthConnect is off");const minutes=config.backgroundRefresh?.minimumIntervalMinutes;if(minutes!==void 0&&(!Number.isFinite(minutes)||minutes<15))throw Error("android.backgroundRefresh.minimumIntervalMinutes is at least 15 (WorkManager's shortest period)");for(const scheme of config.urlSchemes??[])if(!/^[a-z][a-z0-9+.-]*$/i.test(scheme))throw Error(`Invalid Android URL scheme: ${scheme}`)}
@@ -1,4 +1,4 @@
1
- import process from"node:process";export const GITHUB_API_URL="https://api.github.com",MAX_RELEASE_BODY=120000;function runCommand(cmd,input){try{const result=Bun.spawnSync(cmd,{stdin:input===void 0?"ignore":Buffer.from(input),stdout:"pipe",stderr:"ignore",env:{...process.env,GIT_TERMINAL_PROMPT:"0",GH_PROMPT_DISABLED:"1"}});return{exitCode:result.exitCode??1,stdout:result.stdout?.toString()??""}}catch{return{exitCode:127,stdout:""}}}export function parseGitHubRemote(url){const match=url?.trim().match(/^(?:https?:\/\/(?:[^@/]+@)?github\.com\/|(?:ssh:\/\/)?git@github\.com[:/])([\w.-]+)\/([\w.-]+?)(?:\.git)?\/?$/);if(!match)return null;return{owner:match[1],repo:match[2]}}export function resolveGitHubToken(env=process.env,run=runCommand){for(const key of["GITHUB_TOKEN","GH_TOKEN"]){const value=env[key]?.trim();if(value)return value}const gh=run(["gh","auth","token","--hostname","github.com"]);if(gh.exitCode===0&&gh.stdout.trim())return gh.stdout.trim();const credential=run(["git","credential","fill"],`protocol=https
1
+ import{githubHeaders}from"@stacksjs/github";import process from"node:process";export const GITHUB_API_URL="https://api.github.com",MAX_RELEASE_BODY=120000;function runCommand(cmd,input){try{const result=Bun.spawnSync(cmd,{stdin:input===void 0?"ignore":Buffer.from(input),stdout:"pipe",stderr:"ignore",env:{...process.env,GIT_TERMINAL_PROMPT:"0",GH_PROMPT_DISABLED:"1"}});return{exitCode:result.exitCode??1,stdout:result.stdout?.toString()??""}}catch{return{exitCode:127,stdout:""}}}export function parseGitHubRemote(url){const match=url?.trim().match(/^(?:https?:\/\/(?:[^@/]+@)?github\.com\/|(?:ssh:\/\/)?git@github\.com[:/])([\w.-]+)\/([\w.-]+?)(?:\.git)?\/?$/);if(!match)return null;return{owner:match[1],repo:match[2]}}export function resolveGitHubToken(env=process.env,run=runCommand){for(const key of["GITHUB_TOKEN","GH_TOKEN"]){const value=env[key]?.trim();if(value)return value}const gh=run(["gh","auth","token","--hostname","github.com"]);if(gh.exitCode===0&&gh.stdout.trim())return gh.stdout.trim();const credential=run(["git","credential","fill"],`protocol=https
2
2
  host=github.com
3
3
 
4
4
  `);if(credential.exitCode===0){const password=credential.stdout.split(`
@@ -6,6 +6,6 @@ host=github.com
6
6
 
7
7
  \u2026the notes were longer than GitHub allows${compareUrl?`; see [every change](${compareUrl})`:""}.
8
8
  `,cut=body.slice(0,MAX_RELEASE_BODY-note.length);return`${cut.slice(0,Math.max(0,cut.lastIndexOf(`
9
- `)))}${note}`}export async function createGitHubRelease(repository,draft,options){const fetcher=options.fetch??globalThis.fetch,base=`${(options.apiUrl??GITHUB_API_URL).replace(/\/$/,"")}/repos/${repository.owner}/${repository.repo}/releases`,headers={Authorization:`Bearer ${options.token}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28"},existing=await fetcher(`${base}/tags/${encodeURIComponent(draft.tag)}`,{headers});if(existing.ok)return{url:(await existing.json()).html_url,created:!1};if(existing.status!==404)throw Error(`GitHub API ${existing.status} looking up the release for ${draft.tag}: ${await apiMessage(existing)}`);const response=await fetcher(base,{method:"POST",headers:{...headers,"Content-Type":"application/json"},body:JSON.stringify({tag_name:draft.tag,name:draft.name,body:draft.body,draft:!1,prerelease:draft.prerelease??!1})});if(!response.ok)throw Error(`GitHub API ${response.status} creating the release for ${draft.tag}: ${await apiMessage(response)}`);return{url:(await response.json()).html_url,created:!0}}async function apiMessage(response){const text=await response.text().catch(()=>"");try{return JSON.parse(text).message||text||response.statusText}catch{return text||response.statusText}}function git(cwd,args){const result=Bun.spawnSync(["git",...args],{cwd,stdout:"pipe",stderr:"ignore"});return result.exitCode===0?result.stdout.toString().trim():null}export function previousTag(cwd,tag){return git(cwd,["describe","--tags","--abbrev=0",`${tag}^`])||void 0}export function latestTag(cwd,ref="HEAD"){return git(cwd,["describe","--tags","--abbrev=0",ref])||void 0}export function originRepository(cwd){return parseGitHubRemote(git(cwd,["remote","get-url","origin"])??void 0)}export async function releaseNotes(options){const{generateChangelog,loadLogsmithConfig}=await import("@stacksjs/logsmith"),repoUrl=`https://github.com/${options.repository.owner}/${options.repository.repo}`,config=await loadLogsmithConfig({dir:options.cwd,from:options.from,to:options.tag,output:!1,theme:"github",repo:repoUrl,hideAuthorEmail:!0});return(await generateChangelog(config)).content.trim()||`No changes since ${options.from??"the start of the history"}.`}export async function publishGitHubRelease(options){const repository=originRepository(options.cwd);if(!repository)return{status:"skipped",reason:"origin is not a GitHub repository"};try{const from=options.ref?latestTag(options.cwd,options.ref):previousTag(options.cwd,options.tag),notes=await releaseNotes({cwd:options.cwd,tag:options.ref??options.tag,from,repository}),compareUrl=from?`https://github.com/${repository.owner}/${repository.repo}/compare/${from}...${options.tag}`:void 0,draft={tag:options.tag,name:options.name??options.tag,body:fitReleaseBody(options.summary?`${options.summary.trim()}
9
+ `)))}${note}`}export async function createGitHubRelease(repository,draft,options){const fetcher=options.fetch??globalThis.fetch,base=`${(options.apiUrl??GITHUB_API_URL).replace(/\/$/,"")}/repos/${repository.owner}/${repository.repo}/releases`,headers=githubHeaders(options.token),existing=await fetcher(`${base}/tags/${encodeURIComponent(draft.tag)}`,{headers});if(existing.ok)return{url:(await existing.json()).html_url,created:!1};if(existing.status!==404)throw Error(`GitHub API ${existing.status} looking up the release for ${draft.tag}: ${await apiMessage(existing)}`);const response=await fetcher(base,{method:"POST",headers:{...headers,"Content-Type":"application/json"},body:JSON.stringify({tag_name:draft.tag,name:draft.name,body:draft.body,draft:!1,prerelease:draft.prerelease??!1})});if(!response.ok)throw Error(`GitHub API ${response.status} creating the release for ${draft.tag}: ${await apiMessage(response)}`);return{url:(await response.json()).html_url,created:!0}}async function apiMessage(response){const text=await response.text().catch(()=>"");try{return JSON.parse(text).message||text||response.statusText}catch{return text||response.statusText}}function git(cwd,args){const result=Bun.spawnSync(["git",...args],{cwd,stdout:"pipe",stderr:"ignore"});return result.exitCode===0?result.stdout.toString().trim():null}export function previousTag(cwd,tag){return git(cwd,["describe","--tags","--abbrev=0",`${tag}^`])||void 0}export function latestTag(cwd,ref="HEAD"){return git(cwd,["describe","--tags","--abbrev=0",ref])||void 0}export function originRepository(cwd){return parseGitHubRemote(git(cwd,["remote","get-url","origin"])??void 0)}export async function releaseNotes(options){const{generateChangelog,loadLogsmithConfig}=await import("@stacksjs/logsmith"),repoUrl=`https://github.com/${options.repository.owner}/${options.repository.repo}`,config=await loadLogsmithConfig({dir:options.cwd,from:options.from,to:options.tag,output:!1,theme:"github",repo:repoUrl,hideAuthorEmail:!0});return(await generateChangelog(config)).content.trim()||`No changes since ${options.from??"the start of the history"}.`}export async function publishGitHubRelease(options){const repository=originRepository(options.cwd);if(!repository)return{status:"skipped",reason:"origin is not a GitHub repository"};try{const from=options.ref?latestTag(options.cwd,options.ref):previousTag(options.cwd,options.tag),notes=await releaseNotes({cwd:options.cwd,tag:options.ref??options.tag,from,repository}),compareUrl=from?`https://github.com/${repository.owner}/${repository.repo}/compare/${from}...${options.tag}`:void 0,draft={tag:options.tag,name:options.name??options.tag,body:fitReleaseBody(options.summary?`${options.summary.trim()}
10
10
 
11
11
  ${notes}`:notes,compareUrl),prerelease:options.prerelease};if(options.dryRun)return{status:"skipped",reason:"dry run",draft};const token=resolveGitHubToken(options.env,options.run);if(!token)return{status:"failed",reason:"no GitHub token (set GITHUB_TOKEN, or sign in with `gh auth login`)",draft};const release=await createGitHubRelease(repository,draft,{token,fetch:options.fetch});return{status:release.created?"created":"exists",url:release.url,draft}}catch(error){return{status:"failed",reason:error instanceof Error?error.message:String(error)}}}export function describeGitHubRelease(tag,result){switch(result.status){case"created":return`Created the GitHub release ${result.url}`;case"exists":return`${tag} already has a GitHub release: ${result.url}`;case"skipped":return`No GitHub release for ${tag}: ${result.reason}`;case"failed":return`Could not create the GitHub release for ${tag} (${result.reason}). The tag is pushed; run \`buddy release:github ${tag}\` to finish it.`}}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/actions",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.177",
5
+ "version": "0.75.178",
6
6
  "description": "The Stacks actions.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -66,53 +66,54 @@
66
66
  "prepublishOnly": "bun run build"
67
67
  },
68
68
  "dependencies": {
69
- "@stacksjs/action-runner": "0.75.177",
70
- "@stacksjs/ai": "0.75.177",
71
- "@stacksjs/analytics": "0.75.177",
72
- "@stacksjs/api": "0.75.177",
73
- "@stacksjs/auth": "0.75.177",
74
- "@stacksjs/build": "0.75.177",
69
+ "@stacksjs/action-runner": "0.75.178",
70
+ "@stacksjs/ai": "0.75.178",
71
+ "@stacksjs/analytics": "0.75.178",
72
+ "@stacksjs/api": "0.75.178",
73
+ "@stacksjs/auth": "0.75.178",
74
+ "@stacksjs/build": "0.75.178",
75
75
  "@stacksjs/bumpx": "^0.2.21",
76
76
  "@stacksjs/bunpress": "^0.2.15",
77
- "@stacksjs/cli": "0.75.177",
78
- "@stacksjs/cloud": "0.75.177",
79
- "@stacksjs/cms": "0.75.177",
77
+ "@stacksjs/cli": "0.75.178",
78
+ "@stacksjs/cloud": "0.75.178",
79
+ "@stacksjs/cms": "0.75.178",
80
80
  "@stacksjs/components": "^0.2.483",
81
- "@stacksjs/config": "0.75.177",
82
- "@stacksjs/database": "0.75.177",
83
- "@stacksjs/desktop-build": "0.75.177",
84
- "@stacksjs/dns": "0.75.177",
85
- "@stacksjs/enums": "0.75.177",
86
- "@stacksjs/env": "0.75.177",
87
- "@stacksjs/error-handling": "0.75.177",
81
+ "@stacksjs/config": "0.75.178",
82
+ "@stacksjs/database": "0.75.178",
83
+ "@stacksjs/desktop-build": "0.75.178",
84
+ "@stacksjs/dns": "0.75.178",
85
+ "@stacksjs/enums": "0.75.178",
86
+ "@stacksjs/env": "0.75.178",
87
+ "@stacksjs/error-handling": "0.75.178",
88
+ "@stacksjs/github": "0.75.178",
88
89
  "@stacksjs/gitit": "^0.2.5",
89
- "@stacksjs/i18n": "0.75.177",
90
- "@stacksjs/image": "0.75.177",
91
- "@stacksjs/logging": "0.75.177",
90
+ "@stacksjs/i18n": "0.75.178",
91
+ "@stacksjs/image": "0.75.178",
92
+ "@stacksjs/logging": "0.75.178",
92
93
  "@stacksjs/logsmith": "^0.2.11",
93
- "@stacksjs/mobile": "0.75.177",
94
- "@stacksjs/orm": "0.75.177",
95
- "@stacksjs/path": "0.75.177",
96
- "@stacksjs/payments": "0.75.177",
97
- "@stacksjs/queue": "0.75.177",
98
- "@stacksjs/registry": "0.75.177",
99
- "@stacksjs/router": "0.75.177",
94
+ "@stacksjs/mobile": "0.75.178",
95
+ "@stacksjs/orm": "0.75.178",
96
+ "@stacksjs/path": "0.75.178",
97
+ "@stacksjs/payments": "0.75.178",
98
+ "@stacksjs/queue": "0.75.178",
99
+ "@stacksjs/registry": "0.75.178",
100
+ "@stacksjs/router": "0.75.178",
100
101
  "@stacksjs/rpx": "^0.11.54",
101
- "@stacksjs/scheduler": "0.75.177",
102
- "@stacksjs/search-engine": "0.75.177",
103
- "@stacksjs/security": "0.75.177",
104
- "@stacksjs/server": "0.75.177",
105
- "@stacksjs/sites": "0.75.177",
106
- "@stacksjs/storage": "0.75.177",
107
- "@stacksjs/strings": "0.75.177",
102
+ "@stacksjs/scheduler": "0.75.178",
103
+ "@stacksjs/search-engine": "0.75.178",
104
+ "@stacksjs/security": "0.75.178",
105
+ "@stacksjs/server": "0.75.178",
106
+ "@stacksjs/sites": "0.75.178",
107
+ "@stacksjs/storage": "0.75.178",
108
+ "@stacksjs/strings": "0.75.178",
108
109
  "@stacksjs/stx": "^0.2.483",
109
110
  "@stacksjs/tlsx": "^0.13.19",
110
111
  "@stacksjs/ts-cloud": "^0.16.52",
111
112
  "@stacksjs/ts-md": "^0.1.1",
112
- "@stacksjs/tunnel": "0.75.177",
113
- "@stacksjs/types": "0.75.177",
114
- "@stacksjs/utils": "0.75.177",
115
- "@stacksjs/whois": "0.75.177",
113
+ "@stacksjs/tunnel": "0.75.178",
114
+ "@stacksjs/types": "0.75.178",
115
+ "@stacksjs/utils": "0.75.178",
116
+ "@stacksjs/whois": "0.75.178",
116
117
  "bun-plugin-stx": "^0.2.483"
117
118
  },
118
119
  "peerDependencies": {
@@ -128,7 +129,7 @@
128
129
  }
129
130
  },
130
131
  "devDependencies": {
131
- "@stacksjs/validation": "0.75.177",
132
+ "@stacksjs/validation": "0.75.178",
132
133
  "better-dx": "^0.2.24"
133
134
  }
134
135
  }