@stacksjs/utils 0.70.45 → 0.70.54
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.
- package/LICENSE.md +21 -0
- package/README.md +394 -0
- package/dist/index.js +11 -11
- package/dist/src/errors.d.ts +65 -0
- package/dist/src/index.d.ts +1 -0
- package/package.json +11 -11
- package/dist/package.json +0 -1
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Open Web Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# Rapid App & Library Development
|
|
4
|
+
|
|
5
|
+
[](https://npmjs.com/package/stacks)
|
|
6
|
+
[](https://github.com/stacksjs/stacks/actions?query=workflow%3Aci)
|
|
7
|
+
[](http://commitizen.github.io/cz-cli/)
|
|
8
|
+
[](https://npmjs.com/package/stacks)
|
|
9
|
+
<!-- [![Codecov][codecov-src]][codecov-href] -->
|
|
10
|
+
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> Stacks is in active development and usable today — every section below
|
|
13
|
+
> is real, runnable functionality. Expect occasional breaking changes
|
|
14
|
+
> while we cut the official 1.0. Feedback and issue reports are welcome.
|
|
15
|
+
|
|
16
|
+
Stacks is a rapid development framework, where the goal is to _help you_ create & maintain frontends, backends, and clouds—without having to worry about the boilerplate. _An all-in-one toolkit that meets all your full stack needs._
|
|
17
|
+
|
|
18
|
+
- Web & Desktop Applications _(including system tray apps)_
|
|
19
|
+
- Serverless & Traditional APIs
|
|
20
|
+
- Cloud Infrastructure Creation & Maintenance
|
|
21
|
+
- Interactive CLIs
|
|
22
|
+
- Framework-agnostic Component & Function Libraries
|
|
23
|
+
- Deployment & Release Manager _(CI & CD)_
|
|
24
|
+
|
|
25
|
+
## Convention Over Configuration
|
|
26
|
+
|
|
27
|
+
As a developer, Stacks helps you every step along the way—in beginner & expert-friendly ways, allowing you to focus on the _what & why_ of your project, all while enabling you to stay in control & ownership of your _(& your users’)_ data.
|
|
28
|
+
|
|
29
|
+
> “It is the framework’s responsibility to remove patterns that lead to boilerplate code. And Stacks is really good at that.” _- Chris_
|
|
30
|
+
|
|
31
|
+
<!--  -->
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
Stacks runs on [Bun](https://bun.sh). You'll need:
|
|
36
|
+
|
|
37
|
+
- **Bun ≥ 1.3.11** — install with `curl -fsSL https://bun.sh/install | bash`, or upgrade an existing install with `bun upgrade`.
|
|
38
|
+
- **macOS, Linux, or WSL** — Windows-native is on the roadmap; today the toolchain assumes a POSIX shell.
|
|
39
|
+
- **Node.js is NOT required.** Bun handles the JS/TS runtime, package management, and bundling.
|
|
40
|
+
|
|
41
|
+
That's it for the framework itself. Individual features (Postgres, Redis, AWS deploys, etc.) bring their own prereqs — each is called out where it matters in the docs.
|
|
42
|
+
|
|
43
|
+
## Get Started
|
|
44
|
+
|
|
45
|
+
The fastest path, assuming Bun is installed:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
bunx buddy new my-project
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
A one-line installer (`curl -Ssf stacksjs.com/install | sh`) is also planned and will appear here once it lands; for now the `bunx` form above is the supported install path.
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
Stacks ships with `buddy`, a single CLI for everything you'll do day to day. The handful below covers the common workflows; the full reference is collapsed underneath.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
buddy dev # start the dev server (frontend, API, dashboard, …)
|
|
59
|
+
buddy build # build for production (CLI prompts for what to build)
|
|
60
|
+
buddy test # run tests
|
|
61
|
+
buddy migrate # run database migrations
|
|
62
|
+
buddy make:action UpdateUser # scaffold a new Action (also: model, view, job, …)
|
|
63
|
+
buddy --help # show every available command
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For the full command reference, see the collapsible section below or the [Buddy CLI documentation](https://stacksjs.org/docs/cli).
|
|
67
|
+
|
|
68
|
+
<details>
|
|
69
|
+
<summary>View the complete Buddy Toolkit</summary>
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
buddy --version # get the Stacks version
|
|
73
|
+
buddy --help # view help menu
|
|
74
|
+
# please note: you may suffix any command with the
|
|
75
|
+
# `command --help` flag to review the help menu
|
|
76
|
+
|
|
77
|
+
buddy install # installs dependencies
|
|
78
|
+
buddy add # adds a stack or dependency
|
|
79
|
+
buddy fresh # fresh reinstall of all deps
|
|
80
|
+
buddy clean # removes all deps
|
|
81
|
+
buddy setup # sets up the project initially
|
|
82
|
+
buddy setup:oh-my-zsh # optional: sets up Oh My Zsh with auto-completions & "aliases"
|
|
83
|
+
|
|
84
|
+
buddy upgrade # upgrades all dependencies
|
|
85
|
+
buddy upgrade -i # prompts you to select which updates to apply (wip)
|
|
86
|
+
buddy upgrade:dependencies # auto-upgrades package.json deps
|
|
87
|
+
buddy upgrade:framework # auto-upgrades deps & the Stacks framework
|
|
88
|
+
buddy upgrade:search-engine # auto-upgrades configured search engine
|
|
89
|
+
buddy upgrade:shell # upgrades the shell integration
|
|
90
|
+
buddy upgrade:binary # upgrades the `stacks` binary
|
|
91
|
+
buddy upgrade:bun # upgrades to latest project-defined Bun version
|
|
92
|
+
buddy upgrade:all # auto-upgrades all of the above
|
|
93
|
+
|
|
94
|
+
# if you need any more info on any command listed here, you may suffix
|
|
95
|
+
# any of them via the "help option", i.e. `buddy ... --help`
|
|
96
|
+
|
|
97
|
+
buddy dev # starts the frontend dev server
|
|
98
|
+
buddy dev -i # prompts any of the dev servers (components, functions, views, docs, or api)
|
|
99
|
+
buddy dev:api # starts the API dev server
|
|
100
|
+
buddy dev:dashboard # starts the Admin/Dashboard dev server
|
|
101
|
+
buddy dev:desktop # starts the Desktop dev server
|
|
102
|
+
buddy dev:views # starts frontend dev server
|
|
103
|
+
buddy dev:components # starts component dev server
|
|
104
|
+
buddy dev:functions # stubs functions
|
|
105
|
+
buddy dev:docs # starts local docs dev server
|
|
106
|
+
buddy dev docs # also starts the local docs dev server (colon is optional for all commands)
|
|
107
|
+
buddy development # `buddy dev` alias
|
|
108
|
+
|
|
109
|
+
buddy share # creates a sharable link to your local project
|
|
110
|
+
|
|
111
|
+
# for Laravel folks, `serve` may ring more familiar than the `dev` name. Hence, we aliased it
|
|
112
|
+
buddy serve
|
|
113
|
+
buddy serve:components
|
|
114
|
+
buddy serve:desktop
|
|
115
|
+
buddy serve:views
|
|
116
|
+
buddy serve:functions
|
|
117
|
+
buddy serve:docs
|
|
118
|
+
|
|
119
|
+
# building for production (e.g. AWS, Google Cloud, npm, Vercel, Netlify, et al.)
|
|
120
|
+
buddy build # select a specific build (follow CLI prompts)
|
|
121
|
+
buddy build:views # builds SSG views
|
|
122
|
+
buddy build:desktop # builds Desktop application
|
|
123
|
+
buddy build:library # builds any or all libraries
|
|
124
|
+
buddy build:functions # builds function library
|
|
125
|
+
buddy build:components # builds Vue component library & Web Component library
|
|
126
|
+
buddy build:web-components # builds framework agnostic Web Component library (i.e. Custom Elements)
|
|
127
|
+
buddy build:all # builds all your code
|
|
128
|
+
|
|
129
|
+
# `buddy build` aliases
|
|
130
|
+
buddy prod
|
|
131
|
+
buddy prod:components
|
|
132
|
+
buddy prod:desktop
|
|
133
|
+
buddy prod:library
|
|
134
|
+
buddy prod:views
|
|
135
|
+
buddy prod:functions
|
|
136
|
+
buddy prod:web-components
|
|
137
|
+
buddy prod:all
|
|
138
|
+
buddy production # `buddy prod` alias
|
|
139
|
+
|
|
140
|
+
# sets your application key
|
|
141
|
+
buddy key:generate
|
|
142
|
+
|
|
143
|
+
buddy make:component HelloWorld # bootstraps a HelloWorld component
|
|
144
|
+
buddy make:function hello-world # bootstraps a hello-world function
|
|
145
|
+
buddy make:view hello-world # bootstraps a hello-word page
|
|
146
|
+
buddy make:model Car # bootstraps a Car model
|
|
147
|
+
buddy make:database cars # creates a cars database
|
|
148
|
+
buddy make:migration create_cars_table # creates a cars migration file
|
|
149
|
+
buddy make:factory cars # creates a Car factory file
|
|
150
|
+
buddy make:table cars # bootstraps a cars data table
|
|
151
|
+
buddy make:notification welcome-email # bootstraps a welcome-email notification
|
|
152
|
+
buddy make:lang de # bootstraps a lang/de.yml language file
|
|
153
|
+
buddy make:stack my-project # shares logic with `bunx --bun stacks new my-project`
|
|
154
|
+
|
|
155
|
+
buddy migrate # runs database migrations
|
|
156
|
+
buddy migrate:dns # sets the ./config/dns.ts file
|
|
157
|
+
|
|
158
|
+
buddy dns example.com # list all DNS records for example.com
|
|
159
|
+
buddy dns example.com --type MX # list MX records for example.com
|
|
160
|
+
|
|
161
|
+
buddy https example.com/api/hello
|
|
162
|
+
# http [flags] [METHOD] URL [ITEM [ITEM]]
|
|
163
|
+
buddy http --help
|
|
164
|
+
buddy http PUT example.com/api/put X-API-Token:123 name=John # Custom HTTP method, HTTP headers and JSON data
|
|
165
|
+
buddy http -v example.com/api/get # See the request that is being sent using one of the output options
|
|
166
|
+
buddy http POST example.com/api/post hello=World # submitting forms
|
|
167
|
+
buddy http -a USERNAME POST https://api.github.com/repos/user/repo/issues/83/comments body='Great feature! :heart:'
|
|
168
|
+
buddy http localhost:8000 Host:example.com
|
|
169
|
+
|
|
170
|
+
buddy lint # runs linter
|
|
171
|
+
buddy lint:fix # runs linter and fixes issues
|
|
172
|
+
|
|
173
|
+
buddy commit # follow CLI prompts for committing staged changes
|
|
174
|
+
buddy release # creates the releases for the stack & triggers the Release Action (workflow)
|
|
175
|
+
buddy changelog # generates CHANGELOG.md
|
|
176
|
+
|
|
177
|
+
# when deploying your app/s to a remote server or cloud provider
|
|
178
|
+
buddy deploy # select a specific deployment (follow CLI prompts)
|
|
179
|
+
# buddy deploy:docs # deploys docs to AWS (or other configured provider)
|
|
180
|
+
# buddy deploy:functions # deploys functions to AWS (or other configured provider)
|
|
181
|
+
# buddy deploy:views # deploys views to AWS (or other configured provider)
|
|
182
|
+
# buddy deploy:all # deploys all your code
|
|
183
|
+
buddy undeploy # be careful: "undeploys" removes/deletes your deployed resources
|
|
184
|
+
|
|
185
|
+
buddy cloud:remove # removes cloud setup
|
|
186
|
+
buddy cloud:cleanup # removes cloud setup & cleans up all potentially leftover resources
|
|
187
|
+
buddy cloud:add --jump-box # adds a jump box to your cloud setup
|
|
188
|
+
|
|
189
|
+
# select the example to run (follow CLI prompts)
|
|
190
|
+
buddy example # prompts you to select which example to run
|
|
191
|
+
buddy example:vue # runs the Vue example
|
|
192
|
+
buddy example:web-components # runs the Web Component example
|
|
193
|
+
|
|
194
|
+
# you likely won’t need to run these commands as they are auto-triggered, but they are available
|
|
195
|
+
buddy generate # prompts you to select which generator to run
|
|
196
|
+
buddy generate:types # generates types for your components, functions, & views
|
|
197
|
+
buddy generate:entries # generates entry files for components, functions, & views
|
|
198
|
+
buddy generate:web-types # generates Web Component types
|
|
199
|
+
buddy generate:vscode-custom-data # generates VSCode custom data
|
|
200
|
+
buddy generate:ide-helpers # generates IDE helpers
|
|
201
|
+
buddy generate:component-meta # generates component meta
|
|
202
|
+
buddy generate:all # runs all generators
|
|
203
|
+
|
|
204
|
+
# generates your application key
|
|
205
|
+
buddy key:generate # generates your application key
|
|
206
|
+
|
|
207
|
+
# manage your environment variables
|
|
208
|
+
buddy env:get # get an environment variable
|
|
209
|
+
buddy env:set # set an environment variable
|
|
210
|
+
buddy env:encrypt # encrypt an environment variable
|
|
211
|
+
buddy env:decrypt # decrypt an environment variable
|
|
212
|
+
buddy env:keypair # generate a keypair
|
|
213
|
+
buddy env:rotate # rotate a keypair
|
|
214
|
+
|
|
215
|
+
# generate your TypeScript declarations
|
|
216
|
+
buddy types:generate # generates types for your components, functions, & views
|
|
217
|
+
buddy types:fix # auto-fixes types for your components, functions, & views
|
|
218
|
+
|
|
219
|
+
buddy domains # alias for `buddy domains:list`
|
|
220
|
+
buddy domains:add stacksjs.com # adds a domain
|
|
221
|
+
buddy domains:remove stacksjs.com # removes a domain
|
|
222
|
+
buddy domains:list # lists all domains
|
|
223
|
+
buddy domains:update # apply ./config/dns.ts updates
|
|
224
|
+
buddy domains:purchase stacksjs.com # purchase a new domain
|
|
225
|
+
|
|
226
|
+
# test your stack
|
|
227
|
+
buddy test # runs test suite (unit & e2e)
|
|
228
|
+
buddy test:coverage # runs test coverage
|
|
229
|
+
buddy test:types # runs typecheck
|
|
230
|
+
|
|
231
|
+
# the CLI may be triggered in any
|
|
232
|
+
# of the following syntax
|
|
233
|
+
stx fresh
|
|
234
|
+
buddy fresh
|
|
235
|
+
bud fresh
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
</details>
|
|
239
|
+
|
|
240
|
+
Read more about the Buddy CLI in the [official docs](https://stacksjs.org/docs/cli) — every command, every flag, every prompt explained.
|
|
241
|
+
|
|
242
|
+
## Features
|
|
243
|
+
|
|
244
|
+
The Stacks framework is a harmony of several “engines” to build any web and/or desktop application, in highly scalable & privacy-friendly ways. It consists of the following engines:
|
|
245
|
+
|
|
246
|
+
### Frontend Development
|
|
247
|
+
|
|
248
|
+
_Develop dynamic UIs with helpers for atomic design, and much more._
|
|
249
|
+
|
|
250
|
+
- 🧩 **Components** _primitive to develop user interfaces_
|
|
251
|
+
- 🤖 **Functions** _primitive to develop business logic (and grant your UI superpowers)_
|
|
252
|
+
- 🎨 **UI Kit** _modern & deeply-integrated components_
|
|
253
|
+
- 🌐 **Web** _“a routing & templating engine that makes sense”_
|
|
254
|
+
- 🖥️ **Desktop** _transforms your web app into a desktop app, plus more_
|
|
255
|
+
- 📝 **Documentation** _markdown-based documentation, auto-generated_
|
|
256
|
+
- 📚 **Library** _auto-builds & manages component & function libraries_
|
|
257
|
+
- ⚡️ Powered by Bun, Craft, Headwind
|
|
258
|
+
|
|
259
|
+
### Backend Development
|
|
260
|
+
|
|
261
|
+
_Develop serverless (or server) functions with countless helpers to build scalable & fast APIs._
|
|
262
|
+
|
|
263
|
+
- 🪄 **AI** _deep AI integrations to simplify building agentic workflow_
|
|
264
|
+
- 🤖 **APIs** _scalability & maintainability built-in_
|
|
265
|
+
- 🏎️ **Cache** _unified caching for DynamoDB, Redis and more_
|
|
266
|
+
- ⚙️ **CLIs** _create beautiful CLIs for Linux, Windows, and Mac (dependency-free binaries)_
|
|
267
|
+
- 🛍️ **Commerce** _own & grow your own online business with ease (SaaS-optimized)_
|
|
268
|
+
- 📀 **Database** _DynamoDB, SQLite, MySQL, Postgres, and more_
|
|
269
|
+
- 👾 **Errors** _native type-safe error handling_
|
|
270
|
+
- 🗓️ **Events** _functional event (front & backend) communication_
|
|
271
|
+
- 📢 **Notifications** _emails, SMSs, direct, and push notifications & webhooks_
|
|
272
|
+
- 🗺️ **ORM** _automated schemas for scale & a pretty API_
|
|
273
|
+
- 💳 **Payments** _unified API for one-off & subscription billing methods for Stripe_
|
|
274
|
+
- ⚙️ **Queues** _run any heavy workload in the background_
|
|
275
|
+
- 🛠️ **Query Builder** _powerful, type-safe SQL query builder_
|
|
276
|
+
- 💬 **Realtime** _“everything you need to build dynamic real-time apps”_
|
|
277
|
+
- 🧭 **Router** _smart routing, file-based or Laravel-like_
|
|
278
|
+
- 🔎 **Search Engine** _smart searching, advanced filtering & sorting, pagination, headless UI_
|
|
279
|
+
- 💾 **Storage** _a secure-by-default File API that feels right_
|
|
280
|
+
- 🧪 **Tinker** _a powerful TypeScript REPL_
|
|
281
|
+
- 🌪️ **Validation** _e2e type-safety (true frontend & backend harmony)_
|
|
282
|
+
- 🎯 **X-Ray** _all you need to debug, log & analyze_
|
|
283
|
+
|
|
284
|
+
### Cloud Development
|
|
285
|
+
|
|
286
|
+
_Develop & maintain cloud infrastructure with ease. “Imagine Vercel, Vapor and Forge having been unified.”_
|
|
287
|
+
|
|
288
|
+
- ☁️ **Server** _local development server & production-ready servers out-of-the-box_
|
|
289
|
+
- ⛅️ **Serverless** _on-demand, auto-scaling, zero maintenance_
|
|
290
|
+
- ⏰ **Alarms** _built-in cloud infrastructure monitoring to avoid surprises_
|
|
291
|
+
- 🚏 **CDN** _zero-config, low-latency, request life-cycle hooks, optimized request compressions (Brotli & gzip)_
|
|
292
|
+
- 🔀 **Domain** _version-controlled & zero-config domain management (e.g. DNS management)_
|
|
293
|
+
- 🤖 **AI** _fine-tune a foundational model using your application data_
|
|
294
|
+
- 📧 **Email** _secure & zero-setup <easy-peasy@custom-domains.com> mailboxes_
|
|
295
|
+
- 🔐 **Firewall** _native web application firewall support_
|
|
296
|
+
- 📦 **Storage** _unlimited cloud storage & automatic backups_
|
|
297
|
+
- 🚜 **Maintenance** _maintain your cloud infrastructure with ease using Buddy & Stacks_
|
|
298
|
+
- 🚦 **Infrastructure as Code** _version-controlled cloud infrastructure (AWS, Google next?)_
|
|
299
|
+
|
|
300
|
+
### CI/CD
|
|
301
|
+
|
|
302
|
+
_Focus on coding, not publishing._
|
|
303
|
+
|
|
304
|
+
- 🚀 **Deployment Manager** _takes the sweat out of production deployments—zero-setup push-to-deploy_
|
|
305
|
+
- 0️⃣ **Zero Downtime** _deploy with confidence using a zero-downtime deployment strategy_
|
|
306
|
+
- 📫 **Release Manager** _libraries (component & function) auto-published to npm, git helpers, and more_
|
|
307
|
+
|
|
308
|
+
### Developer Experience (DX)
|
|
309
|
+
|
|
310
|
+
Convention over configuration, while staying wholly configurable. _No more boilerplate._
|
|
311
|
+
|
|
312
|
+
- 💎 **Automated Upgrades** _no need to worry about upgrading to the latest versions, Stacks upgrades you_
|
|
313
|
+
- 🦋 **Pretty Dev URLs** _your-project.localhost instead of localhost:3000_
|
|
314
|
+
- 💡 **IDE Integration** _auto-completions, inline docs & a powerful IDE setup_
|
|
315
|
+
- 🪄 **Zero-Config** _yet highly configurable—convention over configuration_
|
|
316
|
+
- 💅 **Linter & Formatter** _auto-configured & built into your IDE_
|
|
317
|
+
- 💪🏼 **Type Strong** _built-in e2e type-safety_
|
|
318
|
+
- ✨ **Git Workflows** _committing with ease_
|
|
319
|
+
- 🚗 **Auto Imports** _your components & functions, including date, string, array, & object helpers_
|
|
320
|
+
- ⏩ **Code Snippets** _goodbye to the boilerplate code—thank you Sarah Drasner_
|
|
321
|
+
- 🔤 **Spell Checker** _be notified once there are typos_
|
|
322
|
+
- 🛠️ **Essential Utilities** _powers at your fingertips. Collections, VueUse, and more_
|
|
323
|
+
- 👥 **Team Management** _manage your team & their permissions_
|
|
324
|
+
- 🧪 **Streamlined Testing** _unit & e2e tests powered by Bun, Vitest & Playwright_
|
|
325
|
+
|
|
326
|
+
No matter whether you are a beginner or an expert, the approachable Stacks design allows you to learn at your own pace, using our thorough documentation covering every aspect of the framework. Stacks is extremely beginner & expert-friendly.
|
|
327
|
+
|
|
328
|
+
Develop beautiful, reactive, composable UIs without learning a new set of languages. HTML, CSS, and minimal JavaScript—that’s all you need to dive in now! _Or TypeScript ✌🏼_
|
|
329
|
+
|
|
330
|
+
> _An actual rapid application development framework for all Full Stack needs. Next-level simplicity & DX._
|
|
331
|
+
|
|
332
|
+
## Testing
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
./buddy test
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Changelog
|
|
339
|
+
|
|
340
|
+
Please see our [releases](https://github.com/stacksjs/stacks/releases) page for more information on what has changed recently.
|
|
341
|
+
|
|
342
|
+
## Contributing
|
|
343
|
+
|
|
344
|
+
Please see the [Contributing Guide](https://github.com/stacksjs/contributing) for details.
|
|
345
|
+
|
|
346
|
+
## Community
|
|
347
|
+
|
|
348
|
+
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
|
|
349
|
+
|
|
350
|
+
[Discussions on GitHub](https://github.com/stacksjs/stacks/discussions)
|
|
351
|
+
|
|
352
|
+
For casual chit-chat with others using this package:
|
|
353
|
+
|
|
354
|
+
[Join the Stacks Discord Server](https://discord.gg/stacksjs)
|
|
355
|
+
|
|
356
|
+
## Postcardware
|
|
357
|
+
|
|
358
|
+
“Software that is free, but hopes for a postcard.” We love receiving postcards from around the world showing where Stacks is being used! We showcase them on our website too.
|
|
359
|
+
|
|
360
|
+
Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
|
|
361
|
+
|
|
362
|
+
## Sponsors
|
|
363
|
+
|
|
364
|
+
We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.
|
|
365
|
+
|
|
366
|
+
- [JetBrains](https://www.jetbrains.com/)
|
|
367
|
+
- [The Solana Foundation](https://solana.com/)
|
|
368
|
+
|
|
369
|
+
## Credits
|
|
370
|
+
|
|
371
|
+
- [Laravel](https://laravel.com) _many thanks to their community_
|
|
372
|
+
- [Chris Breuer](https://github.com/chrisbbreuer)
|
|
373
|
+
- [All Contributors](../../contributors)
|
|
374
|
+
|
|
375
|
+
And a special thanks to [Dan Scanlon](https://twitter.com/danscan) for donating the `stacks` name on npm ✨
|
|
376
|
+
|
|
377
|
+
## License
|
|
378
|
+
|
|
379
|
+
The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.
|
|
380
|
+
|
|
381
|
+
Made with 💙
|
|
382
|
+
|
|
383
|
+
<!-- Badges -->
|
|
384
|
+
[npm-version-src]: https://img.shields.io/npm/v/stacks?style=flat-square
|
|
385
|
+
[npm-version-href]: https://npmjs.com/package/stacks
|
|
386
|
+
|
|
387
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/stacks?style=flat-square
|
|
388
|
+
[npm-downloads-href]: https://npmjs.com/package/stacks
|
|
389
|
+
|
|
390
|
+
[github-actions-src]: https://img.shields.io/github/actions/workflow/status/stacksjs/stacks/ci.yml?style=flat-square&branch=main
|
|
391
|
+
[github-actions-href]: https://github.com/stacksjs/stacks/actions?query=workflow%3Aci
|
|
392
|
+
|
|
393
|
+
<!-- [codecov-src]: https://img.shields.io/codecov/c/gh/stacksjs/stacks/main?style=flat-square
|
|
394
|
+
[codecov-href]: https://codecov.io/gh/stacksjs/buddy -->
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{path as
|
|
3
|
-
`).filter(Boolean)){let f
|
|
4
|
-
`)}import g from"fs/promises";import D from"os";import b from"path";import{italic as
|
|
5
|
-
`).find((
|
|
2
|
+
import{path as L}from"@stacksjs/path";async function S$(){await Bun.$`rm -rf ${L.projectPath("bun.lock")}`,await Bun.$`rm -rf ${L.projectPath("yarn.lock")}`,await Bun.$`rm -rf ${L.projectPath("node_modules/")}`,await Bun.$`rm -rf ${L.frameworkPath("dist")}`,await Bun.$`rm -rf ${L.frameworkPath("node_modules")}`,await Bun.$`rm -rf ${L.frameworkPath("**/dist")}`,await Bun.$`rm -rf ${L.frameworkPath("**/node_modules")}`,await Bun.$`rm -rf ${L.frameworkCloudPath("cdk.out/")}`,await Bun.$`rm -rf ${L.frameworkCloudPath("cdk.context.json")}`,await Bun.$`rm -rf ${L.cloudPath("dist.zip")}`}import{defineApp as p$,defineCache as g$,defineCdn as b$,defineChat as m$,defineCli as u$,defineDatabase as d$,defineDependencies as c$,defineDns as n$,defineEmail as i$,defineEmailConfig as s$,defineGit as r$,defineHashing as a$,defineLibrary as o$,defineNotification as l$,definePayment as t$,defineQueue as e$,defineSearchEngine as $T,defineServices as TT,defineSms as HT,defineFilesystems as fT,defineUi as QT}from"@stacksjs/config";import{getTypeName as S}from"@stacksjs/types";function v($,T,H=new WeakMap){if($===T)return!0;if(typeof $==="number"&&typeof T==="number"&&Number.isNaN($)&&Number.isNaN(T))return!0;let f=S($),Q=S(T);if(f!==Q)return!1;if($&&typeof $==="object"){if(H.get($)===T)return!0;H.set($,T)}if(f==="array"){if($.length!==T.length)return!1;return $.every((X,_)=>v(X,T[_],H))}if(f==="object"){let X=Object.keys($);if(X.length!==Object.keys(T).length)return!1;return X.every((_)=>v($[_],T[_],H))}return Object.is($,T)}function $$($){if($ instanceof Error)return $.message;if(typeof $==="string")return $;if(typeof $==="number"||typeof $==="boolean")return String($);if($&&typeof $==="object"&&"message"in $&&typeof $.message==="string")return $.message;if($==null)return"Unknown error";try{return String($)}catch{return"Unknown error"}}function qT($){if($ instanceof Error)return $.stack;if($&&typeof $==="object"&&"stack"in $&&typeof $.stack==="string")return $.stack;return}function VT($){if($&&typeof $==="object"&&"code"in $&&typeof $.code==="string")return $.code;return}function _T($){if(!$||typeof $!=="object")return;let T=$;if(typeof T.statusCode==="number"&&Number.isFinite(T.statusCode))return T.statusCode;if(typeof T.status==="number"&&Number.isFinite(T.status))return T.status;return}function PT($){if($ instanceof Error)return $;return Error($$($),{cause:$})}import{stat as T$}from"fs/promises";var C=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],p=["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"];function W($,T={}){let{precision:H=1,binary:f=!1,space:Q=!0,locale:X="en-US",minimumFractionDigits:_=0,maximumFractionDigits:P=H}=T;if(!Number.isFinite($))throw TypeError(`Expected a finite number, got ${typeof $}: ${$}`);let B=$<0,J=B?"-":"";if(B)$=-$;if($<1){let e=$.toLocaleString(X,{minimumFractionDigits:_,maximumFractionDigits:P});return`${J}${e}${Q?" ":""}B`}let G=f?1024:1000,Y=f?p:C,U=Math.min(Math.floor(Math.log($)/Math.log(G)),Y.length-1),O=($/G**U).toLocaleString(X,{minimumFractionDigits:_,maximumFractionDigits:P}),k=Y[U];return`${J}${O}${Q?" ":""}${k}`}function y($){let T=$.match(/^(-?[\d.]+)\s*([A-Za-z]+)?$/);if(!T)throw Error(`Invalid byte string: ${$}`);let[,H,f="B"]=T;if(H===void 0)throw Error(`Invalid byte string: ${$}`);let Q=Number.parseFloat(H);if(!Number.isFinite(Q))throw Error(`Invalid number in byte string: ${H}`);let X=f.toUpperCase(),_=X.endsWith("IB"),P=_?1024:1000,B=0,J=_?p:C;for(let G=0;G<J.length;G++)if(J[G]?.toUpperCase()===X){B=G;break}return Q*P**B}function GT($,T){let H=typeof $==="string"?y($):$,f=typeof T==="string"?y(T):T;return H-f}var JT=W,UT=W;async function H$($){try{return(await T$($)).size}catch{return 0}}async function f$($){let T=[],H=0;try{let f=await Q$($);for(let Q of f){let X=await H$(Q.path);H+=X,T.push({name:Q.name,size:X,readable:W(X)})}}catch(f){}return{totalSize:H,totalReadable:W(H),exports:T.sort((f,Q)=>Q.size-f.size)}}async function Q$($){let T=[];try{let H=await Bun.$.throws(!1)`find ${$} -type f \\( -name "*.js" -o -name "*.mjs" -o -name "*.cjs" \\)`.text();for(let f of H.split(`
|
|
3
|
+
`).filter(Boolean)){let Q=f.replace($,"").replace(/^\//,"");T.push({name:Q,path:f})}}catch{}return T}function X$($){return Math.floor($*0.3)}function Z$($){return Math.floor($*0.25)}function OT($){if($.exports.length===0)return"No exports found";let T=["Export Sizes:",""],H=Math.max(...$.exports.map((f)=>f.name.length));for(let f of $.exports){let Q=f.name.padEnd(H," ");T.push(` ${Q} ${f.readable}`)}return T.push(""),T.push(`Total: ${$.totalReadable}`),T.push(`Estimated gzipped: ${W(X$($.totalSize))}`),T.push(`Estimated brotli: ${W(Z$($.totalSize))}`),T.join(`
|
|
4
|
+
`)}import g from"fs/promises";import D from"os";import b from"path";import{italic as R}from"@stacksjs/cli";import{log as z}from"@stacksjs/logging";var q$="buddy",m=["node_modules","dist","vendor","storage/framework",/.*out.*/,/.*\/\..*/],V$=[`${D.homedir()}/Documents`,`${D.homedir()}/Pictures`,`${D.homedir()}/Library`,`${D.homedir()}/.Trash`];async function zT($,T){let H=!!$;$=$||D.homedir();let f=H?m:[...m,...V$];if(!T?.quiet)z.info(`Searching for Stacks projects in: ${R($)}`),z.info("This may take a few moments..."),console.log(""),console.log(R(" Please note, while Stacks is searching for projects on your machine,")),console.log(R(" you may be asked for permissions to scan certain directories.")),console.log(""),z.debug(`Excluding directories: ${f.join(", ")}`);let Q=await u($,f);if(!Q)throw Error("No Stacks projects found");return Q}async function u($,T){let H=[];if(T.some((P)=>typeof P==="string"?$.includes(P):P.test($)))return H;let Q;try{Q=await g.readdir($,{withFileTypes:!0})}catch(P){return console.error(`Error reading directory ${$}:`,P),H}let X=!1,_=!1;for(let P of Q){if(P.isFile()&&P.name===q$)X=!0;if(P.isDirectory()){let B=b.join($,P.name);if(P.name==="storage"){let G=b.join(B,"framework/core/buddy");try{await g.access(G),_=!0}catch{}}let J=await u(B,T);H.push(...J)}}if(X&&_)H.push($);return H}import{execSync as _$}from"child_process";import{handleError as P$}from"@stacksjs/error-handling";function hT(){try{return _$("git diff-index --quiet HEAD --"),!0}catch($){return P$($),!1}}import{config as B$}from"@stacksjs/config";import{log as d}from"@stacksjs/logging";import{path as M}from"@stacksjs/path";import{hashPaths as E}from"@stacksjs/storage";function CT(){try{return E(M.cloudPath("src/edge"))}catch($){d.error("Are we in a Docker container? Failed to hash paths. Error below:"),d.error($);return}}function pT(){let $=[M.projectPath("docs"),M.frameworkPath("docs/dist")],T=[M.projectPath("resources/views"),M.projectPath("resources/assets"),M.projectPath("resources/lang"),M.projectPath("resources/functions"),M.projectPath("resources/components"),M.projectPath("resources/modules"),M.projectPath("resources/stores"),M.frameworkPath("views/web")];return B$.app.docMode===!0?E($):E(T)}function gT(){let $=[M.projectPath("docs"),M.frameworkPath("docs/dist")];return E($)}import{runAction as G$}from"@stacksjs/actions";import{log as c,runCommand as J$}from"@stacksjs/cli";import{app as s,ui as n}from"@stacksjs/config";import{Action as U$}from"@stacksjs/enums";import{err as r,handleError as x,ok as Y$}from"@stacksjs/error-handling";import{frameworkPath as h,projectPath as I}from"@stacksjs/path";import{fs as A,readJsonFile as K$,readPackageJson as a,readTextFile as o,writeTextFile as M$}from"@stacksjs/storage";async function rT(){let{packageManager:$}=await a(h("package.json"));return $}async function aT(){if(s.env!=="production")c.info("Project not yet initialized, generating application key...");else x("Please run `buddy key:generate` to generate an application key");let $=await G$(U$.KeyGenerate,{cwd:I()});if($.isErr)return r(x($.error));return c.info("Application key generated."),Y$($.value)}async function oT(){if(A.existsSync(I(".env")))return await i();if(A.existsSync(I(".env.example")))A.copyFileSync(I(".env.example"),I(".env"));else console.error("no .env.example file found");return await i()}async function lT(){}async function tT(){return(await a(h("package.json"))).version}async function i(){let H=(await o(".env",I())).data.split(`
|
|
5
|
+
`).find((f)=>f.startsWith("APP_KEY="));return!!(H&&H.length>16)}function eT($){if($===void 0&&n.reset)$=n.reset;if($===null)return[];let f={tailwind:'import { tailwindPreflight as reset } from "@cwcss/crosswind"',preflight:'import { tailwindPreflight as reset } from "@cwcss/crosswind"',forms:'import { tailwindFormsPreflight as reset } from "@cwcss/crosswind"'}[$??"tailwind"];return f?[f]:[]}function O$($){return $&&typeof $==="object"&&w($.name)&&w($.version)&&w($.description)}function w($){let T=typeof $;return $===null||T==="undefined"||T==="string"}async function $H($,T){let H=await o(I(".env")),f=$.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Q=new RegExp(`^${f}=.*$`,"m"),X=`${$}=${T}`,_=Q.test(H.data)?H.data.replace(Q,X):`${H.data}${H.data.endsWith(`
|
|
6
6
|
`)?"":`
|
|
7
|
-
`}${
|
|
8
|
-
`;await
|
|
9
|
-
`),
|
|
7
|
+
`}${X}
|
|
8
|
+
`;await M$({path:I(".env"),data:_})}async function TH($,T){let{data:H}=await K$("package.json",h());if(O$(H)&&L$(H,$))return await J$(`bun run ${$}`,T);return r(x(`The ${$} script does not exist in the package.json file.`))}function L$($,T){let H=$.scripts;if(H&&typeof H==="object")return Boolean(H[T]);return!1}function HH($){return Bun.YAML.parse($)}function fH($){if($?.verbose===!0)return!0;return s.debug===!0}function QH($){return $.family==="IPv6"||$.family===6}function XH($){let T=Bun.YAML;if(typeof T.stringify==="function")return T.stringify($);return JSON.stringify($,null,2)}function ZH($){return Bun.YAML.parse($)}class I${static macros=new Map;static macro($,T,H=!1){if(this.macros.has($)&&!H)throw Error(`Macro "${$}" is already registered`);this.macros.set($,T),Object.defineProperty(this.prototype,$,{value:T,writable:!0,configurable:!0,enumerable:!1})}static mixin($,T=!0){let H=Object.getOwnPropertyNames($);for(let f of H){if(f==="constructor")continue;if(this.macros.has(f)&&!T)continue;let Q=Object.getOwnPropertyDescriptor($,f);if(Q&&typeof Q.value==="function")this.macro(f,Q.value,T)}}static hasMacro($){return this.macros.has($)}static flushMacros(){for(let $ of this.macros.keys())delete this.prototype[$];this.macros.clear()}static getMacros(){return Array.from(this.macros.keys())}callMacro($,...T){let H=this.constructor.macros.get($);if(!H)throw Error(`Macro "${$}" is not registered`);return H.apply(this,T)}}function VH($=class{}){return class extends ${static macros=new Map;static macro(T,H,f=!1){if(this.macros.has(T)&&!f)throw Error(`Macro "${T}" is already registered`);this.macros.set(T,H),Object.defineProperty(this.prototype,T,{value:H,writable:!0,configurable:!0,enumerable:!1})}static mixin(T,H=!0){let f=Object.getOwnPropertyNames(T);for(let Q of f){if(Q==="constructor")continue;if(this.macros.has(Q)&&!H)continue;let X=Object.getOwnPropertyDescriptor(T,Q);if(X&&typeof X.value==="function")this.macro(Q,X.value,H)}}static hasMacro(T){return this.macros.has(T)}static flushMacros(){for(let T of this.macros.keys())delete this.prototype[T];this.macros.clear()}static getMacros(){return Array.from(this.macros.keys())}}}function _H($){let T=new Map;return $.macro=function(H,f,Q=!1){if(T.has(H)&&!Q)throw Error(`Macro "${H}" is already registered`);T.set(H,f),Object.defineProperty($.prototype,H,{value:f,writable:!0,configurable:!0,enumerable:!1})},$.mixin=function(H,f=!0){let Q=Object.getOwnPropertyNames(H);for(let X of Q){if(X==="constructor")continue;if(T.has(X)&&!f)continue;let _=Object.getOwnPropertyDescriptor(H,X);if(_&&typeof _.value==="function")$.macro(X,_.value,f)}},$.hasMacro=function(H){return T.has(H)},$.flushMacros=function(){for(let H of T.keys())delete $.prototype[H];T.clear()},$.getMacros=function(){return Array.from(T.keys())},$}function JH($,T){if(typeof $!=="string"||$.length===0)return T;try{return JSON.parse($)}catch{return T}}function UH($){if(typeof $!=="string")return{ok:!1,reason:"not-string"};if($.length===0)return{ok:!1,reason:"empty"};try{return{ok:!0,value:JSON.parse($)}}catch(T){return{ok:!1,reason:"malformed",error:T}}}function YH($,T){let H=new WeakSet;return JSON.stringify($,(f,Q)=>{if(typeof Q==="bigint")return Q.toString();if(Q&&typeof Q==="object"){if(H.has(Q))return"[Circular]";H.add(Q)}return Q},T)}var k$="0.70.54";var LH=Bun.semver;function IH($,T){return Bun.semver.order($,T)===1}function WH($,T){return Bun.semver.order($,T)===-1}function kH($,T){return Bun.semver.order($,T)===0}function DH($,T){return Bun.semver.order($,T)>=0}function EH($,T){return Bun.semver.order($,T)<=0}import*as nf from"@stacksjs/browser";import{clamp as rf,notNullish as af,retry as of,useOnline as lf}from"@stacksjs/browser";function N(...$){let T={};for(let H of $){if(!H||typeof H!=="object")continue;for(let f in H){let Q=H[f],X=T[f];if(Q===void 0)continue;if(Array.isArray(Q))T[f]=Array.isArray(X)?[...X,...Q]:[...Q];else if(Q&&typeof Q==="object"&&!E$(Q))T[f]=N(X||{},Q);else T[f]=Q}}return T}function RH($){return(...T)=>{return N($,...T)}}function D$($,...T){return N({},...T,$)}function E$($){if($ instanceof Date)return!0;if($ instanceof RegExp)return!0;if($ instanceof Error)return!0;if($ instanceof Promise)return!0;if($ instanceof Map)return!0;if($ instanceof Set)return!0;if($ instanceof WeakMap)return!0;if($ instanceof WeakSet)return!0;if(ArrayBuffer.isView($))return!0;return!1}var zH=D$,AH=N;function xH($){let T=$.split(`
|
|
9
|
+
`),H=[];for(let P of T){if(!P.trim())continue;let B=P.match(/^(\s+)/);if(B&&B[1]!==void 0)H.push(B[1])}if(H.length===0)return{amount:0,type:null,indent:""};let f=new Map;for(let P of H)f.set(P,(f.get(P)||0)+1);let Q="",X=0;for(let[P,B]of f)if(B>X)X=B,Q=P;if(Q.includes("\t"))return{amount:Q.length,type:"tab",indent:Q};return{amount:Q.length,type:"space",indent:Q}}function N$($){if(!$)return null;if($.includes(`\r
|
|
10
10
|
`))return`\r
|
|
11
11
|
`;if($.includes(`
|
|
12
12
|
`))return`
|
|
13
|
-
`;if($.includes("\r"))return"\r";return null}function
|
|
14
|
-
`){return
|
|
15
|
-
`){return $.replace(/\r\n|\r|\n/g,T)}function
|
|
16
|
-
`)}function F($,T,
|
|
13
|
+
`;if($.includes("\r"))return"\r";return null}function hH($,T=`
|
|
14
|
+
`){return N$($)||T}function FH($,T=`
|
|
15
|
+
`){return $.replace(/\r\n|\r|\n/g,T)}function jH($){let T=($.match(/\r\n/g)||[]).length,H=($.match(/\r(?!\n)/g)||[]).length,f=($.match(/(?<!\r)\n/g)||[]).length;return{crlf:T,lf:f,cr:H,total:T+f+H}}function vH($,T=0,H={}){let{leading:f=!1,trailing:Q=!0}=H,X=null,_=null,P=null,B,J=()=>{if(_)B=$.apply(P,_),_=null,P=null;return B},G=()=>{if(X)clearTimeout(X),X=null;_=null,P=null},Y=()=>{if(X)return clearTimeout(X),X=null,J();return B},U=function(...K){_=K,P=this;let O=f&&!X;if(X)clearTimeout(X);if(X=setTimeout(()=>{if(X=null,Q&&_)J()},T),O)return J();return B};return U.cancel=G,U.flush=Y,U}function yH($,T=0){let H=null,f=0,Q=null,X=null,_=()=>{if(Q)$.apply(X,Q),Q=null,X=null,f=Date.now()},P=()=>{if(H)clearTimeout(H),H=null;Q=null,X=null},B=function(...J){Q=J,X=this;let Y=Date.now()-f;if(Y>=T)_();else if(!H)H=setTimeout(()=>{H=null,_()},T-Y)};return B.cancel=P,B}function CH($){return new Promise((T)=>setTimeout(T,$))}var Z=!process.env.NO_COLOR&&(process.env.FORCE_COLOR||process.stdout?.isTTY),q={reset:Z?"\x1B[0m":"",black:Z?"\x1B[30m":"",red:Z?"\x1B[31m":"",green:Z?"\x1B[32m":"",yellow:Z?"\x1B[33m":"",blue:Z?"\x1B[34m":"",magenta:Z?"\x1B[35m":"",cyan:Z?"\x1B[36m":"",white:Z?"\x1B[37m":"",gray:Z?"\x1B[90m":"",grey:Z?"\x1B[90m":"",lightRed:Z?"\x1B[91m":"",lightGreen:Z?"\x1B[92m":"",lightYellow:Z?"\x1B[93m":"",lightBlue:Z?"\x1B[94m":"",lightMagenta:Z?"\x1B[95m":"",lightCyan:Z?"\x1B[96m":"",lightGray:Z?"\x1B[37m":"",lightGrey:Z?"\x1B[37m":"",bgBlack:Z?"\x1B[40m":"",bgRed:Z?"\x1B[41m":"",bgGreen:Z?"\x1B[42m":"",bgYellow:Z?"\x1B[43m":"",bgBlue:Z?"\x1B[44m":"",bgMagenta:Z?"\x1B[45m":"",bgCyan:Z?"\x1B[46m":"",bgWhite:Z?"\x1B[47m":"",bgLightRed:Z?"\x1B[101m":"",bgLightGreen:Z?"\x1B[102m":"",bgLightYellow:Z?"\x1B[103m":"",bgLightBlue:Z?"\x1B[104m":"",bgLightMagenta:Z?"\x1B[105m":"",bgLightCyan:Z?"\x1B[106m":"",bold:Z?"\x1B[1m":"",dim:Z?"\x1B[2m":"",italic:Z?"\x1B[3m":"",underline:Z?"\x1B[4m":"",inverse:Z?"\x1B[7m":"",hidden:Z?"\x1B[8m":"",strikethrough:Z?"\x1B[9m":""};function V($,T=q.reset){return(H)=>{if(!Z)return String(H);return`${$}${H}${T}`}}var gH=V(q.black),bH=V(q.red),mH=V(q.green),uH=V(q.yellow),dH=V(q.blue),cH=V(q.magenta),nH=V(q.cyan),iH=V(q.white),R$=V(q.gray),sH=R$,rH=V(q.lightRed),aH=V(q.lightGreen),oH=V(q.lightYellow),lH=V(q.lightBlue),tH=V(q.lightMagenta),eH=V(q.lightCyan),z$=V(q.lightGray),$f=z$,Tf=V(q.bgBlack),Hf=V(q.bgRed),ff=V(q.bgGreen),Qf=V(q.bgYellow),Xf=V(q.bgBlue),Zf=V(q.bgMagenta),qf=V(q.bgCyan),Vf=V(q.bgWhite),_f=V(q.bgLightRed),Pf=V(q.bgLightGreen),Bf=V(q.bgLightYellow),Gf=V(q.bgLightBlue),Jf=V(q.bgLightMagenta),Uf=V(q.bgLightCyan),Yf=V(q.bold),Kf=V(q.dim),Mf=V(q.italic),Of=V(q.underline),Lf=V(q.inverse),If=V(q.hidden),Wf=V(q.strikethrough),kf=V(q.reset,"");function Df($){return $.replace(/\x1B\[\d+m/g,"")}function Ef(){return!!Z}function A$($,T={}){let{align:H=[],padding:f=!0,delimiter:Q="|",delimiterStart:X=!0,delimiterEnd:_=!0,alignDelimiter:P="-"}=T;if(!$||$.length===0)return"";let B=$.map((U)=>U.map((K)=>{if(K===null||K===void 0)return"";return String(K)})),J=Math.max(...B.map((U)=>U.length)),G=Array.from({length:J}).fill(0);for(let U of B)for(let K=0;K<U.length;K++){let O=U[K]?.length??0;if(O>(G[K]??0))G[K]=O}let Y=[];if(B.length>0){let U=B[0]??[];Y.push(F(U,G,f,Q,X,_));let K=G.map((O,k)=>{let j=x$(H[k]);return w$(O,j,P)});Y.push(F(K,G,f,Q,X,_));for(let O=1;O<B.length;O++){let k=B[O]??[];Y.push(F(k,G,f,Q,X,_))}}return Y.join(`
|
|
16
|
+
`)}function F($,T,H,f,Q,X){let _=$.map((J,G)=>{let Y=T[G]??0;return J.padEnd(Y," ")}),P=H?" ":"",B=_.map((J)=>`${P}${J}${P}`).join(f);if(Q)B=f+B;if(X)B=B+f;return B}function w$($,T,H){let f=T==="center"?3:T?2:1;if($<f)$=f;let Q=H.repeat($);if(T==="left")Q=`:${Q.slice(1)}`;else if(T==="right")Q=Q.slice(0,-1)+":";else if(T==="center")Q=`:${Q.slice(2)}:`;return Q}function x$($){if(!$)return null;switch($){case"l":case"left":return"left";case"c":case"center":return"center";case"r":case"right":return"right";default:return null}}function Rf($,T={}){if(!$||$.length===0)return"";let H=Array.from(new Set($.flatMap((Q)=>Object.keys(Q)))),f=[H,...$.map((Q)=>H.map((X)=>Q[X]))];return A$(f,T)}function h$(){return typeof window<"u"&&"ResizeObserver"in window}function l(){if(h$())return window.ResizeObserver;return class{callback;observedElements=new Set;rafId=null;constructor(T){this.callback=T}observe(T){if(!this.observedElements.has(T))this.observedElements.add(T),this.scheduleCheck()}unobserve(T){if(this.observedElements.delete(T),this.observedElements.size===0&&this.rafId!==null)(typeof cancelAnimationFrame<"u"?cancelAnimationFrame:clearTimeout)(this.rafId),this.rafId=null}disconnect(){if(this.observedElements.clear(),this.rafId!==null)(typeof cancelAnimationFrame<"u"?cancelAnimationFrame:clearTimeout)(this.rafId),this.rafId=null}scheduleCheck(){if(this.rafId!==null)return;let T=typeof requestAnimationFrame<"u"?requestAnimationFrame:setTimeout;this.rafId=T(()=>{if(this.check(),this.rafId=null,this.observedElements.size>0)this.scheduleCheck()})}check(){let T=[];for(let H of this.observedElements){let f=H.getBoundingClientRect(),Q={target:H,contentRect:f,borderBoxSize:[{inlineSize:f.width,blockSize:f.height}],contentBoxSize:[{inlineSize:f.width,blockSize:f.height}],devicePixelContentBoxSize:[{inlineSize:f.width,blockSize:f.height}]};T.push(Q)}if(T.length>0)this.callback(T,this)}}}function F$($,T){let f=new(l())($),Q=Array.isArray(T)?T:[T];for(let X of Q)f.observe(X);return()=>{f.disconnect()}}function Af($,T){return F$((H)=>{let f=H.find((Q)=>Q.target===$);if(f)T(f)},$)}var wf=l();class t{passable;pipes=[];method="handle";static send($){let T=new t;return T.passable=$,T}through($){return this.pipes=$,this}pipe(...$){return this.pipes.push(...$),this}via($){return this.method=$,this}then($){return this.pipes.reduceRight((H,f)=>{return(Q)=>{if(typeof f==="function")return f(Q,H);let X=f[this.method];if(typeof X==="function")return X.call(f,Q,H);return H(Q)}},$)(this.passable)}thenReturn(){return this.then(($)=>$)}}export{uH as yellow,iH as white,pT as websiteSourceHash,k$ as version,lf as useOnline,Of as underline,PT as toError,yH as throttle,Ef as supportsColor,Df as stripColors,Wf as strikethrough,$H as setEnvValue,LH as semver,YH as safeJsonStringify,UH as safeJsonParseResult,JH as safeJsonParse,TH as runNpmScript,of as retry,kf as reset,bH as red,UT as readableSize,JT as prettyBytes,HH as parseYaml,y as parseBytes,rT as packageManager,CT as originRequestFunctionHash,Af as observeElementSize,af as notNullish,FH as normalizeNewlines,D$ as mergeDefaults,N as merge,Rf as markdownTableFromObjects,A$ as markdownTable,cH as magenta,_H as macroable,ZH as loadYaml,oH as lightYellow,rH as lightRed,tH as lightMagenta,$f as lightGrey,aH as lightGreen,z$ as lightGray,eH as lightCyan,lH as lightBlue,Mf as italic,EH as isVersionLessThanOrEqual,WH as isVersionLessThan,DH as isVersionGreaterThanOrEqual,IH as isVersionGreaterThan,kH as isVersionEqual,h$ as isResizeObserverSupported,w as isOptionalString,O$ as isManifest,QH as isIpv6,hT as isGitClean,v as isDeepEqual,i as isAppKeySet,Lf as inverse,lT as installIfVersionMismatch,aT as initProject,If as hidden,L$ as hasScript,sH as grey,mH as green,R$ as gray,l as getResizeObserver,H$ as getFileSize,f$ as getExportsSize,_T as getErrorStatusCode,qT as getErrorStack,$$ as getErrorMessage,VT as getErrorCode,tT as frameworkVersion,OT as formatExportSizes,W as formatBytes,zT as findStacksProjects,X$ as estimateGzipSize,Z$ as estimateBrotliSize,oT as ensureProjectIsInitialized,XH as dumpYaml,gT as docsSourceHash,Kf as dim,eT as determineResetPreset,fH as determineDebugLevel,hH as detectNewlineGraceful,N$ as detectNewline,xH as detectIndent,CH as delay,AH as defuArrayFn,zH as defu,QT as defineUi,HT as defineSms,TT as defineServices,$T as defineSearchEngine,e$ as defineQueue,t$ as definePayment,l$ as defineNotification,o$ as defineLibrary,a$ as defineHashing,r$ as defineGit,fT as defineFilesystems,s$ as defineEmailConfig,i$ as defineEmail,n$ as defineDns,c$ as defineDependencies,d$ as defineDatabase,u$ as defineCli,m$ as defineChat,b$ as defineCdn,g$ as defineCache,p$ as defineApp,vH as debounce,nH as cyan,F$ as createResizeObserver,RH as createMerger,VH as createMacroable,jH as countNewlines,GT as compareBytes,S$ as cleanProject,rf as clamp,nf as browserUtils,Yf as bold,dH as blue,gH as black,Qf as bgYellow,Vf as bgWhite,Hf as bgRed,Zf as bgMagenta,Bf as bgLightYellow,_f as bgLightRed,Jf as bgLightMagenta,Pf as bgLightGreen,Uf as bgLightCyan,Gf as bgLightBlue,ff as bgGreen,qf as bgCyan,Xf as bgBlue,Tf as bgBlack,wf as ResizeObserver,t as Pipeline,I$ as Macroable};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error-handling helpers (stacksjs/stacks#1875 T-1).
|
|
3
|
+
*
|
|
4
|
+
* Background: a `catch (e: any)` block lets you reach `e.message`
|
|
5
|
+
* without a typecheck — but the thrown value isn't guaranteed to be
|
|
6
|
+
* an `Error`. Strings, numbers, plain objects, and even `null` can
|
|
7
|
+
* be thrown. `e.message` on a string returns `undefined`; on `null`
|
|
8
|
+
* it throws TypeError. `${e}` works but loses stack trace info.
|
|
9
|
+
*
|
|
10
|
+
* These helpers let catch blocks type `e` as `unknown` (the safe
|
|
11
|
+
* TypeScript default) and pull a useful string / stack out without
|
|
12
|
+
* branching at every site.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Pull a human-readable message out of an unknown thrown value.
|
|
16
|
+
*
|
|
17
|
+
* Resolution order:
|
|
18
|
+
* 1. `Error.message` — the common case
|
|
19
|
+
* 2. plain-object `.message` — duck-typing for error-like values
|
|
20
|
+
* from across a serialization boundary (HTTP responses, IPC, etc.)
|
|
21
|
+
* 3. `String(e)` — covers strings, numbers, booleans
|
|
22
|
+
* 4. `'Unknown error'` — for `null` / `undefined` thrown values
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* try {
|
|
27
|
+
* await someAsyncOp()
|
|
28
|
+
* }
|
|
29
|
+
* catch (e: unknown) {
|
|
30
|
+
* log.error(`Failed: ${getErrorMessage(e)}`)
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function getErrorMessage(e: unknown): string;
|
|
35
|
+
/**
|
|
36
|
+
* Pull a stack trace out of an unknown thrown value, returning
|
|
37
|
+
* `undefined` when one isn't available. Useful for log enrichment
|
|
38
|
+
* without forcing the caller to narrow `e` first.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getErrorStack(e: unknown): string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Pull a `.code` string out of an unknown thrown value. Common across
|
|
43
|
+
* AWS SDK errors (`'AlreadyExistsException'`, `'NoSuchEntity'`, …),
|
|
44
|
+
* Node fs errors (`'ENOENT'`, `'EACCES'`, …), and many HTTP-client
|
|
45
|
+
* libraries. Returns `undefined` when the input doesn't carry a
|
|
46
|
+
* string code, so callers can default-handle.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getErrorCode(e: unknown): string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Pull an HTTP-style status code (`.statusCode` or `.status`) out of an
|
|
51
|
+
* unknown thrown value. AWS SDK errors use `.statusCode`; fetch/Node
|
|
52
|
+
* errors often use `.status`. Returns `undefined` when neither is a
|
|
53
|
+
* finite number — same default-handling pattern as `getErrorCode`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function getErrorStatusCode(e: unknown): number | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Coerce an unknown thrown value into a real `Error`. The thrown
|
|
58
|
+
* value is preserved on `.cause` (ES2022) when the input was a
|
|
59
|
+
* non-Error so debugging tools can still surface it. Idempotent —
|
|
60
|
+
* passing in an Error returns it unchanged.
|
|
61
|
+
*
|
|
62
|
+
* Use this when downstream APIs require an `Error` instance (e.g.
|
|
63
|
+
* tracing SDKs that want `captureException(Error)`).
|
|
64
|
+
*/
|
|
65
|
+
export declare function toError(e: unknown): Error;
|
package/dist/src/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/utils",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.70.
|
|
4
|
+
"version": "0.70.54",
|
|
5
5
|
"description": "The Stacks helper functions.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"contributors": [
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
"size": "bun scripts/export-size.ts"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@stacksjs/browser": "
|
|
55
|
+
"@stacksjs/browser": "0.70.54"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@stacksjs/actions": "
|
|
59
|
-
"@stacksjs/arrays": "
|
|
60
|
-
"@stacksjs/cli": "
|
|
61
|
-
"@stacksjs/config": "
|
|
58
|
+
"@stacksjs/actions": "0.70.54",
|
|
59
|
+
"@stacksjs/arrays": "0.70.54",
|
|
60
|
+
"@stacksjs/cli": "0.70.54",
|
|
61
|
+
"@stacksjs/config": "0.70.54",
|
|
62
62
|
"better-dx": "^0.2.12",
|
|
63
|
-
"@stacksjs/lint": "
|
|
64
|
-
"@stacksjs/path": "
|
|
65
|
-
"@stacksjs/storage": "
|
|
66
|
-
"@stacksjs/strings": "
|
|
67
|
-
"@stacksjs/types": "
|
|
63
|
+
"@stacksjs/lint": "0.70.54",
|
|
64
|
+
"@stacksjs/path": "0.70.54",
|
|
65
|
+
"@stacksjs/storage": "0.70.54",
|
|
66
|
+
"@stacksjs/strings": "0.70.54",
|
|
67
|
+
"@stacksjs/types": "0.70.54"
|
|
68
68
|
}
|
|
69
69
|
}
|
package/dist/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|