@stacksjs/buddy 0.75.151 → 0.75.152
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { CLI } from '@stacksjs/types';
|
|
2
|
+
/**
|
|
3
|
+
* What a status says about whether the endpoint is still there.
|
|
4
|
+
*
|
|
5
|
+
* The distinction this exists to draw is the one from #2856: the
|
|
6
|
+
* decommissioned FCM endpoint answers 404 where its replacement answers 401.
|
|
7
|
+
*/
|
|
8
|
+
export declare function classifyStatus(status: number | null): Verdict;
|
|
9
|
+
/** What the run as a whole establishes, controls first. */
|
|
10
|
+
export declare function concludeProbe(targets: ProbeResult[], controls: ProbeResult[]): Conclusion;
|
|
11
|
+
/** 0 says nothing is wrong, 1 says something we call is gone, 2 says ask again. */
|
|
12
|
+
export declare function exitCodeFor(conclusion: Conclusion): number;
|
|
13
|
+
export declare function renderReport(targets: ProbeResult[], controls: ProbeResult[], conclusion: Conclusion): string;
|
|
14
|
+
export declare function integrationsProbe(buddy: CLI): void;
|
|
15
|
+
/**
|
|
16
|
+
* Every endpoint whose disappearance would break something, with a URL that
|
|
17
|
+
* answers without a credential.
|
|
18
|
+
*
|
|
19
|
+
* Each `observed` value was measured, not assumed. Several are deliberately
|
|
20
|
+
* incomplete requests - a POST with no body, a project id that does not exist -
|
|
21
|
+
* because the question is only whether the route is there.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PROBE_TARGETS: ProbeTarget[];
|
|
24
|
+
/**
|
|
25
|
+
* Paths that must read as gone, which is what makes a clean run mean anything.
|
|
26
|
+
*
|
|
27
|
+
* Without these the command cannot tell "nothing we call has been withdrawn"
|
|
28
|
+
* from "nothing can reach the internet, or something is answering for it". A
|
|
29
|
+
* captive portal, a corporate proxy or an interception appliance can return 200
|
|
30
|
+
* or 403 for every URL on earth, under which every target reads as alive and
|
|
31
|
+
* the run is quietly, confidently wrong.
|
|
32
|
+
*
|
|
33
|
+
* Three hosts, so one provider changing how it reports a missing path does not
|
|
34
|
+
* silence the check. The first is the real decommissioned FCM endpoint, which
|
|
35
|
+
* doubles as evidence that a withdrawn endpoint does read as 404 here; the
|
|
36
|
+
* other two are paths that cannot exist.
|
|
37
|
+
*/
|
|
38
|
+
export declare const PROBE_CONTROLS: ProbeTarget[];
|
|
39
|
+
/**
|
|
40
|
+
* `buddy integrations:probe` - ask every third-party endpoint this framework
|
|
41
|
+
* calls whether it is still there (stacksjs/stacks#2859).
|
|
42
|
+
*
|
|
43
|
+
* The companion to `tests/third-party-api-versions.test.ts`, which pins the
|
|
44
|
+
* version surface and runs on every pull request. That test cannot see this
|
|
45
|
+
* failure mode: an endpoint can be withdrawn with our source unchanged, and the
|
|
46
|
+
* first report is then a user whose notification never arrives. Equally, this
|
|
47
|
+
* cannot see the one the test catches, because a version that has expired and
|
|
48
|
+
* is being silently upgraded answers exactly as a current one. Neither replaces
|
|
49
|
+
* the other.
|
|
50
|
+
*
|
|
51
|
+
* It runs on a schedule rather than per pull request. Probing third parties on
|
|
52
|
+
* every PR means someone else's outage or rate limit fails our builds, and a
|
|
53
|
+
* check that fails for reasons the author cannot fix is a check that gets
|
|
54
|
+
* disabled.
|
|
55
|
+
*
|
|
56
|
+
* **No credential is ever sent.** That is the whole method: an endpoint that
|
|
57
|
+
* exists answers an unauthenticated request with 401, 403, or a complaint about
|
|
58
|
+
* the body, and one that is gone answers 404. So the absence of a credential is
|
|
59
|
+
* what makes the signal readable, and it also means none of the POSTs below can
|
|
60
|
+
* have an effect - each is rejected before anything is read.
|
|
61
|
+
*/
|
|
62
|
+
export declare interface ProbeTarget {
|
|
63
|
+
name: string
|
|
64
|
+
url: string
|
|
65
|
+
method: 'GET' | 'POST'
|
|
66
|
+
observed: number
|
|
67
|
+
}
|
|
68
|
+
export declare interface ProbeResult {
|
|
69
|
+
target: ProbeTarget
|
|
70
|
+
status: number | null
|
|
71
|
+
verdict: Verdict
|
|
72
|
+
}
|
|
73
|
+
export type Verdict = 'alive' | 'gone' | 'inconclusive';
|
|
74
|
+
export type Conclusion = 'ok' | 'withdrawn' | 'untrustworthy' | 'inconclusive';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import process from"node:process";export const PROBE_TARGETS=[{name:"FCM HTTP v1",url:"https://fcm.googleapis.com/v1/projects/stacks-probe/messages:send",method:"POST",observed:401},{name:"OpenAI",url:"https://api.openai.com/v1/models",method:"GET",observed:401},{name:"Anthropic",url:"https://api.anthropic.com/v1/messages",method:"POST",observed:401},{name:"SendGrid",url:"https://api.sendgrid.com/v3/mail/send",method:"POST",observed:401},{name:"Twilio",url:"https://api.twilio.com/2010-04-01/Accounts",method:"GET",observed:401},{name:"Twilio Lookups v2",url:"https://lookups.twilio.com/v2/PhoneNumbers/+15005550006",method:"GET",observed:401},{name:"Twilio Verify v2",url:"https://verify.twilio.com/v2/Services",method:"GET",observed:401},{name:"Discord",url:"https://discord.com/api/v10/users/@me",method:"GET",observed:401},{name:"Mozilla add-ons v5",url:"https://addons.mozilla.org/api/v5/addons/search/?q=test",method:"GET",observed:200},{name:"Hetzner Cloud",url:"https://api.hetzner.cloud/v1/servers",method:"GET",observed:401},{name:"Lemon Squeezy",url:"https://api.lemonsqueezy.com/v1/products",method:"GET",observed:401},{name:"Vonage Messages v1",url:"https://api.nexmo.com/v1/messages",method:"POST",observed:401},{name:"Vonage Verify v2",url:"https://api.nexmo.com/v2/verify",method:"POST",observed:422},{name:"Expo push",url:"https://exp.host/--/api/v2/push/send",method:"POST",observed:400},{name:"Threads",url:"https://graph.threads.net/v1.0/me",method:"GET",observed:400},{name:"Meta Graph",url:"https://graph.facebook.com/v24.0/me",method:"GET",observed:400},{name:"LinkedIn",url:"https://api.linkedin.com/rest/me",method:"GET",observed:401},{name:"GitHub",url:"https://api.github.com/user",method:"GET",observed:401}],PROBE_CONTROLS=[{name:"FCM legacy send (decommissioned 2024-06-20)",url:"https://fcm.googleapis.com/fcm/send",method:"POST",observed:404},{name:"GitHub, a path that cannot exist",url:"https://api.github.com/stacks-probe-control-does-not-exist",method:"GET",observed:404},{name:"OpenAI, a path that cannot exist",url:"https://api.openai.com/v1/stacks-probe-control-does-not-exist",method:"GET",observed:404}];export function classifyStatus(status){if(status===null)return"inconclusive";if(status===404||status===410)return"gone";if(status>=500)return"inconclusive";return"alive"}export function concludeProbe(targets,controls){if(controls.length===0)return"untrustworthy";if(controls.some((result)=>result.verdict!=="gone"))return"untrustworthy";if(targets.some((result)=>result.verdict==="gone"))return"withdrawn";if(targets.some((result)=>result.verdict==="inconclusive"))return"inconclusive";return"ok"}export function exitCodeFor(conclusion){if(conclusion==="withdrawn")return 1;if(conclusion==="ok")return 0;return 2}export function renderReport(targets,controls,conclusion){const row=(result)=>{const status=result.status===null?"no answer":String(result.status),moved=result.status!==null&&result.status!==result.target.observed?` (was ${result.target.observed})`:"";return`| ${result.target.name} | ${result.target.method} | ${status}${moved} | ${result.verdict} |`};return["## Integration sunset probe","",{ok:"Every endpoint this framework calls is still answering.",withdrawn:"An endpoint this framework calls has been withdrawn.",untrustworthy:"This run proves nothing: a control that must read as gone did not, so something is answering for the network.",inconclusive:"No conclusion: something did not answer. The controls were sound, so this is likely a transient failure."}[conclusion],"","| Endpoint | Method | Status | Verdict |","| --- | --- | --- | --- |",...targets.map(row),"","### Controls","","Paths that must read as gone. If any does not, the table above says nothing.","","| Control | Method | Status | Verdict |","| --- | --- | --- | --- |",...controls.map(row),"","No credential is sent by any request here, which is what makes the signal readable: an endpoint that exists rejects an unauthenticated request, and one that is gone answers 404."].join(`
|
|
2
|
+
`)}async function probe(target,timeoutMs){try{const response=await fetch(target.url,{method:target.method,redirect:"manual",signal:AbortSignal.timeout(timeoutMs)});return{target,status:response.status,verdict:classifyStatus(response.status)}}catch{return{target,status:null,verdict:"inconclusive"}}}async function probeAll(targets,timeoutMs,concurrency=4){const results=[];for(let index=0;index<targets.length;index+=concurrency)results.push(...await Promise.all(targets.slice(index,index+concurrency).map((target)=>probe(target,timeoutMs))));return results}export function integrationsProbe(buddy){buddy.command("integrations:probe","Check whether the third-party endpoints this framework calls still exist (sends no credentials)").option("--timeout <ms>","How long to wait for each endpoint",{default:"12000"}).option("--json","Print the results as JSON instead of a report",{default:!1}).action(async(options)=>{const timeoutMs=Number.parseInt(String(options.timeout??"12000"),10)||12000,controls=await probeAll(PROBE_CONTROLS,timeoutMs),targets=await probeAll(PROBE_TARGETS,timeoutMs),conclusion=concludeProbe(targets,controls);if(options.json)console.log(JSON.stringify({conclusion,targets,controls},null,2));else console.log(renderReport(targets,controls,conclusion));process.exit(exitCodeFor(conclusion))})}
|
package/dist/lazy-commands.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export async function withTimeout(work,ms){let timeoutId;const deadline=new Promise((_,reject)=>{timeoutId=setTimeout(()=>reject(Error("timeout")),ms)});try{return await Promise.race([work,deadline])}finally{if(timeoutId!==void 0)clearTimeout(timeoutId)}}const commandRegistry={about:{path:"./commands/about.js",exportName:"about"},add:{path:"./commands/add.js",exportName:"add"},"ai:access":{path:"./commands/ai-access.js",exportName:"aiAccess"},"ai:context":{path:"./commands/ai-context.js",exportName:"aiContext"},auth:{path:"./commands/auth.js",exportName:"auth"},build:{path:"./commands/build.js",exportName:"build"},cd:{path:"./commands/cd.js",exportName:"cd"},changelog:{path:"./commands/changelog.js",exportName:"changelog"},clean:{path:"./commands/clean.js",exportName:"clean"},cloud:{path:"./commands/cloud.js",exportName:"cloud"},commit:{path:"./commands/commit.js",exportName:"commit"},completion:{path:"./commands/completion.js",exportName:"completion"},"config:migrate":{path:"./commands/config-migrate.js",exportName:"configMigrate"},configure:{path:"./commands/configure.js",exportName:"configure"},create:{path:"./commands/create.js",exportName:"create"},new:{path:"./commands/create.js",exportName:"create"},deploy:{path:"./commands/deploy.js",exportName:"deploy"},"deploy:rollback":{path:"./commands/deploy.js",exportName:"deploy"},dev:{path:"./commands/dev.js",exportName:"dev"},"desktop:apple:doctor":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:csr":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:init":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:package":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:provision":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:publish":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:probe":{path:"./commands/desktop-probe.js",exportName:"desktopProbe"},dns:{path:"./commands/dns.js",exportName:"dns"},"dns:pull":{path:"./commands/dns.js",exportName:"dns"},"dns:diff":{path:"./commands/dns.js",exportName:"dns"},"dns:sync":{path:"./commands/dns.js",exportName:"dns"},doctor:{path:"./commands/doctor.js",exportName:"doctor"},domains:{path:"./commands/domains.js",exportName:"domains"},email:{path:"./commands/email.js",exportName:"email"},env:{path:"./commands/env.js",exportName:"env"},"extension:init":{path:"./commands/extension.js",exportName:"extension"},"extension:build":{path:"./commands/extension.js",exportName:"extension"},"extension:package":{path:"./commands/extension.js",exportName:"extension"},"extension:chrome:publish":{path:"./commands/extension.js",exportName:"extension"},"extension:chrome:status":{path:"./commands/extension.js",exportName:"extension"},"extension:firefox:publish":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:init":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:provision":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:app":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:publish":{path:"./commands/extension.js",exportName:"extension"},"dashboard:install":{path:"./commands/features.js",exportName:"features"},"dashboard:uninstall":{path:"./commands/features.js",exportName:"features"},"commerce:install":{path:"./commands/features.js",exportName:"features"},"commerce:uninstall":{path:"./commands/features.js",exportName:"features"},"commerce:import":{path:"./commands/commerce-import.js",exportName:"commerceImport"},"cms:install":{path:"./commands/features.js",exportName:"features"},"cms:uninstall":{path:"./commands/features.js",exportName:"features"},"marketing:install":{path:"./commands/features.js",exportName:"features"},"marketing:uninstall":{path:"./commands/features.js",exportName:"features"},"monitoring:install":{path:"./commands/features.js",exportName:"features"},"monitoring:uninstall":{path:"./commands/features.js",exportName:"features"},"realtime:install":{path:"./commands/features.js",exportName:"features"},"realtime:uninstall":{path:"./commands/features.js",exportName:"features"},"queue:install":{path:"./commands/features.js",exportName:"features"},"queue:uninstall":{path:"./commands/features.js",exportName:"features"},"db:backup":{path:"./commands/db.js",exportName:"db"},"db:backups":{path:"./commands/db.js",exportName:"db"},"db:restore":{path:"./commands/db.js",exportName:"db"},"storage:backup":{path:"./commands/storage-backup.js",exportName:"storageBackup"},"storage:backups":{path:"./commands/storage-backup.js",exportName:"storageBackup"},"storage:restore":{path:"./commands/storage-backup.js",exportName:"storageBackup"},"feedback:invite":{path:"./commands/feedback.js",exportName:"feedback"},"feedback:tokens":{path:"./commands/feedback.js",exportName:"feedback"},"feedback:revoke":{path:"./commands/feedback.js",exportName:"feedback"},"socials:identities":{path:"./commands/socials.js",exportName:"socials"},"socials:authorize":{path:"./commands/socials.js",exportName:"socials"},fresh:{path:"./commands/fresh.js",exportName:"fresh"},generate:{path:"./commands/generate.js",exportName:"generate"},"gdpr:export":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:erase":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:prune":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:register":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:register:check":{path:"./commands/gdpr.js",exportName:"gdpr"},http:{path:"./commands/http.js",exportName:"http"},install:{path:"./commands/install.js",exportName:"install"},key:{path:"./commands/key.js",exportName:"key"},lint:{path:"./commands/lint.js",exportName:"lint"},format:{path:"./commands/lint.js",exportName:"lint"},"format:check":{path:"./commands/lint.js",exportName:"lint"},libs:{path:"./commands/libs.js",exportName:"libs"},libraries:{path:"./commands/libs.js",exportName:"libs"},list:{path:"./commands/list.js",exportName:"list"},mail:{path:"./commands/mail.js",exportName:"mailCommands"},"mail:preview":{path:"./commands/mail.js",exportName:"mailCommands"},maintenance:{path:"./commands/maintenance.js",exportName:"maintenance"},down:{path:"./commands/maintenance.js",exportName:"maintenance"},up:{path:"./commands/maintenance.js",exportName:"maintenance"},status:{path:"./commands/maintenance.js",exportName:"maintenance"},"coming-soon":{path:"./commands/maintenance.js",exportName:"maintenance"},"coming-soon:status":{path:"./commands/maintenance.js",exportName:"maintenance"},launch:{path:"./commands/maintenance.js",exportName:"maintenance"},make:{path:"./commands/make.js",exportName:"make"},"scaffold:crud":{path:"./commands/make.js",exportName:"make"},migrate:{path:"./commands/migrate.js",exportName:"migrate"},"migrate:fresh":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:switch":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:project":{path:"./commands/migrate-project.js",exportName:"migrateProject"},outdated:{path:"./commands/outdated.js",exportName:"outdated"},package:{path:"./commands/package.js",exportName:"packageCommands"},phone:{path:"./commands/phone.js",exportName:"phone"},ports:{path:"./commands/ports.js",exportName:"ports"},"server:flash":{path:"./commands/server.js",exportName:"server"},"server:first-boot":{path:"./commands/server.js",exportName:"server"},"server:doctor":{path:"./commands/server.js",exportName:"server"},"server:setup":{path:"./commands/server.js",exportName:"server"},"server:trust":{path:"./commands/server.js",exportName:"server"},"link:core":{path:"./commands/link.js",exportName:"link"},"comments:list":{path:"./commands/comments.js",exportName:"commentsCommands"},"comments:approve":{path:"./commands/comments.js",exportName:"commentsCommands"},"comments:reject":{path:"./commands/comments.js",exportName:"commentsCommands"},"comments:delete":{path:"./commands/comments.js",exportName:"commentsCommands"},"user:add":{path:"./commands/user.js",exportName:"user"},"user:list":{path:"./commands/user.js",exportName:"user"},"unlink:core":{path:"./commands/link.js",exportName:"link"},prepublish:{path:"./commands/prepublish.js",exportName:"prepublish"},projects:{path:"./commands/projects.js",exportName:"projects"},publish:{path:"./commands/publish.js",exportName:"publish"},"publish:model":{path:"./commands/publish.js",exportName:"publish"},"publish:controller":{path:"./commands/publish.js",exportName:"publish"},"publish:middleware":{path:"./commands/publish.js",exportName:"publish"},"publish:action":{path:"./commands/publish.js",exportName:"publish"},"publish:core":{path:"./commands/publish.js",exportName:"publish"},"core:status":{path:"./commands/publish.js",exportName:"publish"},queue:{path:"./commands/queue.js",exportName:"queue"},release:{path:"./commands/release.js",exportName:"release"},route:{path:"./commands/route.js",exportName:"route"},saas:{path:"./commands/saas.js",exportName:"saas"},"stripe:setup":{path:"./commands/saas.js",exportName:"saas"},schedule:{path:"./commands/schedule.js",exportName:"schedule"},search:{path:"./commands/search.js",exportName:"search"},"search-engine:update":{path:"./commands/search.js",exportName:"search"},"search-engine:settings":{path:"./commands/search.js",exportName:"search"},seed:{path:"./commands/seed.js",exportName:"seed"},"seed:roles":{path:"./commands/seed.js",exportName:"seed"},"roles:seed":{path:"./commands/seed.js",exportName:"seed"},preview:{path:"./commands/serve.js",exportName:"preview"},serve:{path:"./commands/serve.js",exportName:"serve"},"serve:api":{path:"./commands/serve.js",exportName:"serveApi"},setup:{path:"./commands/setup.js",exportName:"setup"},"setup:ai":{path:"./commands/setup.js",exportName:"setup"},"setup:ssl":{path:"./commands/setup.js",exportName:"setup"},"setup:oh-my-zsh":{path:"./commands/setup.js",exportName:"setup"},"ai:setup":{path:"./commands/setup.js",exportName:"setup"},share:{path:"./commands/share.js",exportName:"share"},"simulator:doctor":{path:"./commands/simulator.js",exportName:"simulator"},"simulator:open":{path:"./commands/simulator.js",exportName:"simulator"},stack:{path:"./commands/stacks.js",exportName:"stacks"},sms:{path:"./commands/sms.js",exportName:"sms"},telemetry:{path:"./commands/telemetry.js",exportName:"telemetryCommand"},test:{path:"./commands/test.js",exportName:"test"},tinker:{path:"./commands/tinker.js",exportName:"tinker"},types:{path:"./commands/types.js",exportName:"types"},undeploy:{path:"./commands/cloud.js",exportName:"cloud"},upgrade:{path:"./commands/upgrade.js",exportName:"upgrade"},version:{path:"./commands/version.js",exportName:"version"},"docs:buddy":{path:"./commands/docs.js",exportName:"docs"},"docs:native-skills":{path:"./commands/docs.js",exportName:"docs"},"docs:native-skills:check":{path:"./commands/docs.js",exportName:"docs"},"docs:buddy:check":{path:"./commands/docs.js",exportName:"docs"},"docs:artifacts":{path:"./commands/docs.js",exportName:"docs"},"docs:artifacts:check":{path:"./commands/docs.js",exportName:"docs"},"docs:links":{path:"./commands/docs.js",exportName:"docs"},"docs:links:check":{path:"./commands/docs.js",exportName:"docs"}},commandGroups={minimal:["version","help"],development:["dev","build","test","lint"],database:["migrate","seed","fresh"],scaffolding:["make","generate"],deployment:["deploy","release","cloud","server"],info:["about","doctor","list"]},loadedRegistrars=new WeakMap;function loaderKey(loader){return`${loader.path}#${loader.exportName}`}export function markLoaded(buddy,commandName){const loader=commandRegistry[commandName];if(!loader)return;let set=loadedRegistrars.get(buddy);if(!set){set=new Set;loadedRegistrars.set(buddy,set)}set.add(loaderKey(loader))}export async function loadCommand(commandName,buddy){const loader=commandRegistry[commandName];if(!loader)return!1;let set=loadedRegistrars.get(buddy);if(!set){set=new Set;loadedRegistrars.set(buddy,set)}const key=loaderKey(loader);if(set.has(key))return!0;set.add(key);try{const commandFunction=(await import(loader.path))[loader.exportName];if(typeof commandFunction==="function"){commandFunction(buddy);return!0}else return!1}catch{return!1}}export async function loadCommands(commandNames,buddy){const seen=new Set,unique=[];for(const name of commandNames){const loader=commandRegistry[name],key=loader?`${loader.path}#${loader.exportName}`:`name:${name}`;if(seen.has(key))continue;seen.add(key);unique.push(name)}await Promise.all(unique.map(async(name)=>{try{await withTimeout(loadCommand(name,buddy),5000)}catch{}}))}export async function loadCommandGroup(groupName,buddy){const commands=commandGroups[groupName];if(commands)await loadCommands(commands,buddy)}export async function loadAllCommands(buddy){const allCommands=Object.keys(commandRegistry);await loadCommands(allCommands,buddy)}export function getCommandNames(){return Object.keys(commandRegistry)}export function getCommandsToLoad(args){const requestedCommand=args[0],isVersionFlag=requestedCommand==="--version"||requestedCommand==="-v",isHelpFlag=requestedCommand==="--help"||requestedCommand==="-h",isHelpWord=requestedCommand==="help";if(isVersionFlag)return["version"];if(!requestedCommand||isHelpFlag||isHelpWord)return Object.keys(commandRegistry);const baseCommand=requestedCommand.split(":")[0];if(baseCommand==="list")return["list",...Object.keys(commandRegistry).filter((k)=>k!=="list")];if(commandRegistry[requestedCommand])return[requestedCommand];if(commandRegistry[baseCommand])return[baseCommand];return Object.keys(commandRegistry)}
|
|
1
|
+
export async function withTimeout(work,ms){let timeoutId;const deadline=new Promise((_,reject)=>{timeoutId=setTimeout(()=>reject(Error("timeout")),ms)});try{return await Promise.race([work,deadline])}finally{if(timeoutId!==void 0)clearTimeout(timeoutId)}}const commandRegistry={about:{path:"./commands/about.js",exportName:"about"},add:{path:"./commands/add.js",exportName:"add"},"ai:access":{path:"./commands/ai-access.js",exportName:"aiAccess"},"ai:context":{path:"./commands/ai-context.js",exportName:"aiContext"},auth:{path:"./commands/auth.js",exportName:"auth"},build:{path:"./commands/build.js",exportName:"build"},cd:{path:"./commands/cd.js",exportName:"cd"},changelog:{path:"./commands/changelog.js",exportName:"changelog"},clean:{path:"./commands/clean.js",exportName:"clean"},cloud:{path:"./commands/cloud.js",exportName:"cloud"},commit:{path:"./commands/commit.js",exportName:"commit"},completion:{path:"./commands/completion.js",exportName:"completion"},"config:migrate":{path:"./commands/config-migrate.js",exportName:"configMigrate"},configure:{path:"./commands/configure.js",exportName:"configure"},create:{path:"./commands/create.js",exportName:"create"},new:{path:"./commands/create.js",exportName:"create"},deploy:{path:"./commands/deploy.js",exportName:"deploy"},"deploy:rollback":{path:"./commands/deploy.js",exportName:"deploy"},dev:{path:"./commands/dev.js",exportName:"dev"},"desktop:apple:doctor":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:csr":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:init":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:package":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:provision":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:apple:publish":{path:"./commands/desktop-apple.js",exportName:"desktopApple"},"desktop:probe":{path:"./commands/desktop-probe.js",exportName:"desktopProbe"},"integrations:probe":{path:"./commands/integrations-probe.js",exportName:"integrationsProbe"},dns:{path:"./commands/dns.js",exportName:"dns"},"dns:pull":{path:"./commands/dns.js",exportName:"dns"},"dns:diff":{path:"./commands/dns.js",exportName:"dns"},"dns:sync":{path:"./commands/dns.js",exportName:"dns"},doctor:{path:"./commands/doctor.js",exportName:"doctor"},domains:{path:"./commands/domains.js",exportName:"domains"},email:{path:"./commands/email.js",exportName:"email"},env:{path:"./commands/env.js",exportName:"env"},"extension:init":{path:"./commands/extension.js",exportName:"extension"},"extension:build":{path:"./commands/extension.js",exportName:"extension"},"extension:package":{path:"./commands/extension.js",exportName:"extension"},"extension:chrome:publish":{path:"./commands/extension.js",exportName:"extension"},"extension:chrome:status":{path:"./commands/extension.js",exportName:"extension"},"extension:firefox:publish":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:init":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:provision":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:app":{path:"./commands/extension.js",exportName:"extension"},"extension:safari:publish":{path:"./commands/extension.js",exportName:"extension"},"dashboard:install":{path:"./commands/features.js",exportName:"features"},"dashboard:uninstall":{path:"./commands/features.js",exportName:"features"},"commerce:install":{path:"./commands/features.js",exportName:"features"},"commerce:uninstall":{path:"./commands/features.js",exportName:"features"},"commerce:import":{path:"./commands/commerce-import.js",exportName:"commerceImport"},"cms:install":{path:"./commands/features.js",exportName:"features"},"cms:uninstall":{path:"./commands/features.js",exportName:"features"},"marketing:install":{path:"./commands/features.js",exportName:"features"},"marketing:uninstall":{path:"./commands/features.js",exportName:"features"},"monitoring:install":{path:"./commands/features.js",exportName:"features"},"monitoring:uninstall":{path:"./commands/features.js",exportName:"features"},"realtime:install":{path:"./commands/features.js",exportName:"features"},"realtime:uninstall":{path:"./commands/features.js",exportName:"features"},"queue:install":{path:"./commands/features.js",exportName:"features"},"queue:uninstall":{path:"./commands/features.js",exportName:"features"},"db:backup":{path:"./commands/db.js",exportName:"db"},"db:backups":{path:"./commands/db.js",exportName:"db"},"db:restore":{path:"./commands/db.js",exportName:"db"},"storage:backup":{path:"./commands/storage-backup.js",exportName:"storageBackup"},"storage:backups":{path:"./commands/storage-backup.js",exportName:"storageBackup"},"storage:restore":{path:"./commands/storage-backup.js",exportName:"storageBackup"},"feedback:invite":{path:"./commands/feedback.js",exportName:"feedback"},"feedback:tokens":{path:"./commands/feedback.js",exportName:"feedback"},"feedback:revoke":{path:"./commands/feedback.js",exportName:"feedback"},"socials:identities":{path:"./commands/socials.js",exportName:"socials"},"socials:authorize":{path:"./commands/socials.js",exportName:"socials"},fresh:{path:"./commands/fresh.js",exportName:"fresh"},generate:{path:"./commands/generate.js",exportName:"generate"},"gdpr:export":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:erase":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:prune":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:register":{path:"./commands/gdpr.js",exportName:"gdpr"},"gdpr:register:check":{path:"./commands/gdpr.js",exportName:"gdpr"},http:{path:"./commands/http.js",exportName:"http"},install:{path:"./commands/install.js",exportName:"install"},key:{path:"./commands/key.js",exportName:"key"},lint:{path:"./commands/lint.js",exportName:"lint"},format:{path:"./commands/lint.js",exportName:"lint"},"format:check":{path:"./commands/lint.js",exportName:"lint"},libs:{path:"./commands/libs.js",exportName:"libs"},libraries:{path:"./commands/libs.js",exportName:"libs"},list:{path:"./commands/list.js",exportName:"list"},mail:{path:"./commands/mail.js",exportName:"mailCommands"},"mail:preview":{path:"./commands/mail.js",exportName:"mailCommands"},maintenance:{path:"./commands/maintenance.js",exportName:"maintenance"},down:{path:"./commands/maintenance.js",exportName:"maintenance"},up:{path:"./commands/maintenance.js",exportName:"maintenance"},status:{path:"./commands/maintenance.js",exportName:"maintenance"},"coming-soon":{path:"./commands/maintenance.js",exportName:"maintenance"},"coming-soon:status":{path:"./commands/maintenance.js",exportName:"maintenance"},launch:{path:"./commands/maintenance.js",exportName:"maintenance"},make:{path:"./commands/make.js",exportName:"make"},"scaffold:crud":{path:"./commands/make.js",exportName:"make"},migrate:{path:"./commands/migrate.js",exportName:"migrate"},"migrate:fresh":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:switch":{path:"./commands/migrate.js",exportName:"migrate"},"migrate:project":{path:"./commands/migrate-project.js",exportName:"migrateProject"},outdated:{path:"./commands/outdated.js",exportName:"outdated"},package:{path:"./commands/package.js",exportName:"packageCommands"},phone:{path:"./commands/phone.js",exportName:"phone"},ports:{path:"./commands/ports.js",exportName:"ports"},"server:flash":{path:"./commands/server.js",exportName:"server"},"server:first-boot":{path:"./commands/server.js",exportName:"server"},"server:doctor":{path:"./commands/server.js",exportName:"server"},"server:setup":{path:"./commands/server.js",exportName:"server"},"server:trust":{path:"./commands/server.js",exportName:"server"},"link:core":{path:"./commands/link.js",exportName:"link"},"comments:list":{path:"./commands/comments.js",exportName:"commentsCommands"},"comments:approve":{path:"./commands/comments.js",exportName:"commentsCommands"},"comments:reject":{path:"./commands/comments.js",exportName:"commentsCommands"},"comments:delete":{path:"./commands/comments.js",exportName:"commentsCommands"},"user:add":{path:"./commands/user.js",exportName:"user"},"user:list":{path:"./commands/user.js",exportName:"user"},"unlink:core":{path:"./commands/link.js",exportName:"link"},prepublish:{path:"./commands/prepublish.js",exportName:"prepublish"},projects:{path:"./commands/projects.js",exportName:"projects"},publish:{path:"./commands/publish.js",exportName:"publish"},"publish:model":{path:"./commands/publish.js",exportName:"publish"},"publish:controller":{path:"./commands/publish.js",exportName:"publish"},"publish:middleware":{path:"./commands/publish.js",exportName:"publish"},"publish:action":{path:"./commands/publish.js",exportName:"publish"},"publish:core":{path:"./commands/publish.js",exportName:"publish"},"core:status":{path:"./commands/publish.js",exportName:"publish"},queue:{path:"./commands/queue.js",exportName:"queue"},release:{path:"./commands/release.js",exportName:"release"},route:{path:"./commands/route.js",exportName:"route"},saas:{path:"./commands/saas.js",exportName:"saas"},"stripe:setup":{path:"./commands/saas.js",exportName:"saas"},schedule:{path:"./commands/schedule.js",exportName:"schedule"},search:{path:"./commands/search.js",exportName:"search"},"search-engine:update":{path:"./commands/search.js",exportName:"search"},"search-engine:settings":{path:"./commands/search.js",exportName:"search"},seed:{path:"./commands/seed.js",exportName:"seed"},"seed:roles":{path:"./commands/seed.js",exportName:"seed"},"roles:seed":{path:"./commands/seed.js",exportName:"seed"},preview:{path:"./commands/serve.js",exportName:"preview"},serve:{path:"./commands/serve.js",exportName:"serve"},"serve:api":{path:"./commands/serve.js",exportName:"serveApi"},setup:{path:"./commands/setup.js",exportName:"setup"},"setup:ai":{path:"./commands/setup.js",exportName:"setup"},"setup:ssl":{path:"./commands/setup.js",exportName:"setup"},"setup:oh-my-zsh":{path:"./commands/setup.js",exportName:"setup"},"ai:setup":{path:"./commands/setup.js",exportName:"setup"},share:{path:"./commands/share.js",exportName:"share"},"simulator:doctor":{path:"./commands/simulator.js",exportName:"simulator"},"simulator:open":{path:"./commands/simulator.js",exportName:"simulator"},stack:{path:"./commands/stacks.js",exportName:"stacks"},sms:{path:"./commands/sms.js",exportName:"sms"},telemetry:{path:"./commands/telemetry.js",exportName:"telemetryCommand"},test:{path:"./commands/test.js",exportName:"test"},tinker:{path:"./commands/tinker.js",exportName:"tinker"},types:{path:"./commands/types.js",exportName:"types"},undeploy:{path:"./commands/cloud.js",exportName:"cloud"},upgrade:{path:"./commands/upgrade.js",exportName:"upgrade"},version:{path:"./commands/version.js",exportName:"version"},"docs:buddy":{path:"./commands/docs.js",exportName:"docs"},"docs:native-skills":{path:"./commands/docs.js",exportName:"docs"},"docs:native-skills:check":{path:"./commands/docs.js",exportName:"docs"},"docs:buddy:check":{path:"./commands/docs.js",exportName:"docs"},"docs:artifacts":{path:"./commands/docs.js",exportName:"docs"},"docs:artifacts:check":{path:"./commands/docs.js",exportName:"docs"},"docs:links":{path:"./commands/docs.js",exportName:"docs"},"docs:links:check":{path:"./commands/docs.js",exportName:"docs"}},commandGroups={minimal:["version","help"],development:["dev","build","test","lint"],database:["migrate","seed","fresh"],scaffolding:["make","generate"],deployment:["deploy","release","cloud","server"],info:["about","doctor","list"]},loadedRegistrars=new WeakMap;function loaderKey(loader){return`${loader.path}#${loader.exportName}`}export function markLoaded(buddy,commandName){const loader=commandRegistry[commandName];if(!loader)return;let set=loadedRegistrars.get(buddy);if(!set){set=new Set;loadedRegistrars.set(buddy,set)}set.add(loaderKey(loader))}export async function loadCommand(commandName,buddy){const loader=commandRegistry[commandName];if(!loader)return!1;let set=loadedRegistrars.get(buddy);if(!set){set=new Set;loadedRegistrars.set(buddy,set)}const key=loaderKey(loader);if(set.has(key))return!0;set.add(key);try{const commandFunction=(await import(loader.path))[loader.exportName];if(typeof commandFunction==="function"){commandFunction(buddy);return!0}else return!1}catch{return!1}}export async function loadCommands(commandNames,buddy){const seen=new Set,unique=[];for(const name of commandNames){const loader=commandRegistry[name],key=loader?`${loader.path}#${loader.exportName}`:`name:${name}`;if(seen.has(key))continue;seen.add(key);unique.push(name)}await Promise.all(unique.map(async(name)=>{try{await withTimeout(loadCommand(name,buddy),5000)}catch{}}))}export async function loadCommandGroup(groupName,buddy){const commands=commandGroups[groupName];if(commands)await loadCommands(commands,buddy)}export async function loadAllCommands(buddy){const allCommands=Object.keys(commandRegistry);await loadCommands(allCommands,buddy)}export function getCommandNames(){return Object.keys(commandRegistry)}export function getCommandsToLoad(args){const requestedCommand=args[0],isVersionFlag=requestedCommand==="--version"||requestedCommand==="-v",isHelpFlag=requestedCommand==="--help"||requestedCommand==="-h",isHelpWord=requestedCommand==="help";if(isVersionFlag)return["version"];if(!requestedCommand||isHelpFlag||isHelpWord)return Object.keys(commandRegistry);const baseCommand=requestedCommand.split(":")[0];if(baseCommand==="list")return["list",...Object.keys(commandRegistry).filter((k)=>k!=="list")];if(commandRegistry[requestedCommand])return[requestedCommand];if(commandRegistry[baseCommand])return[baseCommand];return Object.keys(commandRegistry)}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/buddy",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.152",
|
|
6
6
|
"description": "Meet Buddy. The Stacks runtime.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -96,71 +96,71 @@
|
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
98
|
"@stacksjs/bumpx": "^0.2.21",
|
|
99
|
-
"@stacksjs/actions": "0.75.
|
|
100
|
-
"@stacksjs/ai": "0.75.
|
|
101
|
-
"@stacksjs/alias": "0.75.
|
|
102
|
-
"@stacksjs/analytics": "0.75.
|
|
103
|
-
"@stacksjs/api": "0.75.
|
|
104
|
-
"@stacksjs/arrays": "0.75.
|
|
105
|
-
"@stacksjs/auth": "0.75.
|
|
106
|
-
"@stacksjs/browser-extension": "0.75.
|
|
107
|
-
"@stacksjs/build": "0.75.
|
|
108
|
-
"@stacksjs/cache": "0.75.
|
|
109
|
-
"@stacksjs/chat": "0.75.
|
|
99
|
+
"@stacksjs/actions": "0.75.152",
|
|
100
|
+
"@stacksjs/ai": "0.75.152",
|
|
101
|
+
"@stacksjs/alias": "0.75.152",
|
|
102
|
+
"@stacksjs/analytics": "0.75.152",
|
|
103
|
+
"@stacksjs/api": "0.75.152",
|
|
104
|
+
"@stacksjs/arrays": "0.75.152",
|
|
105
|
+
"@stacksjs/auth": "0.75.152",
|
|
106
|
+
"@stacksjs/browser-extension": "0.75.152",
|
|
107
|
+
"@stacksjs/build": "0.75.152",
|
|
108
|
+
"@stacksjs/cache": "0.75.152",
|
|
109
|
+
"@stacksjs/chat": "0.75.152",
|
|
110
110
|
"@stacksjs/clapp": "^0.2.16",
|
|
111
|
-
"@stacksjs/cli": "0.75.
|
|
112
|
-
"@stacksjs/cloud": "0.75.
|
|
113
|
-
"@stacksjs/cms": "0.75.
|
|
114
|
-
"@stacksjs/collections": "0.75.
|
|
115
|
-
"@stacksjs/commerce": "0.75.
|
|
116
|
-
"@stacksjs/config": "0.75.
|
|
117
|
-
"@stacksjs/database": "0.75.
|
|
118
|
-
"@stacksjs/desktop-build": "0.75.
|
|
119
|
-
"@stacksjs/dns": "0.75.
|
|
111
|
+
"@stacksjs/cli": "0.75.152",
|
|
112
|
+
"@stacksjs/cloud": "0.75.152",
|
|
113
|
+
"@stacksjs/cms": "0.75.152",
|
|
114
|
+
"@stacksjs/collections": "0.75.152",
|
|
115
|
+
"@stacksjs/commerce": "0.75.152",
|
|
116
|
+
"@stacksjs/config": "0.75.152",
|
|
117
|
+
"@stacksjs/database": "0.75.152",
|
|
118
|
+
"@stacksjs/desktop-build": "0.75.152",
|
|
119
|
+
"@stacksjs/dns": "0.75.152",
|
|
120
120
|
"@stacksjs/dnsx": "^0.2.3",
|
|
121
|
-
"@stacksjs/email": "0.75.
|
|
122
|
-
"@stacksjs/enums": "0.75.
|
|
123
|
-
"@stacksjs/env": "0.75.
|
|
124
|
-
"@stacksjs/error-handling": "0.75.
|
|
125
|
-
"@stacksjs/events": "0.75.
|
|
126
|
-
"@stacksjs/features": "0.75.
|
|
127
|
-
"@stacksjs/git": "0.75.
|
|
121
|
+
"@stacksjs/email": "0.75.152",
|
|
122
|
+
"@stacksjs/enums": "0.75.152",
|
|
123
|
+
"@stacksjs/env": "0.75.152",
|
|
124
|
+
"@stacksjs/error-handling": "0.75.152",
|
|
125
|
+
"@stacksjs/events": "0.75.152",
|
|
126
|
+
"@stacksjs/features": "0.75.152",
|
|
127
|
+
"@stacksjs/git": "0.75.152",
|
|
128
128
|
"@stacksjs/gitit": "^0.2.5",
|
|
129
|
-
"@stacksjs/health": "0.75.
|
|
129
|
+
"@stacksjs/health": "0.75.152",
|
|
130
130
|
"@stacksjs/httx": "^0.1.10",
|
|
131
|
-
"@stacksjs/image": "0.75.
|
|
132
|
-
"@stacksjs/lint": "0.75.
|
|
133
|
-
"@stacksjs/logging": "0.75.
|
|
134
|
-
"@stacksjs/notifications": "0.75.
|
|
135
|
-
"@stacksjs/objects": "0.75.
|
|
136
|
-
"@stacksjs/orm": "0.75.
|
|
137
|
-
"@stacksjs/path": "0.75.
|
|
138
|
-
"@stacksjs/payments": "0.75.
|
|
139
|
-
"@stacksjs/realtime": "0.75.
|
|
140
|
-
"@stacksjs/router": "0.75.
|
|
131
|
+
"@stacksjs/image": "0.75.152",
|
|
132
|
+
"@stacksjs/lint": "0.75.152",
|
|
133
|
+
"@stacksjs/logging": "0.75.152",
|
|
134
|
+
"@stacksjs/notifications": "0.75.152",
|
|
135
|
+
"@stacksjs/objects": "0.75.152",
|
|
136
|
+
"@stacksjs/orm": "0.75.152",
|
|
137
|
+
"@stacksjs/path": "0.75.152",
|
|
138
|
+
"@stacksjs/payments": "0.75.152",
|
|
139
|
+
"@stacksjs/realtime": "0.75.152",
|
|
140
|
+
"@stacksjs/router": "0.75.152",
|
|
141
141
|
"@stacksjs/rpx": "^0.11.54",
|
|
142
|
-
"@stacksjs/scheduler": "0.75.
|
|
143
|
-
"@stacksjs/search-engine": "0.75.
|
|
144
|
-
"@stacksjs/security": "0.75.
|
|
145
|
-
"@stacksjs/server": "0.75.
|
|
146
|
-
"@stacksjs/sites": "0.75.
|
|
147
|
-
"@stacksjs/skills": "0.75.
|
|
148
|
-
"@stacksjs/socials": "0.75.
|
|
149
|
-
"@stacksjs/storage": "0.75.
|
|
150
|
-
"@stacksjs/strings": "0.75.
|
|
151
|
-
"@stacksjs/stx": "^0.2.
|
|
152
|
-
"@stacksjs/testing": "0.75.
|
|
153
|
-
"@stacksjs/tinker": "0.75.
|
|
142
|
+
"@stacksjs/scheduler": "0.75.152",
|
|
143
|
+
"@stacksjs/search-engine": "0.75.152",
|
|
144
|
+
"@stacksjs/security": "0.75.152",
|
|
145
|
+
"@stacksjs/server": "0.75.152",
|
|
146
|
+
"@stacksjs/sites": "0.75.152",
|
|
147
|
+
"@stacksjs/skills": "0.75.152",
|
|
148
|
+
"@stacksjs/socials": "0.75.152",
|
|
149
|
+
"@stacksjs/storage": "0.75.152",
|
|
150
|
+
"@stacksjs/strings": "0.75.152",
|
|
151
|
+
"@stacksjs/stx": "^0.2.483",
|
|
152
|
+
"@stacksjs/testing": "0.75.152",
|
|
153
|
+
"@stacksjs/tinker": "0.75.152",
|
|
154
154
|
"@stacksjs/tlsx": "^0.13.19",
|
|
155
155
|
"@stacksjs/ts-cloud": "^0.16.52",
|
|
156
|
-
"@stacksjs/tunnel": "0.75.
|
|
157
|
-
"@stacksjs/types": "0.75.
|
|
158
|
-
"@stacksjs/ui": "0.75.
|
|
159
|
-
"@stacksjs/utils": "0.75.
|
|
160
|
-
"@stacksjs/validation": "0.75.
|
|
156
|
+
"@stacksjs/tunnel": "0.75.152",
|
|
157
|
+
"@stacksjs/types": "0.75.152",
|
|
158
|
+
"@stacksjs/ui": "0.75.152",
|
|
159
|
+
"@stacksjs/utils": "0.75.152",
|
|
160
|
+
"@stacksjs/validation": "0.75.152",
|
|
161
161
|
"ajv": "^8.20.0",
|
|
162
162
|
"ajv-formats": "^3.0.1",
|
|
163
|
-
"bun-plugin-stx": "^0.2.
|
|
163
|
+
"bun-plugin-stx": "^0.2.483",
|
|
164
164
|
"ts-pantry": "^0.11.69"
|
|
165
165
|
},
|
|
166
166
|
"devDependencies": {
|