detached 54cdd9d

wip

commit
54cdd9d41f6cef0aef394c1fb084fe632b0eb788
author
bamen · · 2025-06-01 21:38 UTC
committer
bamen · · 2025-06-01 18:01 UTC
parent
c1e4589
signature
unsigned
1607 files · +178060 -7862
M .gitignore +7 -2
@@ -1,9 +1,10 @@
11 .env
2-node_modules/
2+# Node.js/Bun specific (removed)
3+# node_modules/
34 *tmp/
45 tmp/*
56 config.yml
6-bun.lockb
7+# bun.lockb
78 *.log
89 *.txt
910 *sync-conflict*
@@ -16,3 +17,7 @@ setup.sh
1617 sqlite.db
1718 .vscode/
1819 admin-ui/
20+
21+# Standalone Tailwind/DaisyUI
22+tailwindcss
23+daisyui.js
M .goreleaser.yaml +1 -1
@@ -4,7 +4,7 @@ before:
44 hooks:
55 - go mod tidy
66 - templ generate
7- - bun run build:css
7+ - tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css
88
99 release:
1010 draft: true
M Makefile +1 -1
@@ -38,7 +38,7 @@ build: build-css build-templ
3838 # Build CSS with tailwindcss
3939 build-css:
4040 @echo "Building CSS with tailwindcss..."
41- @bun run build:css
41+ @tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css
4242 @echo "CSS built successfully"
4343
4444 # Generate Go code from templ templates
M internal/httpserve/handlers/container_crud.go +34 -22
@@ -1,8 +1,8 @@
11 package handlers
22
33 import (
4+ "encoding/json"
45 "fmt"
5- "net/http"
66 "strings"
77
88 "github.com/bnema/gordon/internal/server"
@@ -126,25 +126,6 @@ func CreateContainerFullGET(c echo.Context, a *server.App) error {
126126 func CreateContainerPOST(c echo.Context, a *server.App) error {
127127 log.Debug("CreateContainerPOST handler called")
128128
129- // Retrieve the ShortID of the image from the URL
130- ShortID := c.Param("ID")
131- log.Debug("Received ShortID for container creation:", "ShortID", ShortID)
132-
133- // Convert the ShortID to a full image ID
134- imageID, err := FromShortIDToImageID(ShortID)
135- if err != nil {
136- log.Error("Error converting ShortID to full image ID:", "error", err)
137- return sendError(c, err)
138- }
139- log.Debug("Converted ShortID to full image ID:", "imageID", imageID)
140-
141- // Get the image info
142- _, err = docker.GetImageInfo(imageID)
143- if err != nil {
144- log.Error("Error getting image info:", "error", err)
145- return sendError(c, err)
146- }
147-
148129 // Retrieve all form parameters
149130 formParams, err := c.FormParams()
150131 if err != nil {
@@ -165,6 +146,22 @@ func CreateContainerPOST(c echo.Context, a *server.App) error {
165146 }
166147 }
167148
149+ // Get the full image ID directly from the sanitized form inputs
150+ imageID, ok := sanitizedInputs["image_id"]
151+ if !ok || imageID == "" {
152+ log.Error("Full image ID not found in form submission")
153+ // You might want to return a more specific error message to the user here
154+ return sendError(c, fmt.Errorf("missing image ID in form submission"))
155+ }
156+ log.Debug("Retrieved full image ID from form:", "imageID", imageID)
157+
158+ // Get the image info (Optional but good practice: verify the image ID still exists)
159+ _, err = docker.GetImageInfo(imageID)
160+ if err != nil {
161+ log.Error("Error getting image info:", "error", err)
162+ return sendError(c, err)
163+ }
164+
168165 cmdParams, err := cmdparams.FromInputsToCmdParams(sanitizedInputs, a)
169166 if err != nil {
170167 return sendError(c, err)
@@ -229,6 +226,21 @@ func CreateContainerPOST(c echo.Context, a *server.App) error {
229226 log.Info("Skipping proxy setup as requested", "container_id", containerID, "container_name", containerName)
230227 }
231228
232- // Redirect to the container list page
233- return c.Redirect(http.StatusSeeOther, fmt.Sprintf("%s/containers", a.Config.Admin.Path))
229+ // Prepare success message payload
230+ successPayload := map[string]string{
231+ "level": "success",
232+ "message": fmt.Sprintf("Container '%s' created successfully.", containerName),
233+ }
234+ jsonPayload, err := json.Marshal(successPayload)
235+ if err != nil {
236+ // Log the error, but proceed with redirect as container creation was likely successful
237+ log.Error("Failed to marshal success payload for HX-Trigger", "error", err)
238+ } else {
239+ c.Response().Header().Set("HX-Trigger", fmt.Sprintf(`{"showMessage": %s}`, string(jsonPayload)))
240+ }
241+
242+ // Render a success message fragment instead of redirecting
243+ renderer := render.NewTemplRenderer(a)
244+ successMsg := fmt.Sprintf("Container '%s' created successfully.", containerName)
245+ return renderer.RenderTempl(c, templcomponents.Success(successMsg)) // Use the correct Success component
234246 }
M internal/httpserve/handlers/container_management.go +101 -5
@@ -224,12 +224,108 @@ func ImageManagerPrune(c echo.Context, a *server.App) error {
224224 lastPruneResult.mutex.Unlock()
225225 }()
226226
227- // Immediately return 202 Accepted to the client
228- c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML) // Set appropriate content type if needed for HTMX
227+ // Immediately return a placeholder that initiates polling
228+ // Note: We need to modify imagelist.templ to handle this response properly
229+ // For now, just return 202 Accepted and indicate work started.
230+ // The actual polling trigger will be added in the template.
229231 c.Response().WriteHeader(http.StatusAccepted)
230- // Optionally, return a message or updated component indicating the process has started
231- // For now, just return a simple message in the response body
232- return c.String(http.StatusAccepted, "Image pruning started in the background.")
232+ // We'll return a small snippet that the template swap can use
233+ // This snippet should include the polling mechanism itself.
234+ // Example (needs refinement in the template):
235+ return c.HTML(http.StatusAccepted, `<div id="prune-status-poller" hx-get="/htmx/image-manager/prune-status" hx-trigger="load, every 3s" hx-target="#prune-status-poller" hx-swap="outerHTML">Pruning images in background... Checking status.</div>`)
236+}
237+
238+// ImageManagerPruneStatus checks the status of a background prune operation
239+func ImageManagerPruneStatus(c echo.Context, a *server.App) error {
240+ lastPruneResult.mutex.Lock()
241+ defer lastPruneResult.mutex.Unlock()
242+
243+ // If prune is not done, return an empty response or keep the poller active
244+ if !lastPruneResult.Done {
245+ // Returning 204 No Content will stop polling if using hx-swap="none"
246+ // However, our poller replaces itself, so we just return the same polling div
247+ // or an updated status message within it.
248+ // Let's keep the existing poller HTML but maybe update the text slightly.
249+ return c.HTML(http.StatusOK, `<div id="prune-status-poller" hx-get="/htmx/image-manager/prune-status" hx-trigger="every 3s" hx-target="#prune-status-poller" hx-swap="outerHTML">Still pruning... Checking status.</div>`)
250+ }
251+
252+ // Prune is done, prepare the final response
253+ logger.Info("Prune complete, preparing final response for poller.")
254+
255+ // Prepare JSON payload for HX-Trigger toast message
256+ var level string
257+ if lastPruneResult.Success {
258+ level = "success"
259+ } else {
260+ level = "error"
261+ }
262+ payload := map[string]string{"level": level, "message": lastPruneResult.Message}
263+ jsonPayload, marshalErr := json.Marshal(payload)
264+ if marshalErr != nil {
265+ logger.Error("Failed to marshal prune result payload for poller", "error", marshalErr)
266+ // Handle marshalling error - maybe return an error component
267+ } else {
268+ c.Response().Header().Set("HX-Trigger", fmt.Sprintf(`{"showMessage": %s}`, string(jsonPayload)))
269+ }
270+
271+ // Reset the flag *after* preparing the response
272+ lastPruneResult.Done = false
273+ message := lastPruneResult.Message // Store message before resetting if needed
274+ success := lastPruneResult.Success
275+ // Reset message/success if needed, or maybe they are only relevant for the toast
276+ // lastPruneResult.Message = ""
277+ // lastPruneResult.Success = false
278+
279+ // Fetch the updated image list (copy logic from ImageManagerComponent)
280+ images, listErr := docker.ListContainerImages()
281+ if listErr != nil {
282+ logger.Error("Failed to list images after prune for poller", "error", listErr)
283+ // Return an error FRAGMENT instead of a full page.
284+ // HX-Trigger for the prune status itself was already set.
285+ pruneStatusMsg := "Prune finished but failed to refresh list."
286+ if !success { // Add prune status detail if it also failed
287+ pruneStatusMsg = fmt.Sprintf("Prune status: %s. Failed to refresh list.", message)
288+ }
289+ return c.HTML(http.StatusOK, fmt.Sprintf("<div class='alert alert-error'>%s Error: %v. Please refresh manually.</div>", pruneStatusMsg, listErr))
290+ }
291+
292+ var humanReadableImages []components.HumanReadableImage
293+ for _, img := range images {
294+ shortID := img.ID[7:19]
295+ safelyInteractWithIDMap(Update, shortID, img.ID)
296+ createdStr := humanize.TimeAgo(time.Unix(img.Created, 0))
297+ sizeStr := humanize.BytesToReadableSize(img.Size)
298+ var repository, tag string
299+ repoTag := "<none>:<none>"
300+ if len(img.RepoTags) > 0 {
301+ repoTag = img.RepoTags[0]
302+ parts := strings.Split(repoTag, ":")
303+ if len(parts) == 2 {
304+ repository = parts[0]
305+ tag = parts[1]
306+ } else {
307+ repository = repoTag
308+ tag = "latest"
309+ }
310+ }
311+ humanReadableImages = append(humanReadableImages, components.HumanReadableImage{
312+ ID: img.ID,
313+ ShortID: shortID,
314+ Created: createdStr,
315+ Size: sizeStr,
316+ Name: repoTag,
317+ RepoDigests: img.RepoDigests,
318+ RepoTags: img.RepoTags,
319+ Repository: repository,
320+ Tag: tag,
321+ })
322+ }
323+
324+ // Render the final ImageList component to replace the poller
325+ renderer := render.NewTemplRenderer(a)
326+ component := components.ImageList(humanReadableImages)
327+ logger.Debug("Rendering final ImageList for poller")
328+ return renderer.RenderTempl(c, component)
233329 }
234330
235331 // ContainerManagerComponent handles the /container-manager route
M internal/httpserve/handlers/container_transactions.go +9 -0
@@ -24,6 +24,15 @@ func generateOrderedYAML(infoMap map[string]interface{}) (string, error) {
2424 continue
2525 }
2626
27+ // Special handling for empty Ports and Volumes maps
28+ if key == "Ports" || key == "Volumes" {
29+ if mapVal, ok := value.(map[string]string); ok && len(mapVal) == 0 {
30+ yamlString += key + ": []\n" // Output as empty list instead of map
31+ continue // Skip normal marshalling for this key
32+ }
33+ }
34+
35+ // Default marshalling for other keys or non-empty maps
2736 yamlBytes, err := yaml.Marshal(map[string]interface{}{key: value})
2837 if err != nil {
2938 return "", err
M internal/httpserve/handlers/login.go +4 -4
@@ -81,12 +81,12 @@ func StartOAuthGithub(c echo.Context, a *server.App) error {
8181 return fmt.Errorf("could not extend session expiration: %w", err)
8282 }
8383
84- // Explicitly mark the session as online since we've validated it
85- logger.Info("Marking existing session as online", "sessionID", sessionID)
84+ // Explicitly mark the session as active since we've validated it
85+ logger.Info("Marking existing session as active", "sessionID", sessionID)
8686 err = queries.MarkSessionActive(a.DB, sessionID)
8787 if err != nil {
88- logger.Error("Failed to mark session as online", "error", err, "sessionID", sessionID)
89- return fmt.Errorf("failed to mark session online: %w", err)
88+ logger.Error("Failed to mark session as active", "error", err, "sessionID", sessionID)
89+ return fmt.Errorf("failed to mark session active: %w", err)
9090 }
9191
9292 logger.Info("Session is valid and extended. Redirecting to admin panel")
M internal/proxy/core.go +6 -0
@@ -218,6 +218,12 @@ func (p *Proxy) Close() {
218218
219219 // requestDomainCertificate requests a certificate for a domain
220220 func (p *Proxy) requestDomainCertificate(domainName string) error {
221+ // If certificate acquisition is globally skipped, do nothing.
222+ if p.config.SkipCertificates {
223+ logger.Debug("Skipping certificate request because SkipCertificates is true", "domain", domainName)
224+ return nil
225+ }
226+
221227 logger.Debug("Requesting certificate for domain", "domain", domainName)
222228
223229 // Check if we're already processing this domain
M internal/proxy/middleware.go +15 -16
@@ -1,7 +1,6 @@
11 package proxy
22
33 import (
4- "fmt"
54 "net"
65 "net/http"
76 "strings"
@@ -114,7 +113,7 @@ func (p *Proxy) setupMiddleware() {
114113 }
115114
116115 // Add middleware to log incoming headers (for debugging Cloudflare detection)
117- p.httpsServer.Use(logHeadersMiddleware())
116+ // p.httpsServer.Use(logHeadersMiddleware())
118117
119118 // --- Rate Limiting Setup (Domain Only Now) ---
120119 if p.config.EnableRateLimit {
@@ -250,17 +249,17 @@ func (p *Proxy) createRequestIDMiddleware() echo.MiddlewareFunc {
250249 }
251250
252251 // logHeadersMiddleware creates a middleware function to log request headers
253-func logHeadersMiddleware() echo.MiddlewareFunc {
254- return func(next echo.HandlerFunc) echo.HandlerFunc {
255- return func(c echo.Context) error {
256- // Log all headers at DEBUG level
257- headerStrings := []string{}
258- for k, v := range c.Request().Header {
259- headerStrings = append(headerStrings, fmt.Sprintf("%s: %s", k, strings.Join(v, ",")))
260- }
261- logger.Debug("Incoming Request Headers", "request_id", c.Get(RequestIDKey), "headers", strings.Join(headerStrings, " | "))
262-
263- return next(c)
264- }
265- }
266-}
252+// func logHeadersMiddleware() echo.MiddlewareFunc {
253+// return func(next echo.HandlerFunc) echo.HandlerFunc {
254+// return func(c echo.Context) error {
255+// // Log all headers at DEBUG level
256+// headerStrings := []string{}
257+// for k, v := range c.Request().Header {
258+// headerStrings = append(headerStrings, fmt.Sprintf("%s: %s", k, strings.Join(v, ",")))
259+// }
260+// logger.Debug("Incoming Request Headers", "request_id", c.Get(RequestIDKey), "headers", strings.Join(headerStrings, " | "))
261+
262+// return next(c)
263+// }
264+// }
265+// }
M internal/proxy/routes.go +38 -4
@@ -1196,19 +1196,53 @@ func (p *Proxy) StartContainerEventListener() error {
11961196 } else {
11971197 // Even if IP is the same, make sure the route is active
11981198 if !route.Active {
1199- logger.Info("Reactivating route for restarted container",
1199+ logger.Info("Attempting to reactivate route for restarted container",
12001200 "container_id", containerID,
12011201 "container_name", containerName,
12021202 "domain", domain)
12031203
1204- // Just reuse ForceUpdateRouteIP with the same IP to activate the route
1205- p.ForceUpdateRouteIP(domain, containerIP)
1204+ // --- Add Health Check Before Activation ---
1205+ target := net.JoinHostPort(containerIP, route.ContainerPort)
1206+ maxRetries := 5
1207+ retryDelay := 2 * time.Second
1208+ healthy := false
1209+ for i := 0; i < maxRetries; i++ {
1210+ conn, err := net.DialTimeout("tcp", target, 1*time.Second)
1211+ if err == nil {
1212+ conn.Close()
1213+ healthy = true
1214+ logger.Info("Container health check successful", "target", target, "attempt", i+1)
1215+ break
1216+ }
1217+ logger.Debug("Container health check failed, retrying...",
1218+ "target", target,
1219+ "attempt", i+1,
1220+ "error", err)
1221+ time.Sleep(retryDelay)
1222+ }
1223+ // --- End Health Check ---
1224+
1225+ if healthy {
1226+ logger.Info("Container is healthy, proceeding with route activation", "domain", domain)
1227+ // Just reuse ForceUpdateRouteIP with the same IP to activate the route
1228+ err := p.ForceUpdateRouteIP(domain, containerIP)
1229+ if err != nil {
1230+ logger.Error("Failed to activate route after health check",
1231+ "domain", domain,
1232+ "error", err)
1233+ }
1234+ } else {
1235+ logger.Warn("Container did not become healthy after retries, route remains inactive",
1236+ "domain", domain,
1237+ "target", target)
1238+ // Route remains inactive, periodic check might pick it up later
1239+ }
12061240 }
12071241 }
12081242 }
12091243 }
12101244
1211- // Call the standard recreation handler for additional checks
1245+ // Call the standard recreation handler for additional checks (might add the route if missing)
12121246 p.HandleContainerRecreation(containerID, containerName, containerIP)
12131247 }()
12141248 }
M internal/templating/cmdparams/from_inputs.go +21 -2
@@ -23,6 +23,9 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
2323 }
2424 }
2525
26+ // Retrieve proxy port from the correct input key
27+ proxyPortValue := inputs["container_port"] // Changed from proxy_port
28+
2629 params := docker.ContainerCommandParams{
2730 IsSSL: inputs["container_protocol"] == "https",
2831 ContainerName: inputs["container_name"],
@@ -31,14 +34,30 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
3134 ImageName: inputs["image_name"],
3235 ImageID: inputs["image_id"],
3336 Restart: inputs["restart"],
34- ProxyPort: inputs["proxy_port"],
37+ ProxyPort: proxyPortValue, // Assign the retrieved value
3538 Volumes: volumeSlice,
3639 Environment: environmentSlice,
3740 Network: a.Config.ContainerEngine.Network,
3841 PortMappings: portMappings,
42+ // Labels will be populated below
43+ }
44+
45+ // Initialize Labels slice if nil
46+ if params.Labels == nil {
47+ params.Labels = []string{}
3948 }
4049
41- err = SetupProxyRoute(&params, params.ProxyPort, a)
50+ // Add standard labels and the proxy port label
51+ params.Labels = append(params.Labels,
52+ fmt.Sprintf("gordon.managed=true"),
53+ fmt.Sprintf("gordon.domain=%s.%s", params.ServiceName, params.Domain),
54+ fmt.Sprintf("gordon.proxy.ssl=%t", params.IsSSL),
55+ fmt.Sprintf("gordon.proxy.port=%s", proxyPortValue), // Add the proxy port label
56+ )
57+
58+ // SetupProxyRoute might need adjustment if it relies on params.ProxyPort directly
59+ // Assuming SetupProxyRoute uses the passed proxyPortValue or reads labels
60+ err = SetupProxyRoute(&params, proxyPortValue, a) // Pass the correct port value
4261 if err != nil {
4362 return docker.ContainerCommandParams{}, fmt.Errorf("error setting up proxy route: %w", err)
4463 }
M internal/templating/models/templ/components/containerlist.templ +3 -3
@@ -1,14 +1,14 @@
11 package components
22
33 import (
4- "github.com/docker/docker/api/types"
4+ "github.com/docker/docker/api/types/container"
55 "strconv"
66 )
77
88 // ContainerList displays a list of containers
9-templ ContainerList(containers []types.Container, noContainer bool) {
9+templ ContainerList(containers []container.Summary, noContainer bool) {
1010 <!-- Container list using daisyUI components -->
11- <div class="card w-full bg-base-300">
11+ <div class="card w-full bg-base-100">
1212 <div class="card-body p-4">
1313
1414 <!-- Action buttons -->
M internal/templating/models/templ/components/containerlist_templ.go +3 -3 generated file: collapsed
M internal/templating/models/templ/components/createcontainer.templ +2 -1
@@ -21,7 +21,7 @@ type ContainerFormData struct {
2121 templ CreateContainerForm(data ContainerFormData) {
2222 <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">
2323 <!-- Left Side: Docker Run Options -->
24- <div class="flex-grow card p-6">
24+ <div class="flex-grow card p-6 bg-base-100">
2525 <h2 class="card-title pb-4">Deploy a container based on { data.ImageName }</h2>
2626 if data.ErrorMessage != "" {
2727 <div class="alert alert-error">
@@ -36,6 +36,7 @@ templ CreateContainerForm(data ContainerFormData) {
3636 hx-swap="innerHTML"
3737 hx-target={ "#create-form-target-" + data.ShortID }>
3838 <!-- Image Name -->
39+ <input type="hidden" name="image_id" value={ data.ImageID } />
3940 <div class="grid grid-cols-1 md:grid-cols-3 gap-4 pb-4">
4041 <div class="md:col-span-1">
4142 <label class="label">
M internal/templating/models/templ/components/createcontainer_templ.go +42 -29 generated file: collapsed
M internal/templating/models/templ/components/imagelist.templ +1 -1
@@ -21,7 +21,7 @@ type HumanReadableImage struct {
2121 // ImageList displays a list of images
2222 templ ImageList(images []HumanReadableImage) {
2323 <!-- Image list using daisyUI components -->
24- <div class="card w-full bg-base-300">
24+ <div class="card w-full bg-base-100">
2525 <div class="card-body p-4">
2626
2727 <!-- Action buttons -->
M internal/templating/models/templ/components/imagelist_templ.go +1 -1 generated file: collapsed
M internal/templating/models/templ/components/navbar.templ +1 -1
@@ -3,7 +3,7 @@ package components
33 // Navbar is a menu component for navigation
44 templ Navbar(buildVersion string, adminPath string, userSettingsURL string, logoutURL string) {
55 <!-- DaisyUI Navbar -->
6- <div class="navbar bg-base-200 shadow-lg fixed top-0 z-50">
6+ <div class="navbar bg-base-100 shadow-lg fixed top-0 z-50">
77 <div class="navbar-start">
88 <div class="flex items-center">
99 <h1 class="gordon-title text-2xl md:text-3xl text-primary tracking-tighter px-4">
M internal/templating/models/templ/components/navbar_templ.go +1 -1 generated file: collapsed
M internal/templating/models/templ/components/success.templ +1 -1
@@ -4,7 +4,7 @@ package components
44 templ Success(message string) {
55 <div
66 id="success"
7- class="flex text-indigo-600 content-center justify-center items-center w-full h-full">
7+ class="flex text-success content-center justify-center items-center w-full h-full">
88 <p class="text-2xl text-center">
99 if message != "" {
1010 { message }
M internal/templating/models/templ/components/success_templ.go +1 -1 generated file: collapsed
M internal/templating/models/templ/layouts/admin_layout.templ +1 -1
@@ -7,7 +7,7 @@ templ AdminLayout(title string, buildVersion string, adminPath string, userSetti
77 <!DOCTYPE html>
88 <html lang="en" data-theme="gordon-dark">
99 @components.Header(title)
10- <body class="min-h-screen bg-base-100">
10+ <body class="min-h-screen bg-base-250">
1111 @components.Navbar(buildVersion, adminPath, userSettingsURL, logoutURL)
1212
1313 <!-- Main content starts after navbar height -->
M internal/templating/models/templ/layouts/admin_layout_templ.go +1 -1 generated file: collapsed
M internal/templating/models/templ/layouts/base.templ +1 -1
@@ -8,7 +8,7 @@ templ Base(title string) {
88 <!DOCTYPE html>
99 <html lang="en">
1010 @components.Header(title)
11- <body class="min-h-screen bg-base-100">
11+ <body class="min-h-screen bg-base-200">
1212 { children... }
1313 @components.Footer()
1414 </body>
M internal/templating/models/templ/layouts/base_templ.go +1 -1 generated file: collapsed
M internal/templating/models/templ/pages/admin/install.templ +1 -1
@@ -13,7 +13,7 @@ templ InstallPage(title string, version string) {
1313 >
1414 <div class="circle-shadow flex justify-center w-100">
1515 <img
16- src="/assets/imgs/gordon-mascot-hq-trsp.png"
16+ src="/assets/imgs/gordon-mascot-mq-trsp.png"
1717 alt="logo"
1818 class="sm:h-24 h-32 xl:h-48"
1919 />
M internal/templating/models/templ/pages/admin/install_templ.go +1 -1 generated file: collapsed
M internal/templating/models/templ/pages/admin/manager.templ +2 -2
@@ -17,7 +17,7 @@ templ ManagerPage(title string, buildVersion string, adminPath string, userSetti
1717 </div>
1818
1919 <!-- Stats overview -->
20- <div class="stats shadow mb-6 w-full bg-base-300">
20+ <div class="stats shadow mb-6 w-full bg-base-100">
2121 <div class="stat">
2222 <div class="stat-figure text-primary">
2323 <span class="iconf text-3xl">󰡨</span>
@@ -38,7 +38,7 @@ templ ManagerPage(title string, buildVersion string, adminPath string, userSetti
3838 </div>
3939
4040 <!-- Tabs for containers and images -->
41- <div role="tablist" class="tabs tabs-boxed mb-4">
41+ <div role="tablist" class="tabs tabs-border mb-4">
4242 <input type="radio" name="my_tabs" role="tab" class="tab" aria-label="Containers" id="containers-tab" checked />
4343 <div role="tabpanel" class="tab-content p-0 bg-base-300">
4444 <!-- Container manager section -->
M internal/templating/models/templ/pages/admin/manager_templ.go +2 -2 generated file: collapsed
M internal/templating/models/templ/pages/errors/errors.templ +2 -5
@@ -16,13 +16,10 @@ templ NotFoundPage(data ErrorPageData) {
1616 @layouts.Base(data.Title) {
1717 <div class="flex flex-col items-center justify-center min-h-screen p-4">
1818 <div class="flex flex-col items-center mb-8">
19- <img src="/assets/imgs/gordon-mascot-hq-trsp.png" alt="Gordon Mascot" class="w-64 h-64 mb-4" />
19+ <img src="/assets/imgs/gordon-mascot-mq-trsp.png" alt="Gordon Mascot" class="w-64 mb-4" />
2020 <h1 class="text-4xl font-bold text-error">404</h1>
2121 <h2 class="text-2xl mb-2">Page Not Found</h2>
2222 <p class="text-center text-base-content opacity-70 max-w-md mb-8">{ data.Message }</p>
23- <a href={ templ.URL(data.AdminPath) } class="btn btn-primary">
24- <span class="iconf mr-2">🏠</span> Go Home
25- </a>
2623 </div>
2724 </div>
2825 }
@@ -33,7 +30,7 @@ templ ForbiddenPage(data ErrorPageData) {
3330 @layouts.Base(data.Title) {
3431 <div class="flex flex-col items-center justify-center min-h-screen p-4">
3532 <div class="flex flex-col items-center mb-8">
36- <img src="/assets/imgs/gordon-mascot-hq-trsp.png" alt="Gordon Mascot" class="w-64 h-64 mb-4" />
33+ <img src="/assets/imgs/gordon-mascot-mq-trsp.png" alt="Gordon Mascot" class="w-64 h-64 mb-4" />
3734 <h1 class="text-4xl font-bold text-error">403</h1>
3835 <h2 class="text-2xl mb-2">Access Forbidden</h2>
3936 <p class="text-center text-base-content opacity-70 max-w-md mb-8">{ data.Message }</p>
M internal/templating/models/templ/pages/errors/errors_templ.go +16 -25 generated file: collapsed
M internal/webui/public/assets/css/custom.css +22 -103
@@ -1,123 +1,42 @@
1-/**
2- * Path: internal/ui/public/assets/css/custom.css
3- *
4- * @format
5- */
6-
7-/* Embeded path : assets/css/cutsom.css */
8-
91 @import "tailwindcss";
10-@plugin "daisyui";
11-
12-/* Custom DaisyUI theme */
2+/* Custom DaisyUI theme - Defined in tailwind.config.js */
133 @plugin "daisyui/theme" {
144 name: "gordon-dark";
155 default: true;
166 prefersdark: true;
177 color-scheme: "dark";
18- --color-base-100: oklch(28% 0.091 267.935);
19- --color-base-200: oklch(20% 0.042 265.755);
20- --color-base-300: oklch(13% 0.028 261.692);
21- --color-base-content: oklch(93% 0.034 272.788);
22- --color-primary: oklch(87% 0 0);
23- --color-primary-content: oklch(14% 0 0);
24- --color-secondary: oklch(80% 0.105 251.813);
25- --color-secondary-content: oklch(28% 0.091 267.935);
26- --color-accent: oklch(80% 0.105 251.813);
27- --color-accent-content: oklch(28% 0.091 267.935);
28- --color-neutral: oklch(37% 0.034 259.733);
29- --color-neutral-content: oklch(98% 0.002 247.839);
8+ --color-base-100: oklch(14% 0 0);
9+ --color-base-200: oklch(21% 0.006 285.885);
10+ --color-base-250: oklch(21% 0.006 285.885);
11+ --color-base-300: oklch(26% 0 0);
12+ --color-base-content: oklch(97% 0.001 106.424);
13+ --color-primary: oklch(44% 0.043 257.281);
14+ --color-primary-content: oklch(98% 0.003 247.858);
15+ --color-secondary: oklch(66% 0.179 58.318);
16+ --color-secondary-content: oklch(98% 0.022 95.277);
17+ --color-accent: oklch(60% 0.118 184.704);
18+ --color-accent-content: oklch(98% 0.014 180.72);
19+ --color-neutral: oklch(42% 0.199 265.638);
20+ --color-neutral-content: oklch(98% 0.001 106.423);
3021 --color-info: oklch(68% 0.169 237.323);
3122 --color-info-content: oklch(97% 0.013 236.62);
32- --color-success: oklch(70% 0.14 182.503);
33- --color-success-content: oklch(98% 0.014 180.72);
34- --color-warning: oklch(76% 0.188 70.08);
35- --color-warning-content: oklch(98% 0.022 95.277);
23+ --color-success: oklch(69% 0.17 162.48);
24+ --color-success-content: oklch(97% 0.021 166.113);
25+ --color-warning: oklch(70% 0.213 47.604);
26+ --color-warning-content: oklch(98% 0.016 73.684);
3627 --color-error: oklch(64% 0.246 16.439);
3728 --color-error-content: oklch(96% 0.015 12.422);
38- --radius-selector: 0rem;
39- --radius-field: 0rem;
40- --radius-box: 0rem;
29+ --radius-selector: 1rem;
30+ --radius-field: 0.5rem;
31+ --radius-box: 1rem;
4132 --size-selector: 0.25rem;
42- --size-field: 0.25rem;
33+ --size-field: 0.21875rem;
4334 --border: 1px;
4435 --depth: 0;
4536 --noise: 0;
4637 }
4738
4839
49-/* Custom component classes */
50-@layer components {
51- /* Button styles */
52- .btn-primary {
53- @apply flex w-full justify-center border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2;
54- }
55-
56- .btn-secondary {
57- @apply flex w-full justify-center border border-secondary bg-secondary px-4 py-2 text-sm font-medium text-secondary-content hover:bg-secondary/90 focus:outline-none focus:ring-2 focus:ring-secondary focus:ring-offset-2;
58- }
59-
60- .btn-danger {
61- @apply flex w-full justify-center border border-transparent bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2;
62- }
63-
64- /* Alert styles */
65- .alert-error {
66- @apply bg-red-50 p-4 dark:bg-red-900/20;
67- }
68-
69- .alert-error-icon {
70- @apply h-5 w-5 text-red-400;
71- }
72-
73- .alert-error-text {
74- @apply text-sm font-medium text-red-800 dark:text-red-300;
75- }
76-
77- .alert-success {
78- @apply bg-green-50 p-4 dark:bg-green-900/20;
79- }
80-
81- .alert-success-icon {
82- @apply h-5 w-5 text-green-400;
83- }
84-
85- .alert-success-text {
86- @apply text-sm font-medium text-green-800 dark:text-green-300;
87- }
88-
89- /* Card styles */
90- .card {
91- @apply bg-base-100 p-4 shadow mb-4;
92- }
93-
94- .card-header {
95- @apply text-lg font-semibold text-indigo-600 mb-2;
96- }
97-
98- /* Background styles */
99- .bg-app {
100- @apply bg-base-300;
101- }
102-
103- .bg-sidebar {
104- @apply bg-indigo-900;
105- }
106-
107- .bg-card {
108- @apply bg-base-100;
109- }
110-
111- /* Text styles */
112- .text-title {
113- @apply text-indigo-600 font-semibold;
114- }
115-
116- .text-subtitle {
117- @apply text-indigo-500;
118- }
119-}
120-
12140 /* Import IBM Plex Fonts */
12241 @font-face {
12342 font-family: "IBMPlexSans-Bold";
M internal/webui/public/assets/css/tailwind.css +474 -7547 large diff (8021 lines changed): collapsed
A node_modules/.bin/cssesc +1 -0 generated file: collapsed
A node_modules/.bin/glob +1 -0 generated file: collapsed
A node_modules/.bin/jiti +1 -0 generated file: collapsed
A node_modules/.bin/nanoid +1 -0 generated file: collapsed
A node_modules/.bin/node-which +1 -0 generated file: collapsed
A node_modules/.bin/prettier +1 -0 generated file: collapsed
A node_modules/.bin/resolve +1 -0 generated file: collapsed
A node_modules/.bin/sucrase +1 -0 generated file: collapsed
A node_modules/.bin/sucrase-node +1 -0 generated file: collapsed
A node_modules/.bin/tailwind +1 -0 generated file: collapsed
A node_modules/.bin/yaml +1 -0 generated file: collapsed
A node_modules/.svelte2tsx-language-server-files/svelte-native-jsx.d.ts +32 -0 generated file: collapsed
A node_modules/.svelte2tsx-language-server-files/svelte-shims-v4.d.ts +287 -0 generated file: collapsed
A node_modules/@alloc/quick-lru/index.d.ts +128 -0 generated file: collapsed
A node_modules/@alloc/quick-lru/index.js +263 -0 generated file: collapsed
A node_modules/@alloc/quick-lru/license +9 -0 generated file: collapsed
A node_modules/@alloc/quick-lru/package.json +43 -0 generated file: collapsed
A node_modules/@alloc/quick-lru/readme.md +139 -0 generated file: collapsed
A node_modules/@isaacs/cliui/README.md +143 -0 generated file: collapsed
A node_modules/@isaacs/cliui/build/index.cjs +317 -0 generated file: collapsed
A node_modules/@isaacs/cliui/build/index.d.cts +43 -0 generated file: collapsed
A node_modules/@isaacs/cliui/build/lib/index.js +302 -0 generated file: collapsed
A node_modules/@isaacs/cliui/index.mjs +14 -0 generated file: collapsed
A node_modules/@isaacs/cliui/package.json +86 -0 generated file: collapsed
A node_modules/@jridgewell/gen-mapping/LICENSE +19 -0 generated file: collapsed
A node_modules/@jridgewell/gen-mapping/README.md +227 -0 generated file: collapsed
A node_modules/@jridgewell/gen-mapping/package.json +76 -0 generated file: collapsed
A node_modules/@jridgewell/resolve-uri/LICENSE +19 -0 generated file: collapsed
A node_modules/@jridgewell/resolve-uri/README.md +40 -0 generated file: collapsed
A node_modules/@jridgewell/resolve-uri/package.json +69 -0 generated file: collapsed
A node_modules/@jridgewell/set-array/LICENSE +19 -0 generated file: collapsed
A node_modules/@jridgewell/set-array/README.md +37 -0 generated file: collapsed
A node_modules/@jridgewell/set-array/package.json +65 -0 generated file: collapsed
A node_modules/@jridgewell/sourcemap-codec/LICENSE +21 -0 generated file: collapsed
A node_modules/@jridgewell/sourcemap-codec/README.md +264 -0 generated file: collapsed
A node_modules/@jridgewell/sourcemap-codec/package.json +75 -0 generated file: collapsed
A node_modules/@jridgewell/trace-mapping/LICENSE +19 -0 generated file: collapsed
A node_modules/@jridgewell/trace-mapping/README.md +257 -0 generated file: collapsed
A node_modules/@jridgewell/trace-mapping/package.json +77 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/LICENSE +21 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/README.md +171 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts +20 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/adapters/fs.js +19 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/constants.d.ts +4 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/constants.js +17 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/index.d.ts +12 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/index.js +26 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/providers/async.d.ts +7 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/providers/async.js +104 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/providers/common.d.ts +1 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/providers/common.js +13 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts +5 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/providers/sync.js +54 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/settings.d.ts +20 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/settings.js +24 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/types/index.d.ts +20 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/types/index.js +2 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts +2 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/utils/fs.js +19 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/utils/index.d.ts +2 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/out/utils/index.js +5 -0 generated file: collapsed
A node_modules/@nodelib/fs.scandir/package.json +44 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/LICENSE +21 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/README.md +126 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts +13 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/adapters/fs.js +17 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/index.d.ts +12 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/index.js +26 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/providers/async.d.ts +4 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/providers/async.js +36 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/providers/sync.d.ts +3 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/providers/sync.js +23 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/settings.d.ts +16 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/settings.js +16 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/types/index.d.ts +4 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/out/types/index.js +2 -0 generated file: collapsed
A node_modules/@nodelib/fs.stat/package.json +37 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/LICENSE +21 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/README.md +215 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/index.d.ts +14 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/index.js +34 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/async.d.ts +12 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/async.js +30 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/index.d.ts +4 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/index.js +9 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/stream.d.ts +12 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/stream.js +34 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/sync.d.ts +10 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/providers/sync.js +14 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/async.d.ts +30 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/async.js +97 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/common.d.ts +7 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/common.js +31 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/reader.d.ts +6 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/reader.js +11 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/sync.d.ts +15 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/readers/sync.js +59 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/settings.d.ts +30 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/settings.js +26 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/types/index.d.ts +8 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/out/types/index.js +2 -0 generated file: collapsed
A node_modules/@nodelib/fs.walk/package.json +44 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-glibc/LICENSE +21 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-glibc/README.md +1 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-glibc/package.json +33 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-glibc/watcher.node +0 -0 binary file: no text diff

binary file: no text diff

A node_modules/@parcel/watcher-linux-x64-musl/LICENSE +21 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-musl/README.md +1 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-musl/package.json +33 -0 generated file: collapsed
A node_modules/@parcel/watcher-linux-x64-musl/watcher.node +0 -0 binary file: no text diff

binary file: no text diff

A node_modules/@parcel/watcher/LICENSE +21 -0 generated file: collapsed
A node_modules/@parcel/watcher/README.md +135 -0 generated file: collapsed
A node_modules/@parcel/watcher/binding.gyp +93 -0 generated file: collapsed
A node_modules/@parcel/watcher/index.d.ts +49 -0 generated file: collapsed
A node_modules/@parcel/watcher/index.js +41 -0 generated file: collapsed
A node_modules/@parcel/watcher/index.js.flow +48 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/.bin/detect-libc +1 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/detect-libc/.npmignore +7 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/detect-libc/LICENSE +201 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/detect-libc/README.md +78 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/detect-libc/bin/detect-libc.js +18 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/detect-libc/lib/detect-libc.js +92 -0 generated file: collapsed
A node_modules/@parcel/watcher/node_modules/detect-libc/package.json +35 -0 generated file: collapsed
A node_modules/@parcel/watcher/package.json +88 -0 generated file: collapsed
A node_modules/@parcel/watcher/scripts/build-from-source.js +13 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Backend.cc +182 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Backend.hh +37 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Debounce.cc +113 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Debounce.hh +49 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/DirTree.cc +152 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/DirTree.hh +50 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Event.hh +109 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Glob.cc +22 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Glob.hh +34 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/PromiseRunner.hh +101 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Signal.hh +46 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Watcher.cc +237 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/Watcher.hh +73 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/binding.cc +268 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc +306 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh +35 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/linux/InotifyBackend.cc +232 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/linux/InotifyBackend.hh +34 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc +338 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh +20 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc +41 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh +25 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/unix/fts.cc +50 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/unix/legacy.cc +77 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/wasm/WasmBackend.cc +132 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/wasm/WasmBackend.hh +34 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/wasm/include.h +74 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/watchman/BSER.cc +302 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/watchman/BSER.hh +69 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/watchman/IPC.hh +175 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc +338 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh +35 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/windows/WindowsBackend.cc +282 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/windows/WindowsBackend.hh +18 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/windows/win_utils.cc +44 -0 generated file: collapsed
A node_modules/@parcel/watcher/src/windows/win_utils.hh +11 -0 generated file: collapsed
A node_modules/@parcel/watcher/wrapper.js +77 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/.editorconfig +14 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/CHANGELOG.md +147 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/LICENSE +201 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/README.md +413 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/examples/is-default-value.js +25 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/examples/limit-long-syntax.js +35 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/examples/negate.js +43 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/examples/no-repeated-options.js +31 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/examples/ordered-options.mjs +41 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/examples/simple-hard-coded.js +26 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/index.js +396 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/internal/errors.js +47 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/internal/primordials.js +393 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/internal/util.js +14 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/internal/validators.js +89 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/package.json +36 -0 generated file: collapsed
A node_modules/@pkgjs/parseargs/utils.js +198 -0 generated file: collapsed
A node_modules/@tailwindcss/cli/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/cli/README.md +40 -0 generated file: collapsed
A node_modules/@tailwindcss/cli/package.json +41 -0 generated file: collapsed
A node_modules/@tailwindcss/node/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/node/README.md +40 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/.bin/jiti +1 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/README.md +235 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti-cli.mjs +34 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti-hooks.mjs +117 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti-native.mjs +121 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti-register.d.mts +1 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti-register.mjs +4 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti.cjs +23 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti.d.cts +8 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti.d.mts +8 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/jiti.mjs +22 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/lib/types.d.ts +260 -0 generated file: collapsed
A node_modules/@tailwindcss/node/node_modules/jiti/package.json +134 -0 generated file: collapsed
A node_modules/@tailwindcss/node/package.json +44 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-gnu/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-gnu/README.md +3 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-gnu/package.json +30 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-gnu/tailwindcss-oxide.linux-x64-gnu.node +0 -0 binary file: no text diff

binary file: no text diff

A node_modules/@tailwindcss/oxide-linux-x64-musl/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-musl/README.md +3 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-musl/package.json +30 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide-linux-x64-musl/tailwindcss-oxide.linux-x64-musl.node +0 -0 binary file: no text diff

binary file: no text diff

A node_modules/@tailwindcss/oxide/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide/index.d.ts +37 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide/index.js +315 -0 generated file: collapsed
A node_modules/@tailwindcss/oxide/package.json +63 -0 generated file: collapsed
A node_modules/@tailwindcss/postcss/LICENSE +21 -0 generated file: collapsed
A node_modules/@tailwindcss/postcss/README.md +40 -0 generated file: collapsed
A node_modules/@tailwindcss/postcss/package.json +47 -0 generated file: collapsed
A node_modules/ansi-regex/index.d.ts +33 -0 generated file: collapsed
A node_modules/ansi-regex/index.js +10 -0 generated file: collapsed
A node_modules/ansi-regex/license +9 -0 generated file: collapsed
A node_modules/ansi-regex/package.json +61 -0 generated file: collapsed
A node_modules/ansi-regex/readme.md +60 -0 generated file: collapsed
A node_modules/ansi-styles/index.d.ts +236 -0 generated file: collapsed
A node_modules/ansi-styles/index.js +223 -0 generated file: collapsed
A node_modules/ansi-styles/license +9 -0 generated file: collapsed
A node_modules/ansi-styles/package.json +54 -0 generated file: collapsed
A node_modules/ansi-styles/readme.md +173 -0 generated file: collapsed
A node_modules/any-promise/.jshintrc +4 -0 generated file: collapsed
A node_modules/any-promise/.npmignore +7 -0 generated file: collapsed
A node_modules/any-promise/LICENSE +19 -0 generated file: collapsed
A node_modules/any-promise/README.md +161 -0 generated file: collapsed
A node_modules/any-promise/implementation.d.ts +3 -0 generated file: collapsed
A node_modules/any-promise/implementation.js +1 -0 generated file: collapsed
A node_modules/any-promise/index.d.ts +73 -0 generated file: collapsed
A node_modules/any-promise/index.js +1 -0 generated file: collapsed
A node_modules/any-promise/loader.js +78 -0 generated file: collapsed
A node_modules/any-promise/optional.js +6 -0 generated file: collapsed
A node_modules/any-promise/package.json +45 -0 generated file: collapsed
A node_modules/any-promise/register-shim.js +18 -0 generated file: collapsed
A node_modules/any-promise/register.d.ts +17 -0 generated file: collapsed
A node_modules/any-promise/register.js +94 -0 generated file: collapsed
A node_modules/any-promise/register/bluebird.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/bluebird.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/es6-promise.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/es6-promise.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/lie.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/lie.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/native-promise-only.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/native-promise-only.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/pinkie.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/pinkie.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/promise.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/promise.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/q.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/q.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/rsvp.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/rsvp.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/vow.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/vow.js +2 -0 generated file: collapsed
A node_modules/any-promise/register/when.d.ts +1 -0 generated file: collapsed
A node_modules/any-promise/register/when.js +2 -0 generated file: collapsed
A node_modules/anymatch/LICENSE +15 -0 generated file: collapsed
A node_modules/anymatch/README.md +87 -0 generated file: collapsed
A node_modules/anymatch/index.d.ts +20 -0 generated file: collapsed
A node_modules/anymatch/index.js +104 -0 generated file: collapsed
A node_modules/anymatch/package.json +48 -0 generated file: collapsed
A node_modules/arg/LICENSE.md +21 -0 generated file: collapsed
A node_modules/arg/README.md +317 -0 generated file: collapsed
A node_modules/arg/index.d.ts +44 -0 generated file: collapsed
A node_modules/arg/index.js +195 -0 generated file: collapsed
A node_modules/arg/package.json +28 -0 collapsed to keep the page light
A node_modules/balanced-match/.github/FUNDING.yml +2 -0 collapsed to keep the page light
A node_modules/balanced-match/LICENSE.md +21 -0 collapsed to keep the page light
A node_modules/balanced-match/README.md +97 -0 collapsed to keep the page light
A node_modules/balanced-match/index.js +62 -0 collapsed to keep the page light
A node_modules/balanced-match/package.json +48 -0 collapsed to keep the page light
A node_modules/binary-extensions/binary-extensions.json +263 -0 collapsed to keep the page light
A node_modules/binary-extensions/binary-extensions.json.d.ts +3 -0 collapsed to keep the page light
A node_modules/binary-extensions/index.d.ts +14 -0 collapsed to keep the page light
A node_modules/binary-extensions/index.js +1 -0 collapsed to keep the page light
A node_modules/binary-extensions/license +10 -0 collapsed to keep the page light
A node_modules/binary-extensions/package.json +40 -0 collapsed to keep the page light
A node_modules/binary-extensions/readme.md +25 -0 collapsed to keep the page light
A node_modules/brace-expansion/.github/FUNDING.yml +2 -0 collapsed to keep the page light
A node_modules/brace-expansion/LICENSE +21 -0 collapsed to keep the page light
A node_modules/brace-expansion/README.md +135 -0 collapsed to keep the page light
A node_modules/brace-expansion/index.js +203 -0 collapsed to keep the page light
A node_modules/brace-expansion/package.json +46 -0 collapsed to keep the page light
A node_modules/braces/LICENSE +21 -0 collapsed to keep the page light
A node_modules/braces/README.md +586 -0 collapsed to keep the page light
A node_modules/braces/index.js +170 -0 collapsed to keep the page light
A node_modules/braces/lib/compile.js +60 -0 collapsed to keep the page light
A node_modules/braces/lib/constants.js +57 -0 collapsed to keep the page light
A node_modules/braces/lib/expand.js +113 -0 collapsed to keep the page light
A node_modules/braces/lib/parse.js +331 -0 collapsed to keep the page light
A node_modules/braces/lib/stringify.js +32 -0 collapsed to keep the page light
A node_modules/braces/lib/utils.js +122 -0 collapsed to keep the page light
A node_modules/braces/package.json +77 -0 collapsed to keep the page light
A node_modules/camelcase-css/README.md +27 -0 collapsed to keep the page light
A node_modules/camelcase-css/index-es5.js +24 -0 collapsed to keep the page light
A node_modules/camelcase-css/index.js +30 -0 collapsed to keep the page light
A node_modules/camelcase-css/license +21 -0 collapsed to keep the page light
A node_modules/camelcase-css/package.json +34 -0 collapsed to keep the page light
A node_modules/caniuse-lite/LICENSE +395 -0 collapsed to keep the page light
A node_modules/caniuse-lite/README.md +6 -0 collapsed to keep the page light
A node_modules/caniuse-lite/package.json +34 -0 collapsed to keep the page light
A node_modules/chokidar/LICENSE +21 -0 collapsed to keep the page light
A node_modules/chokidar/README.md +308 -0 collapsed to keep the page light
A node_modules/chokidar/index.js +973 -0 collapsed to keep the page light
A node_modules/chokidar/lib/constants.js +66 -0 collapsed to keep the page light
A node_modules/chokidar/lib/fsevents-handler.js +526 -0 collapsed to keep the page light
A node_modules/chokidar/lib/nodefs-handler.js +654 -0 collapsed to keep the page light
A node_modules/chokidar/node_modules/glob-parent/CHANGELOG.md +110 -0 collapsed to keep the page light
A node_modules/chokidar/node_modules/glob-parent/LICENSE +15 -0 collapsed to keep the page light
A node_modules/chokidar/node_modules/glob-parent/README.md +137 -0 collapsed to keep the page light
A node_modules/chokidar/node_modules/glob-parent/index.js +42 -0 collapsed to keep the page light
A node_modules/chokidar/node_modules/glob-parent/package.json +48 -0 collapsed to keep the page light
A node_modules/chokidar/package.json +70 -0 collapsed to keep the page light
A node_modules/chokidar/types/index.d.ts +192 -0 collapsed to keep the page light
A node_modules/color-convert/CHANGELOG.md +54 -0 collapsed to keep the page light
A node_modules/color-convert/LICENSE +21 -0 collapsed to keep the page light
A node_modules/color-convert/README.md +68 -0 collapsed to keep the page light
A node_modules/color-convert/conversions.js +839 -0 collapsed to keep the page light
A node_modules/color-convert/index.js +81 -0 collapsed to keep the page light
A node_modules/color-convert/package.json +48 -0 collapsed to keep the page light
A node_modules/color-convert/route.js +97 -0 collapsed to keep the page light
A node_modules/color-name/LICENSE +8 -0 collapsed to keep the page light
A node_modules/color-name/README.md +11 -0 collapsed to keep the page light
A node_modules/color-name/index.js +152 -0 collapsed to keep the page light
A node_modules/color-name/package.json +28 -0 collapsed to keep the page light
A node_modules/commander/CHANGELOG.md +436 -0 collapsed to keep the page light
A node_modules/commander/LICENSE +22 -0 collapsed to keep the page light
A node_modules/commander/Readme.md +713 -0 collapsed to keep the page light
A node_modules/commander/index.js +1649 -0 collapsed to keep the page light
A node_modules/commander/package.json +41 -0 collapsed to keep the page light
A node_modules/commander/typings/index.d.ts +311 -0 collapsed to keep the page light
A node_modules/cross-spawn/CHANGELOG.md +130 -0 collapsed to keep the page light
A node_modules/cross-spawn/LICENSE +21 -0 collapsed to keep the page light
A node_modules/cross-spawn/README.md +96 -0 collapsed to keep the page light
A node_modules/cross-spawn/index.js +39 -0 collapsed to keep the page light
A node_modules/cross-spawn/lib/enoent.js +59 -0 collapsed to keep the page light
A node_modules/cross-spawn/lib/parse.js +91 -0 collapsed to keep the page light
A node_modules/cross-spawn/lib/util/escape.js +45 -0 collapsed to keep the page light
A node_modules/cross-spawn/lib/util/readShebang.js +23 -0 collapsed to keep the page light
A node_modules/cross-spawn/lib/util/resolveCommand.js +52 -0 collapsed to keep the page light
A node_modules/cross-spawn/package.json +73 -0 collapsed to keep the page light
A node_modules/cssesc/README.md +201 -0 collapsed to keep the page light
A node_modules/cssesc/bin/cssesc +116 -0 collapsed to keep the page light
A node_modules/cssesc/cssesc.js +110 -0 collapsed to keep the page light
A node_modules/cssesc/man/cssesc.1 +70 -0 collapsed to keep the page light
A node_modules/cssesc/package.json +51 -0 collapsed to keep the page light
A node_modules/daisyui/LICENSE +21 -0 collapsed to keep the page light
A node_modules/daisyui/README.md +37 -0 collapsed to keep the page light
A node_modules/daisyui/base/properties.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/properties/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/base/properties/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/reset.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootcolor.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootcolor/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootcolor/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootscrollgutter.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootscrollgutter/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootscrollgutter/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootscrolllock.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootscrolllock/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/base/rootscrolllock/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/scrollbar.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/scrollbar/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/base/scrollbar/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/svg.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/base/svg/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/base/svg/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/chunks.css +73 -0 collapsed to keep the page light
A node_modules/daisyui/colors/properties-extended.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/colors/properties.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/colors/responsive-extended.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/colors/responsive.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/colors/states-extended.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/colors/states.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/alert.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/alert/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/alert/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/avatar.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/avatar/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/avatar/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/badge.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/badge/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/badge/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/breadcrumbs.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/breadcrumbs/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/breadcrumbs/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/button.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/button/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/button/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/calendar.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/calendar/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/calendar/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/card.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/card/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/card/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/carousel.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/carousel/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/carousel/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/chat.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/chat/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/chat/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/checkbox.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/checkbox/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/checkbox/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/collapse.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/collapse/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/collapse/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/countdown.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/countdown/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/countdown/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/diff.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/diff/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/diff/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/divider.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/divider/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/divider/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/dock.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/dock/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/dock/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/drawer.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/drawer/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/drawer/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/dropdown.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/dropdown/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/dropdown/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/fieldset.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/fieldset/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/fieldset/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/fileinput.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/fileinput/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/fileinput/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/filter.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/filter/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/filter/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/footer.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/footer/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/footer/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/hero.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/hero/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/hero/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/indicator.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/indicator/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/indicator/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/input.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/input/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/input/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/kbd.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/kbd/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/kbd/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/label.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/label/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/label/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/link.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/link/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/link/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/list.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/list/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/list/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/loading.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/loading/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/loading/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/mask.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/mask/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/mask/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/menu.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/menu/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/menu/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/mockup.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/mockup/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/mockup/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/modal.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/modal/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/modal/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/navbar.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/navbar/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/navbar/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/progress.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/progress/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/progress/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/radialprogress.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/radialprogress/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/radialprogress/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/radio.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/radio/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/radio/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/range.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/range/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/range/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/rating.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/rating/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/rating/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/select.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/select/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/select/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/skeleton.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/skeleton/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/skeleton/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/stack.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/stack/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/stack/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/stat.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/stat/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/stat/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/status.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/status/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/status/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/steps.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/steps/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/steps/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/swap.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/swap/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/swap/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/tab.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/tab/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/tab/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/table.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/table/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/table/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/textarea.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/textarea/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/textarea/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/timeline.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/timeline/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/timeline/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/toast.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/toast/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/toast/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/toggle.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/toggle/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/toggle/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/tooltip.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/tooltip/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/tooltip/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/validator.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/components/validator/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/components/validator/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/daisyui.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/functions/addPrefix.js +156 -0 collapsed to keep the page light
A node_modules/daisyui/functions/plugin.js +11 -0 collapsed to keep the page light
A node_modules/daisyui/functions/pluginOptionsHandler.js +86 -0 collapsed to keep the page light
A node_modules/daisyui/functions/themeOrder.js +37 -0 collapsed to keep the page light
A node_modules/daisyui/functions/variables.js +29 -0 collapsed to keep the page light
A node_modules/daisyui/imports.js +68 -0 collapsed to keep the page light
A node_modules/daisyui/index.js +51 -0 collapsed to keep the page light
A node_modules/daisyui/package.json +72 -0 collapsed to keep the page light
A node_modules/daisyui/theme/abyss.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/abyss/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/abyss/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/acid.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/acid/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/acid/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/aqua.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/aqua/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/aqua/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/autumn.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/autumn/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/autumn/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/black.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/black/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/black/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/bumblebee.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/bumblebee/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/bumblebee/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/business.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/business/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/business/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/caramellatte.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/caramellatte/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/caramellatte/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cmyk.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cmyk/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cmyk/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/coffee.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/coffee/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/coffee/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/corporate.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/corporate/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/corporate/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cupcake.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cupcake/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cupcake/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cyberpunk.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cyberpunk/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/cyberpunk/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dark.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dark/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dark/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dim.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dim/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dim/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dracula.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dracula/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/dracula/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/emerald.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/emerald/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/emerald/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/fantasy.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/fantasy/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/fantasy/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/forest.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/forest/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/forest/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/garden.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/garden/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/garden/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/halloween.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/halloween/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/halloween/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/index.js +48 -0 collapsed to keep the page light
A node_modules/daisyui/theme/lemonade.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/lemonade/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/lemonade/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/light.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/light/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/light/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/lofi.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/lofi/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/lofi/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/luxury.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/luxury/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/luxury/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/night.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/night/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/night/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/nord.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/nord/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/nord/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/object.d.ts +74 -0 collapsed to keep the page light
A node_modules/daisyui/theme/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/pastel.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/pastel/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/pastel/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/retro.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/retro/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/retro/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/silk.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/silk/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/silk/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/sunset.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/sunset/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/sunset/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/synthwave.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/synthwave/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/synthwave/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/valentine.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/valentine/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/valentine/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/winter.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/winter/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/winter/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/theme/wireframe.css +31 -0 collapsed to keep the page light
A node_modules/daisyui/theme/wireframe/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/theme/wireframe/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/themes.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/glass.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/glass/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/glass/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/join.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/join/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/join/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/radius.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/radius/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/radius/object.js +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/typography.css +1 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/typography/index.js +7 -0 collapsed to keep the page light
A node_modules/daisyui/utilities/typography/object.js +1 -0 collapsed to keep the page light
A node_modules/detect-libc/LICENSE +201 -0 collapsed to keep the page light
A node_modules/detect-libc/README.md +163 -0 collapsed to keep the page light
A node_modules/detect-libc/index.d.ts +14 -0 collapsed to keep the page light
A node_modules/detect-libc/lib/detect-libc.js +267 -0 collapsed to keep the page light
A node_modules/detect-libc/lib/filesystem.js +41 -0 collapsed to keep the page light
A node_modules/detect-libc/lib/process.js +24 -0 collapsed to keep the page light
A node_modules/detect-libc/package.json +40 -0 collapsed to keep the page light
A node_modules/didyoumean/LICENSE +14 -0 collapsed to keep the page light
A node_modules/didyoumean/README.md +134 -0 collapsed to keep the page light
A node_modules/didyoumean/didYouMean-1.2.1.js +274 -0 collapsed to keep the page light
A node_modules/didyoumean/didYouMean-1.2.1.min.js +17 -0 collapsed to keep the page light
A node_modules/didyoumean/package.json +27 -0 collapsed to keep the page light
A node_modules/dlv/README.md +76 -0 collapsed to keep the page light
A node_modules/dlv/index.js +7 -0 collapsed to keep the page light
A node_modules/dlv/package.json +30 -0 collapsed to keep the page light
A node_modules/dotenv/CHANGELOG.md +488 -0 collapsed to keep the page light
A node_modules/dotenv/LICENSE +23 -0 collapsed to keep the page light
A node_modules/dotenv/README-es.md +448 -0 collapsed to keep the page light
A node_modules/dotenv/README.md +651 -0 collapsed to keep the page light
A node_modules/dotenv/config.d.ts +1 -0 collapsed to keep the page light
A node_modules/dotenv/config.js +9 -0 collapsed to keep the page light
A node_modules/dotenv/lib/cli-options.js +11 -0 collapsed to keep the page light
A node_modules/dotenv/lib/env-options.js +24 -0 collapsed to keep the page light
A node_modules/dotenv/lib/main.d.ts +153 -0 collapsed to keep the page light
A node_modules/dotenv/lib/main.js +361 -0 collapsed to keep the page light
A node_modules/dotenv/package.json +61 -0 collapsed to keep the page light
A node_modules/eastasianwidth/README.md +32 -0 collapsed to keep the page light
A node_modules/eastasianwidth/eastasianwidth.js +311 -0 collapsed to keep the page light
A node_modules/eastasianwidth/package.json +18 -0 collapsed to keep the page light
A node_modules/emoji-regex/README.md +137 -0 collapsed to keep the page light
A node_modules/emoji-regex/RGI_Emoji.d.ts +5 -0 collapsed to keep the page light
A node_modules/emoji-regex/RGI_Emoji.js +6 -0 collapsed to keep the page light
A node_modules/emoji-regex/es2015/RGI_Emoji.d.ts +5 -0 collapsed to keep the page light
A node_modules/emoji-regex/es2015/RGI_Emoji.js +6 -0 collapsed to keep the page light
A node_modules/emoji-regex/es2015/index.d.ts +5 -0 collapsed to keep the page light
A node_modules/emoji-regex/es2015/index.js +6 -0 collapsed to keep the page light
A node_modules/emoji-regex/es2015/text.d.ts +5 -0 collapsed to keep the page light
A node_modules/emoji-regex/es2015/text.js +6 -0 collapsed to keep the page light
A node_modules/emoji-regex/index.d.ts +5 -0 collapsed to keep the page light
A node_modules/emoji-regex/index.js +6 -0 collapsed to keep the page light
A node_modules/emoji-regex/package.json +52 -0 collapsed to keep the page light
A node_modules/emoji-regex/text.d.ts +5 -0 collapsed to keep the page light
A node_modules/emoji-regex/text.js +6 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/LICENSE +20 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/README.md +183 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/AliasFieldPlugin.js +108 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/AliasPlugin.js +183 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/AppendPlugin.js +49 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/CachedInputFileSystem.js +664 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/CloneBasenamePlugin.js +53 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ConditionalPlugin.js +59 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js +98 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/DescriptionFileUtils.js +201 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/DirectoryExistsPlugin.js +63 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ExportsFieldPlugin.js +200 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ExtensionAliasPlugin.js +101 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/FileExistsPlugin.js +58 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ImportsFieldPlugin.js +223 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/JoinRequestPartPlugin.js +75 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/JoinRequestPlugin.js +45 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/LogInfoPlugin.js +54 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/MainFieldPlugin.js +90 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ModulesInHierachicDirectoriesPlugin.js +9 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ModulesInHierarchicalDirectoriesPlugin.js +87 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ModulesInRootPlugin.js +49 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/NextPlugin.js +33 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ParsePlugin.js +76 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/PnpPlugin.js +133 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/Resolver.js +800 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ResolverFactory.js +728 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/RestrictionsPlugin.js +70 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/ResultPlugin.js +42 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/RootsPlugin.js +69 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/SelfReferencePlugin.js +82 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/SymlinkPlugin.js +100 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/SyncAsyncFileSystemDecorator.js +220 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/TryNextPlugin.js +41 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js +112 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/UseFilePlugin.js +55 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/createInnerContext.js +46 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/forEachBail.js +50 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/getInnerRequest.js +36 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/getPaths.js +45 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/index.js +203 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/util/entrypoints.js +573 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/util/identifier.js +69 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/util/module-browser.js +8 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/util/path.js +203 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/lib/util/process-browser.js +22 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/package.json +72 -0 collapsed to keep the page light
A node_modules/enhanced-resolve/types.d.ts +1135 -0 collapsed to keep the page light
A node_modules/fast-glob/LICENSE +21 -0 collapsed to keep the page light
A node_modules/fast-glob/README.md +830 -0 collapsed to keep the page light
A node_modules/fast-glob/node_modules/glob-parent/CHANGELOG.md +110 -0 collapsed to keep the page light
A node_modules/fast-glob/node_modules/glob-parent/LICENSE +15 -0 collapsed to keep the page light
A node_modules/fast-glob/node_modules/glob-parent/README.md +137 -0 collapsed to keep the page light
A node_modules/fast-glob/node_modules/glob-parent/index.js +42 -0 collapsed to keep the page light
A node_modules/fast-glob/node_modules/glob-parent/package.json +48 -0 collapsed to keep the page light
A node_modules/fast-glob/out/index.d.ts +40 -0 collapsed to keep the page light
A node_modules/fast-glob/out/index.js +102 -0 collapsed to keep the page light
A node_modules/fast-glob/out/managers/tasks.d.ts +22 -0 collapsed to keep the page light
A node_modules/fast-glob/out/managers/tasks.js +110 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/async.d.ts +9 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/async.js +23 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/filters/deep.d.ts +16 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/filters/deep.js +62 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/filters/entry.d.ts +16 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/filters/entry.js +63 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/filters/error.d.ts +8 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/filters/error.js +15 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/matchers/matcher.d.ts +33 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/matchers/matcher.js +45 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/matchers/partial.d.ts +4 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/matchers/partial.js +38 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/provider.d.ts +19 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/provider.js +48 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/stream.d.ts +11 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/stream.js +31 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/sync.d.ts +9 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/sync.js +23 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/transformers/entry.d.ts +8 -0 collapsed to keep the page light
A node_modules/fast-glob/out/providers/transformers/entry.js +26 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/async.d.ts +10 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/async.js +35 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/reader.d.ts +15 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/reader.js +33 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/stream.d.ts +14 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/stream.js +55 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/sync.d.ts +12 -0 collapsed to keep the page light
A node_modules/fast-glob/out/readers/sync.js +43 -0 collapsed to keep the page light
A node_modules/fast-glob/out/settings.d.ts +164 -0 collapsed to keep the page light
A node_modules/fast-glob/out/settings.js +59 -0 collapsed to keep the page light
A node_modules/fast-glob/out/types/index.d.ts +31 -0 collapsed to keep the page light
A node_modules/fast-glob/out/types/index.js +2 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/array.d.ts +2 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/array.js +22 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/errno.d.ts +2 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/errno.js +7 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/fs.d.ts +4 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/fs.js +19 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/index.d.ts +8 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/index.js +17 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/path.d.ts +13 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/path.js +68 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/pattern.d.ts +47 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/pattern.js +188 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/stream.d.ts +4 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/stream.js +17 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/string.d.ts +2 -0 collapsed to keep the page light
A node_modules/fast-glob/out/utils/string.js +11 -0 collapsed to keep the page light
A node_modules/fast-glob/package.json +81 -0 collapsed to keep the page light
A node_modules/fastq/.github/dependabot.yml +11 -0 collapsed to keep the page light
A node_modules/fastq/.github/workflows/ci.yml +75 -0 collapsed to keep the page light
A node_modules/fastq/LICENSE +13 -0 collapsed to keep the page light
A node_modules/fastq/README.md +306 -0 collapsed to keep the page light
A node_modules/fastq/bench.js +66 -0 collapsed to keep the page light
A node_modules/fastq/example.js +14 -0 collapsed to keep the page light
A node_modules/fastq/example.mjs +11 -0 collapsed to keep the page light
A node_modules/fastq/index.d.ts +38 -0 collapsed to keep the page light
A node_modules/fastq/package.json +53 -0 collapsed to keep the page light
A node_modules/fastq/queue.js +311 -0 collapsed to keep the page light
A node_modules/fastq/test/example.ts +83 -0 collapsed to keep the page light
A node_modules/fastq/test/promise.js +248 -0 collapsed to keep the page light
A node_modules/fastq/test/test.js +642 -0 collapsed to keep the page light
A node_modules/fastq/test/tsconfig.json +11 -0 collapsed to keep the page light
A node_modules/fill-range/LICENSE +21 -0 collapsed to keep the page light
A node_modules/fill-range/README.md +237 -0 collapsed to keep the page light
A node_modules/fill-range/index.js +248 -0 collapsed to keep the page light
A node_modules/fill-range/package.json +74 -0 collapsed to keep the page light
A node_modules/foreground-child/LICENSE +15 -0 collapsed to keep the page light
A node_modules/foreground-child/README.md +128 -0 collapsed to keep the page light
A node_modules/foreground-child/package.json +111 -0 collapsed to keep the page light
A node_modules/function-bind/.eslintrc +21 -0 collapsed to keep the page light
A node_modules/function-bind/.github/FUNDING.yml +12 -0 collapsed to keep the page light
A node_modules/function-bind/.github/SECURITY.md +3 -0 collapsed to keep the page light
A node_modules/function-bind/.nycrc +13 -0 collapsed to keep the page light
A node_modules/function-bind/CHANGELOG.md +136 -0 collapsed to keep the page light
A node_modules/function-bind/LICENSE +20 -0 collapsed to keep the page light
A node_modules/function-bind/README.md +46 -0 collapsed to keep the page light
A node_modules/function-bind/implementation.js +84 -0 collapsed to keep the page light
A node_modules/function-bind/index.js +5 -0 collapsed to keep the page light
A node_modules/function-bind/package.json +87 -0 collapsed to keep the page light
A node_modules/function-bind/test/.eslintrc +9 -0 collapsed to keep the page light
A node_modules/function-bind/test/index.js +252 -0 collapsed to keep the page light
A node_modules/glob-parent/LICENSE +15 -0 collapsed to keep the page light
A node_modules/glob-parent/README.md +134 -0 collapsed to keep the page light
A node_modules/glob-parent/index.js +75 -0 collapsed to keep the page light
A node_modules/glob-parent/package.json +54 -0 collapsed to keep the page light
A node_modules/glob/LICENSE +15 -0 collapsed to keep the page light
A node_modules/glob/README.md +1265 -0 collapsed to keep the page light
A node_modules/glob/package.json +99 -0 collapsed to keep the page light
A node_modules/graceful-fs/LICENSE +15 -0 collapsed to keep the page light
A node_modules/graceful-fs/README.md +143 -0 collapsed to keep the page light
A node_modules/graceful-fs/clone.js +23 -0 collapsed to keep the page light
A node_modules/graceful-fs/graceful-fs.js +448 -0 collapsed to keep the page light
A node_modules/graceful-fs/legacy-streams.js +118 -0 collapsed to keep the page light
A node_modules/graceful-fs/package.json +53 -0 collapsed to keep the page light
A node_modules/graceful-fs/polyfills.js +355 -0 collapsed to keep the page light
A node_modules/hasown/.eslintrc +5 -0 collapsed to keep the page light
A node_modules/hasown/.github/FUNDING.yml +12 -0 collapsed to keep the page light
A node_modules/hasown/.nycrc +13 -0 collapsed to keep the page light
A node_modules/hasown/CHANGELOG.md +40 -0 collapsed to keep the page light
A node_modules/hasown/LICENSE +21 -0 collapsed to keep the page light
A node_modules/hasown/README.md +40 -0 collapsed to keep the page light
A node_modules/hasown/index.d.ts +3 -0 collapsed to keep the page light
A node_modules/hasown/index.js +8 -0 collapsed to keep the page light
A node_modules/hasown/package.json +92 -0 collapsed to keep the page light
A node_modules/hasown/tsconfig.json +6 -0 collapsed to keep the page light
A node_modules/is-binary-path/index.d.ts +17 -0 collapsed to keep the page light
A node_modules/is-binary-path/index.js +7 -0 collapsed to keep the page light
A node_modules/is-binary-path/license +9 -0 collapsed to keep the page light
A node_modules/is-binary-path/package.json +40 -0 collapsed to keep the page light
A node_modules/is-binary-path/readme.md +34 -0 collapsed to keep the page light
A node_modules/is-core-module/.eslintrc +18 -0 collapsed to keep the page light
A node_modules/is-core-module/.nycrc +9 -0 collapsed to keep the page light
A node_modules/is-core-module/CHANGELOG.md +205 -0 collapsed to keep the page light
A node_modules/is-core-module/LICENSE +20 -0 collapsed to keep the page light
A node_modules/is-core-module/README.md +40 -0 collapsed to keep the page light
A node_modules/is-core-module/core.json +161 -0 collapsed to keep the page light
A node_modules/is-core-module/index.js +69 -0 collapsed to keep the page light
A node_modules/is-core-module/package.json +76 -0 collapsed to keep the page light
A node_modules/is-core-module/test/index.js +154 -0 collapsed to keep the page light
A node_modules/is-extglob/LICENSE +21 -0 collapsed to keep the page light
A node_modules/is-extglob/README.md +107 -0 collapsed to keep the page light
A node_modules/is-extglob/index.js +20 -0 collapsed to keep the page light
A node_modules/is-extglob/package.json +69 -0 collapsed to keep the page light
A node_modules/is-fullwidth-code-point/index.d.ts +17 -0 collapsed to keep the page light
A node_modules/is-fullwidth-code-point/index.js +50 -0 collapsed to keep the page light
A node_modules/is-fullwidth-code-point/license +9 -0 collapsed to keep the page light
A node_modules/is-fullwidth-code-point/package.json +42 -0 collapsed to keep the page light
A node_modules/is-fullwidth-code-point/readme.md +39 -0 collapsed to keep the page light
A node_modules/is-glob/LICENSE +21 -0 collapsed to keep the page light
A node_modules/is-glob/README.md +206 -0 collapsed to keep the page light
A node_modules/is-glob/index.js +150 -0 collapsed to keep the page light
A node_modules/is-glob/package.json +81 -0 collapsed to keep the page light
A node_modules/is-number/LICENSE +21 -0 collapsed to keep the page light
A node_modules/is-number/README.md +187 -0 collapsed to keep the page light
A node_modules/is-number/index.js +18 -0 collapsed to keep the page light
A node_modules/is-number/package.json +82 -0 collapsed to keep the page light
A node_modules/isexe/.npmignore +2 -0 collapsed to keep the page light
A node_modules/isexe/LICENSE +15 -0 collapsed to keep the page light
A node_modules/isexe/README.md +51 -0 collapsed to keep the page light
A node_modules/isexe/index.js +57 -0 collapsed to keep the page light
A node_modules/isexe/mode.js +41 -0 collapsed to keep the page light
A node_modules/isexe/package.json +31 -0 collapsed to keep the page light
A node_modules/isexe/test/basic.js +221 -0 collapsed to keep the page light
A node_modules/isexe/windows.js +42 -0 collapsed to keep the page light
A node_modules/jackspeak/LICENSE.md +55 -0 collapsed to keep the page light
A node_modules/jackspeak/README.md +357 -0 collapsed to keep the page light
A node_modules/jackspeak/package.json +95 -0 collapsed to keep the page light
A node_modules/jiti/LICENSE +21 -0 collapsed to keep the page light
A node_modules/jiti/README.md +235 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti-cli.mjs +34 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti-hooks.mjs +117 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti-native.mjs +121 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti-register.d.mts +1 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti-register.mjs +4 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti.cjs +23 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti.d.cts +8 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti.d.mts +8 -0 collapsed to keep the page light
A node_modules/jiti/lib/jiti.mjs +22 -0 collapsed to keep the page light
A node_modules/jiti/lib/types.d.ts +260 -0 collapsed to keep the page light
A node_modules/jiti/package.json +134 -0 collapsed to keep the page light
A node_modules/lightningcss-linux-x64-gnu/LICENSE +373 -0 collapsed to keep the page light
A node_modules/lightningcss-linux-x64-gnu/README.md +1 -0 collapsed to keep the page light
A node_modules/lightningcss-linux-x64-gnu/lightningcss.linux-x64-gnu.node +0 -0 binary file: no text diff

binary file: no text diff

A node_modules/lightningcss-linux-x64-gnu/package.json +37 -0 collapsed to keep the page light
A node_modules/lightningcss-linux-x64-musl/LICENSE +373 -0 collapsed to keep the page light
A node_modules/lightningcss-linux-x64-musl/README.md +1 -0 collapsed to keep the page light
A node_modules/lightningcss-linux-x64-musl/lightningcss.linux-x64-musl.node +0 -0 binary file: no text diff

binary file: no text diff

A node_modules/lightningcss-linux-x64-musl/package.json +37 -0 collapsed to keep the page light
A node_modules/lightningcss/LICENSE +373 -0 collapsed to keep the page light
A node_modules/lightningcss/README.md +105 -0 collapsed to keep the page light
A node_modules/lightningcss/node/ast.d.ts +9716 -0 collapsed to keep the page light
A node_modules/lightningcss/node/ast.js.flow +10346 -0 collapsed to keep the page light
A node_modules/lightningcss/node/browserslistToTargets.js +48 -0 collapsed to keep the page light
A node_modules/lightningcss/node/composeVisitors.js +442 -0 collapsed to keep the page light
A node_modules/lightningcss/node/flags.js +28 -0 collapsed to keep the page light
A node_modules/lightningcss/node/index.d.ts +477 -0 collapsed to keep the page light
A node_modules/lightningcss/node/index.js +28 -0 collapsed to keep the page light
A node_modules/lightningcss/node/index.js.flow +824 -0 collapsed to keep the page light
A node_modules/lightningcss/node/index.mjs +4 -0 collapsed to keep the page light
A node_modules/lightningcss/node/targets.d.ts +40 -0 collapsed to keep the page light
A node_modules/lightningcss/node/targets.js.flow +39 -0 collapsed to keep the page light
A node_modules/lightningcss/package.json +109 -0 collapsed to keep the page light
A node_modules/lilconfig/LICENSE +21 -0 collapsed to keep the page light
A node_modules/lilconfig/package.json +42 -0 collapsed to keep the page light
A node_modules/lilconfig/readme.md +98 -0 collapsed to keep the page light
A node_modules/lilconfig/src/index.d.ts +54 -0 collapsed to keep the page light
A node_modules/lilconfig/src/index.js +460 -0 collapsed to keep the page light
A node_modules/lines-and-columns/LICENSE +21 -0 collapsed to keep the page light
A node_modules/lines-and-columns/README.md +33 -0 collapsed to keep the page light
A node_modules/lines-and-columns/build/index.d.ts +13 -0 collapsed to keep the page light
A node_modules/lines-and-columns/build/index.js +62 -0 collapsed to keep the page light
A node_modules/lines-and-columns/package.json +49 -0 collapsed to keep the page light
A node_modules/lru-cache/LICENSE +15 -0 collapsed to keep the page light
A node_modules/lru-cache/README.md +331 -0 collapsed to keep the page light
A node_modules/lru-cache/package.json +116 -0 collapsed to keep the page light
A node_modules/merge2/LICENSE +21 -0 collapsed to keep the page light
A node_modules/merge2/README.md +144 -0 collapsed to keep the page light
A node_modules/merge2/index.js +144 -0 collapsed to keep the page light
A node_modules/merge2/package.json +43 -0 collapsed to keep the page light
A node_modules/micromatch/LICENSE +21 -0 collapsed to keep the page light
A node_modules/micromatch/README.md +1024 -0 collapsed to keep the page light
A node_modules/micromatch/index.js +474 -0 collapsed to keep the page light
A node_modules/micromatch/package.json +119 -0 collapsed to keep the page light
A node_modules/minimatch/LICENSE +15 -0 collapsed to keep the page light
A node_modules/minimatch/README.md +454 -0 collapsed to keep the page light
A node_modules/minimatch/package.json +82 -0 collapsed to keep the page light
A node_modules/minipass/LICENSE +15 -0 collapsed to keep the page light
A node_modules/minipass/README.md +825 -0 collapsed to keep the page light
A node_modules/minipass/package.json +82 -0 collapsed to keep the page light
A node_modules/mri/index.d.ts +21 -0 collapsed to keep the page light
A node_modules/mri/lib/index.js +119 -0 collapsed to keep the page light
A node_modules/mri/lib/index.mjs +119 -0 collapsed to keep the page light
A node_modules/mri/license.md +21 -0 collapsed to keep the page light
A node_modules/mri/package.json +43 -0 collapsed to keep the page light
A node_modules/mri/readme.md +166 -0 collapsed to keep the page light
A node_modules/mz/HISTORY.md +66 -0 collapsed to keep the page light
A node_modules/mz/LICENSE +22 -0 collapsed to keep the page light
A node_modules/mz/README.md +106 -0 collapsed to keep the page light
A node_modules/mz/child_process.js +8 -0 collapsed to keep the page light
A node_modules/mz/crypto.js +9 -0 collapsed to keep the page light
A node_modules/mz/dns.js +16 -0 collapsed to keep the page light
A node_modules/mz/fs.js +62 -0 collapsed to keep the page light
A node_modules/mz/index.js +8 -0 collapsed to keep the page light
A node_modules/mz/package.json +44 -0 collapsed to keep the page light
A node_modules/mz/readline.js +64 -0 collapsed to keep the page light
A node_modules/mz/zlib.js +13 -0 collapsed to keep the page light
A node_modules/nanoid/LICENSE +20 -0 collapsed to keep the page light
A node_modules/nanoid/README.md +554 -0 collapsed to keep the page light
A node_modules/nanoid/async/index.browser.cjs +69 -0 collapsed to keep the page light
A node_modules/nanoid/async/index.browser.js +69 -0 collapsed to keep the page light
A node_modules/nanoid/async/index.cjs +71 -0 collapsed to keep the page light
A node_modules/nanoid/async/index.d.ts +56 -0 collapsed to keep the page light
A node_modules/nanoid/async/index.js +71 -0 collapsed to keep the page light
A node_modules/nanoid/async/index.native.js +57 -0 collapsed to keep the page light
A node_modules/nanoid/async/package.json +12 -0 collapsed to keep the page light
A node_modules/nanoid/bin/nanoid.cjs +55 -0 collapsed to keep the page light
A node_modules/nanoid/index.browser.cjs +72 -0 collapsed to keep the page light
A node_modules/nanoid/index.browser.js +72 -0 collapsed to keep the page light
A node_modules/nanoid/index.cjs +85 -0 collapsed to keep the page light
A node_modules/nanoid/index.d.cts +91 -0 collapsed to keep the page light
A node_modules/nanoid/index.d.ts +91 -0 collapsed to keep the page light
A node_modules/nanoid/index.js +85 -0 collapsed to keep the page light
A node_modules/nanoid/nanoid.js +1 -0 collapsed to keep the page light
A node_modules/nanoid/non-secure/index.cjs +34 -0 collapsed to keep the page light
A node_modules/nanoid/non-secure/index.d.ts +33 -0 collapsed to keep the page light
A node_modules/nanoid/non-secure/index.js +34 -0 collapsed to keep the page light
A node_modules/nanoid/non-secure/package.json +6 -0 collapsed to keep the page light
A node_modules/nanoid/package.json +88 -0 collapsed to keep the page light
A node_modules/nanoid/url-alphabet/index.cjs +7 -0 collapsed to keep the page light
A node_modules/nanoid/url-alphabet/index.js +7 -0 collapsed to keep the page light
A node_modules/nanoid/url-alphabet/package.json +6 -0 collapsed to keep the page light
A node_modules/node-addon-api/LICENSE.md +9 -0 collapsed to keep the page light
A node_modules/node-addon-api/README.md +319 -0 collapsed to keep the page light
A node_modules/node-addon-api/common.gypi +20 -0 collapsed to keep the page light
A node_modules/node-addon-api/except.gypi +25 -0 collapsed to keep the page light
A node_modules/node-addon-api/index.js +12 -0 collapsed to keep the page light
A node_modules/node-addon-api/napi-inl.deprecated.h +186 -0 collapsed to keep the page light
A node_modules/node-addon-api/napi-inl.h +6607 -0
@@ -0,0 +1,6607 @@
1+#ifndef SRC_NAPI_INL_H_
2+#define SRC_NAPI_INL_H_
3+
4+////////////////////////////////////////////////////////////////////////////////
5+// Node-API C++ Wrapper Classes
6+//
7+// Inline header-only implementations for "Node-API" ABI-stable C APIs for
8+// Node.js.
9+////////////////////////////////////////////////////////////////////////////////
10+
11+// Note: Do not include this file directly! Include "napi.h" instead.
12+
13+#include <algorithm>
14+#include <cstring>
15+#if NAPI_HAS_THREADS
16+#include <mutex>
17+#endif // NAPI_HAS_THREADS
18+#include <type_traits>
19+#include <utility>
20+
21+namespace Napi {
22+
23+#ifdef NAPI_CPP_CUSTOM_NAMESPACE
24+namespace NAPI_CPP_CUSTOM_NAMESPACE {
25+#endif
26+
27+// Helpers to handle functions exposed from C++ and internal constants.
28+namespace details {
29+
30+// New napi_status constants not yet available in all supported versions of
31+// Node.js releases. Only necessary when they are used in napi.h and napi-inl.h.
32+constexpr int napi_no_external_buffers_allowed = 22;
33+
34+template <typename FreeType>
35+inline void default_finalizer(napi_env /*env*/, void* data, void* /*hint*/) {
36+ delete static_cast<FreeType*>(data);
37+}
38+
39+// Attach a data item to an object and delete it when the object gets
40+// garbage-collected.
41+// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
42+// available on all supported versions of Node.js.
43+template <typename FreeType,
44+ napi_finalize finalizer = default_finalizer<FreeType>>
45+inline napi_status AttachData(napi_env env,
46+ napi_value obj,
47+ FreeType* data,
48+ void* hint = nullptr) {
49+ napi_status status;
50+#if (NAPI_VERSION < 5)
51+ napi_value symbol, external;
52+ status = napi_create_symbol(env, nullptr, &symbol);
53+ if (status == napi_ok) {
54+ status = napi_create_external(env, data, finalizer, hint, &external);
55+ if (status == napi_ok) {
56+ napi_property_descriptor desc = {nullptr,
57+ symbol,
58+ nullptr,
59+ nullptr,
60+ nullptr,
61+ external,
62+ napi_default,
63+ nullptr};
64+ status = napi_define_properties(env, obj, 1, &desc);
65+ }
66+ }
67+#else // NAPI_VERSION >= 5
68+ status = napi_add_finalizer(env, obj, data, finalizer, hint, nullptr);
69+#endif
70+ return status;
71+}
72+
73+// For use in JS to C++ callback wrappers to catch any Napi::Error exceptions
74+// and rethrow them as JavaScript exceptions before returning from the callback.
75+template <typename Callable>
76+inline napi_value WrapCallback(Callable callback) {
77+#ifdef NAPI_CPP_EXCEPTIONS
78+ try {
79+ return callback();
80+ } catch (const Error& e) {
81+ e.ThrowAsJavaScriptException();
82+ return nullptr;
83+ }
84+#else // NAPI_CPP_EXCEPTIONS
85+ // When C++ exceptions are disabled, errors are immediately thrown as JS
86+ // exceptions, so there is no need to catch and rethrow them here.
87+ return callback();
88+#endif // NAPI_CPP_EXCEPTIONS
89+}
90+
91+// For use in JS to C++ void callback wrappers to catch any Napi::Error
92+// exceptions and rethrow them as JavaScript exceptions before returning from
93+// the callback.
94+template <typename Callable>
95+inline void WrapVoidCallback(Callable callback) {
96+#ifdef NAPI_CPP_EXCEPTIONS
97+ try {
98+ callback();
99+ } catch (const Error& e) {
100+ e.ThrowAsJavaScriptException();
101+ }
102+#else // NAPI_CPP_EXCEPTIONS
103+ // When C++ exceptions are disabled, errors are immediately thrown as JS
104+ // exceptions, so there is no need to catch and rethrow them here.
105+ callback();
106+#endif // NAPI_CPP_EXCEPTIONS
107+}
108+
109+template <typename Callable, typename Return>
110+struct CallbackData {
111+ static inline napi_value Wrapper(napi_env env, napi_callback_info info) {
112+ return details::WrapCallback([&] {
113+ CallbackInfo callbackInfo(env, info);
114+ CallbackData* callbackData =
115+ static_cast<CallbackData*>(callbackInfo.Data());
116+ callbackInfo.SetData(callbackData->data);
117+ return callbackData->callback(callbackInfo);
118+ });
119+ }
120+
121+ Callable callback;
122+ void* data;
123+};
124+
125+template <typename Callable>
126+struct CallbackData<Callable, void> {
127+ static inline napi_value Wrapper(napi_env env, napi_callback_info info) {
128+ return details::WrapCallback([&] {
129+ CallbackInfo callbackInfo(env, info);
130+ CallbackData* callbackData =
131+ static_cast<CallbackData*>(callbackInfo.Data());
132+ callbackInfo.SetData(callbackData->data);
133+ callbackData->callback(callbackInfo);
134+ return nullptr;
135+ });
136+ }
137+
138+ Callable callback;
139+ void* data;
140+};
141+
142+template <void (*Callback)(const CallbackInfo& info)>
143+napi_value TemplatedVoidCallback(napi_env env,
144+ napi_callback_info info) NAPI_NOEXCEPT {
145+ return details::WrapCallback([&] {
146+ CallbackInfo cbInfo(env, info);
147+ Callback(cbInfo);
148+ return nullptr;
149+ });
150+}
151+
152+template <Napi::Value (*Callback)(const CallbackInfo& info)>
153+napi_value TemplatedCallback(napi_env env,
154+ napi_callback_info info) NAPI_NOEXCEPT {
155+ return details::WrapCallback([&] {
156+ CallbackInfo cbInfo(env, info);
157+ return Callback(cbInfo);
158+ });
159+}
160+
161+template <typename T,
162+ Napi::Value (T::*UnwrapCallback)(const CallbackInfo& info)>
163+napi_value TemplatedInstanceCallback(napi_env env,
164+ napi_callback_info info) NAPI_NOEXCEPT {
165+ return details::WrapCallback([&] {
166+ CallbackInfo cbInfo(env, info);
167+ T* instance = T::Unwrap(cbInfo.This().As<Object>());
168+ return instance ? (instance->*UnwrapCallback)(cbInfo) : Napi::Value();
169+ });
170+}
171+
172+template <typename T, void (T::*UnwrapCallback)(const CallbackInfo& info)>
173+napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info)
174+ NAPI_NOEXCEPT {
175+ return details::WrapCallback([&] {
176+ CallbackInfo cbInfo(env, info);
177+ T* instance = T::Unwrap(cbInfo.This().As<Object>());
178+ if (instance) (instance->*UnwrapCallback)(cbInfo);
179+ return nullptr;
180+ });
181+}
182+
183+template <typename T, typename Finalizer, typename Hint = void>
184+struct FinalizeData {
185+ static inline void Wrapper(napi_env env,
186+ void* data,
187+ void* finalizeHint) NAPI_NOEXCEPT {
188+ WrapVoidCallback([&] {
189+ FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
190+ finalizeData->callback(Env(env), static_cast<T*>(data));
191+ delete finalizeData;
192+ });
193+ }
194+
195+ static inline void WrapperWithHint(napi_env env,
196+ void* data,
197+ void* finalizeHint) NAPI_NOEXCEPT {
198+ WrapVoidCallback([&] {
199+ FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
200+ finalizeData->callback(
201+ Env(env), static_cast<T*>(data), finalizeData->hint);
202+ delete finalizeData;
203+ });
204+ }
205+
206+ Finalizer callback;
207+ Hint* hint;
208+};
209+
210+#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS)
211+template <typename ContextType = void,
212+ typename Finalizer = std::function<void(Env, void*, ContextType*)>,
213+ typename FinalizerDataType = void>
214+struct ThreadSafeFinalize {
215+ static inline void Wrapper(napi_env env,
216+ void* rawFinalizeData,
217+ void* /* rawContext */) {
218+ if (rawFinalizeData == nullptr) return;
219+
220+ ThreadSafeFinalize* finalizeData =
221+ static_cast<ThreadSafeFinalize*>(rawFinalizeData);
222+ finalizeData->callback(Env(env));
223+ delete finalizeData;
224+ }
225+
226+ static inline void FinalizeWrapperWithData(napi_env env,
227+ void* rawFinalizeData,
228+ void* /* rawContext */) {
229+ if (rawFinalizeData == nullptr) return;
230+
231+ ThreadSafeFinalize* finalizeData =
232+ static_cast<ThreadSafeFinalize*>(rawFinalizeData);
233+ finalizeData->callback(Env(env), finalizeData->data);
234+ delete finalizeData;
235+ }
236+
237+ static inline void FinalizeWrapperWithContext(napi_env env,
238+ void* rawFinalizeData,
239+ void* rawContext) {
240+ if (rawFinalizeData == nullptr) return;
241+
242+ ThreadSafeFinalize* finalizeData =
243+ static_cast<ThreadSafeFinalize*>(rawFinalizeData);
244+ finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));
245+ delete finalizeData;
246+ }
247+
248+ static inline void FinalizeFinalizeWrapperWithDataAndContext(
249+ napi_env env, void* rawFinalizeData, void* rawContext) {
250+ if (rawFinalizeData == nullptr) return;
251+
252+ ThreadSafeFinalize* finalizeData =
253+ static_cast<ThreadSafeFinalize*>(rawFinalizeData);
254+ finalizeData->callback(
255+ Env(env), finalizeData->data, static_cast<ContextType*>(rawContext));
256+ delete finalizeData;
257+ }
258+
259+ FinalizerDataType* data;
260+ Finalizer callback;
261+};
262+
263+template <typename ContextType, typename DataType, typename CallJs, CallJs call>
264+inline typename std::enable_if<call != static_cast<CallJs>(nullptr)>::type
265+CallJsWrapper(napi_env env, napi_value jsCallback, void* context, void* data) {
266+ details::WrapVoidCallback([&]() {
267+ call(env,
268+ Function(env, jsCallback),
269+ static_cast<ContextType*>(context),
270+ static_cast<DataType*>(data));
271+ });
272+}
273+
274+template <typename ContextType, typename DataType, typename CallJs, CallJs call>
275+inline typename std::enable_if<call == static_cast<CallJs>(nullptr)>::type
276+CallJsWrapper(napi_env env,
277+ napi_value jsCallback,
278+ void* /*context*/,
279+ void* /*data*/) {
280+ details::WrapVoidCallback([&]() {
281+ if (jsCallback != nullptr) {
282+ Function(env, jsCallback).Call(0, nullptr);
283+ }
284+ });
285+}
286+
287+#if NAPI_VERSION > 4
288+
289+template <typename CallbackType, typename TSFN>
290+napi_value DefaultCallbackWrapper(napi_env /*env*/, std::nullptr_t /*cb*/) {
291+ return nullptr;
292+}
293+
294+template <typename CallbackType, typename TSFN>
295+napi_value DefaultCallbackWrapper(napi_env /*env*/, Napi::Function cb) {
296+ return cb;
297+}
298+
299+#else
300+template <typename CallbackType, typename TSFN>
301+napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) {
302+ if (cb.IsEmpty()) {
303+ return TSFN::EmptyFunctionFactory(env);
304+ }
305+ return cb;
306+}
307+#endif // NAPI_VERSION > 4
308+#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS
309+
310+template <typename Getter, typename Setter>
311+struct AccessorCallbackData {
312+ static inline napi_value GetterWrapper(napi_env env,
313+ napi_callback_info info) {
314+ return details::WrapCallback([&] {
315+ CallbackInfo callbackInfo(env, info);
316+ AccessorCallbackData* callbackData =
317+ static_cast<AccessorCallbackData*>(callbackInfo.Data());
318+ callbackInfo.SetData(callbackData->data);
319+ return callbackData->getterCallback(callbackInfo);
320+ });
321+ }
322+
323+ static inline napi_value SetterWrapper(napi_env env,
324+ napi_callback_info info) {
325+ return details::WrapCallback([&] {
326+ CallbackInfo callbackInfo(env, info);
327+ AccessorCallbackData* callbackData =
328+ static_cast<AccessorCallbackData*>(callbackInfo.Data());
329+ callbackInfo.SetData(callbackData->data);
330+ callbackData->setterCallback(callbackInfo);
331+ return nullptr;
332+ });
333+ }
334+
335+ Getter getterCallback;
336+ Setter setterCallback;
337+ void* data;
338+};
339+
340+} // namespace details
341+
342+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
343+#include "napi-inl.deprecated.h"
344+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
345+
346+////////////////////////////////////////////////////////////////////////////////
347+// Module registration
348+////////////////////////////////////////////////////////////////////////////////
349+
350+// Register an add-on based on an initializer function.
351+#define NODE_API_MODULE(modname, regfunc) \
352+ static napi_value __napi_##regfunc(napi_env env, napi_value exports) { \
353+ return Napi::RegisterModule(env, exports, regfunc); \
354+ } \
355+ NAPI_MODULE(modname, __napi_##regfunc)
356+
357+// Register an add-on based on a subclass of `Addon<T>` with a custom Node.js
358+// module name.
359+#define NODE_API_NAMED_ADDON(modname, classname) \
360+ static napi_value __napi_##classname(napi_env env, napi_value exports) { \
361+ return Napi::RegisterModule(env, exports, &classname::Init); \
362+ } \
363+ NAPI_MODULE(modname, __napi_##classname)
364+
365+// Register an add-on based on a subclass of `Addon<T>` with the Node.js module
366+// name given by node-gyp from the `target_name` in binding.gyp.
367+#define NODE_API_ADDON(classname) \
368+ NODE_API_NAMED_ADDON(NODE_GYP_MODULE_NAME, classname)
369+
370+// Adapt the NAPI_MODULE registration function:
371+// - Wrap the arguments in NAPI wrappers.
372+// - Catch any NAPI errors and rethrow as JS exceptions.
373+inline napi_value RegisterModule(napi_env env,
374+ napi_value exports,
375+ ModuleRegisterCallback registerCallback) {
376+ return details::WrapCallback([&] {
377+ return napi_value(
378+ registerCallback(Napi::Env(env), Napi::Object(env, exports)));
379+ });
380+}
381+
382+////////////////////////////////////////////////////////////////////////////////
383+// Maybe class
384+////////////////////////////////////////////////////////////////////////////////
385+
386+template <class T>
387+bool Maybe<T>::IsNothing() const {
388+ return !_has_value;
389+}
390+
391+template <class T>
392+bool Maybe<T>::IsJust() const {
393+ return _has_value;
394+}
395+
396+template <class T>
397+void Maybe<T>::Check() const {
398+ NAPI_CHECK(IsJust(), "Napi::Maybe::Check", "Maybe value is Nothing.");
399+}
400+
401+template <class T>
402+T Maybe<T>::Unwrap() const {
403+ NAPI_CHECK(IsJust(), "Napi::Maybe::Unwrap", "Maybe value is Nothing.");
404+ return _value;
405+}
406+
407+template <class T>
408+T Maybe<T>::UnwrapOr(const T& default_value) const {
409+ return _has_value ? _value : default_value;
410+}
411+
412+template <class T>
413+bool Maybe<T>::UnwrapTo(T* out) const {
414+ if (IsJust()) {
415+ *out = _value;
416+ return true;
417+ };
418+ return false;
419+}
420+
421+template <class T>
422+bool Maybe<T>::operator==(const Maybe& other) const {
423+ return (IsJust() == other.IsJust()) &&
424+ (!IsJust() || Unwrap() == other.Unwrap());
425+}
426+
427+template <class T>
428+bool Maybe<T>::operator!=(const Maybe& other) const {
429+ return !operator==(other);
430+}
431+
432+template <class T>
433+Maybe<T>::Maybe() : _has_value(false) {}
434+
435+template <class T>
436+Maybe<T>::Maybe(const T& t) : _has_value(true), _value(t) {}
437+
438+template <class T>
439+inline Maybe<T> Nothing() {
440+ return Maybe<T>();
441+}
442+
443+template <class T>
444+inline Maybe<T> Just(const T& t) {
445+ return Maybe<T>(t);
446+}
447+
448+////////////////////////////////////////////////////////////////////////////////
449+// Env class
450+////////////////////////////////////////////////////////////////////////////////
451+
452+inline Env::Env(napi_env env) : _env(env) {}
453+
454+inline Env::operator napi_env() const {
455+ return _env;
456+}
457+
458+inline Object Env::Global() const {
459+ napi_value value;
460+ napi_status status = napi_get_global(*this, &value);
461+ NAPI_THROW_IF_FAILED(*this, status, Object());
462+ return Object(*this, value);
463+}
464+
465+inline Value Env::Undefined() const {
466+ napi_value value;
467+ napi_status status = napi_get_undefined(*this, &value);
468+ NAPI_THROW_IF_FAILED(*this, status, Value());
469+ return Value(*this, value);
470+}
471+
472+inline Value Env::Null() const {
473+ napi_value value;
474+ napi_status status = napi_get_null(*this, &value);
475+ NAPI_THROW_IF_FAILED(*this, status, Value());
476+ return Value(*this, value);
477+}
478+
479+inline bool Env::IsExceptionPending() const {
480+ bool result;
481+ napi_status status = napi_is_exception_pending(_env, &result);
482+ if (status != napi_ok)
483+ result = false; // Checking for a pending exception shouldn't throw.
484+ return result;
485+}
486+
487+inline Error Env::GetAndClearPendingException() const {
488+ napi_value value;
489+ napi_status status = napi_get_and_clear_last_exception(_env, &value);
490+ if (status != napi_ok) {
491+ // Don't throw another exception when failing to get the exception!
492+ return Error();
493+ }
494+ return Error(_env, value);
495+}
496+
497+inline MaybeOrValue<Value> Env::RunScript(const char* utf8script) const {
498+ String script = String::New(_env, utf8script);
499+ return RunScript(script);
500+}
501+
502+inline MaybeOrValue<Value> Env::RunScript(const std::string& utf8script) const {
503+ return RunScript(utf8script.c_str());
504+}
505+
506+inline MaybeOrValue<Value> Env::RunScript(String script) const {
507+ napi_value result;
508+ napi_status status = napi_run_script(_env, script, &result);
509+ NAPI_RETURN_OR_THROW_IF_FAILED(
510+ _env, status, Napi::Value(_env, result), Napi::Value);
511+}
512+
513+#if NAPI_VERSION > 2
514+template <typename Hook, typename Arg>
515+void Env::CleanupHook<Hook, Arg>::Wrapper(void* data) NAPI_NOEXCEPT {
516+ auto* cleanupData =
517+ static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(
518+ data);
519+ cleanupData->hook();
520+ delete cleanupData;
521+}
522+
523+template <typename Hook, typename Arg>
524+void Env::CleanupHook<Hook, Arg>::WrapperWithArg(void* data) NAPI_NOEXCEPT {
525+ auto* cleanupData =
526+ static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(
527+ data);
528+ cleanupData->hook(static_cast<Arg*>(cleanupData->arg));
529+ delete cleanupData;
530+}
531+#endif // NAPI_VERSION > 2
532+
533+#if NAPI_VERSION > 5
534+template <typename T, Env::Finalizer<T> fini>
535+inline void Env::SetInstanceData(T* data) const {
536+ napi_status status = napi_set_instance_data(
537+ _env,
538+ data,
539+ [](napi_env env, void* data, void*) { fini(env, static_cast<T*>(data)); },
540+ nullptr);
541+ NAPI_THROW_IF_FAILED_VOID(_env, status);
542+}
543+
544+template <typename DataType,
545+ typename HintType,
546+ Napi::Env::FinalizerWithHint<DataType, HintType> fini>
547+inline void Env::SetInstanceData(DataType* data, HintType* hint) const {
548+ napi_status status = napi_set_instance_data(
549+ _env,
550+ data,
551+ [](napi_env env, void* data, void* hint) {
552+ fini(env, static_cast<DataType*>(data), static_cast<HintType*>(hint));
553+ },
554+ hint);
555+ NAPI_THROW_IF_FAILED_VOID(_env, status);
556+}
557+
558+template <typename T>
559+inline T* Env::GetInstanceData() const {
560+ void* data = nullptr;
561+
562+ napi_status status = napi_get_instance_data(_env, &data);
563+ NAPI_THROW_IF_FAILED(_env, status, nullptr);
564+
565+ return static_cast<T*>(data);
566+}
567+
568+template <typename T>
569+void Env::DefaultFini(Env, T* data) {
570+ delete data;
571+}
572+
573+template <typename DataType, typename HintType>
574+void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) {
575+ delete data;
576+}
577+#endif // NAPI_VERSION > 5
578+
579+#if NAPI_VERSION > 8
580+inline const char* Env::GetModuleFileName() const {
581+ const char* result;
582+ napi_status status = node_api_get_module_file_name(_env, &result);
583+ NAPI_THROW_IF_FAILED(*this, status, nullptr);
584+ return result;
585+}
586+#endif // NAPI_VERSION > 8
587+////////////////////////////////////////////////////////////////////////////////
588+// Value class
589+////////////////////////////////////////////////////////////////////////////////
590+
591+inline Value::Value() : _env(nullptr), _value(nullptr) {}
592+
593+inline Value::Value(napi_env env, napi_value value)
594+ : _env(env), _value(value) {}
595+
596+inline Value::operator napi_value() const {
597+ return _value;
598+}
599+
600+inline bool Value::operator==(const Value& other) const {
601+ return StrictEquals(other);
602+}
603+
604+inline bool Value::operator!=(const Value& other) const {
605+ return !this->operator==(other);
606+}
607+
608+inline bool Value::StrictEquals(const Value& other) const {
609+ bool result;
610+ napi_status status = napi_strict_equals(_env, *this, other, &result);
611+ NAPI_THROW_IF_FAILED(_env, status, false);
612+ return result;
613+}
614+
615+inline Napi::Env Value::Env() const {
616+ return Napi::Env(_env);
617+}
618+
619+inline bool Value::IsEmpty() const {
620+ return _value == nullptr;
621+}
622+
623+inline napi_valuetype Value::Type() const {
624+ if (IsEmpty()) {
625+ return napi_undefined;
626+ }
627+
628+ napi_valuetype type;
629+ napi_status status = napi_typeof(_env, _value, &type);
630+ NAPI_THROW_IF_FAILED(_env, status, napi_undefined);
631+ return type;
632+}
633+
634+inline bool Value::IsUndefined() const {
635+ return Type() == napi_undefined;
636+}
637+
638+inline bool Value::IsNull() const {
639+ return Type() == napi_null;
640+}
641+
642+inline bool Value::IsBoolean() const {
643+ return Type() == napi_boolean;
644+}
645+
646+inline bool Value::IsNumber() const {
647+ return Type() == napi_number;
648+}
649+
650+#if NAPI_VERSION > 5
651+inline bool Value::IsBigInt() const {
652+ return Type() == napi_bigint;
653+}
654+#endif // NAPI_VERSION > 5
655+
656+#if (NAPI_VERSION > 4)
657+inline bool Value::IsDate() const {
658+ if (IsEmpty()) {
659+ return false;
660+ }
661+
662+ bool result;
663+ napi_status status = napi_is_date(_env, _value, &result);
664+ NAPI_THROW_IF_FAILED(_env, status, false);
665+ return result;
666+}
667+#endif
668+
669+inline bool Value::IsString() const {
670+ return Type() == napi_string;
671+}
672+
673+inline bool Value::IsSymbol() const {
674+ return Type() == napi_symbol;
675+}
676+
677+inline bool Value::IsArray() const {
678+ if (IsEmpty()) {
679+ return false;
680+ }
681+
682+ bool result;
683+ napi_status status = napi_is_array(_env, _value, &result);
684+ NAPI_THROW_IF_FAILED(_env, status, false);
685+ return result;
686+}
687+
688+inline bool Value::IsArrayBuffer() const {
689+ if (IsEmpty()) {
690+ return false;
691+ }
692+
693+ bool result;
694+ napi_status status = napi_is_arraybuffer(_env, _value, &result);
695+ NAPI_THROW_IF_FAILED(_env, status, false);
696+ return result;
697+}
698+
699+inline bool Value::IsTypedArray() const {
700+ if (IsEmpty()) {
701+ return false;
702+ }
703+
704+ bool result;
705+ napi_status status = napi_is_typedarray(_env, _value, &result);
706+ NAPI_THROW_IF_FAILED(_env, status, false);
707+ return result;
708+}
709+
710+inline bool Value::IsObject() const {
711+ return Type() == napi_object || IsFunction();
712+}
713+
714+inline bool Value::IsFunction() const {
715+ return Type() == napi_function;
716+}
717+
718+inline bool Value::IsPromise() const {
719+ if (IsEmpty()) {
720+ return false;
721+ }
722+
723+ bool result;
724+ napi_status status = napi_is_promise(_env, _value, &result);
725+ NAPI_THROW_IF_FAILED(_env, status, false);
726+ return result;
727+}
728+
729+inline bool Value::IsDataView() const {
730+ if (IsEmpty()) {
731+ return false;
732+ }
733+
734+ bool result;
735+ napi_status status = napi_is_dataview(_env, _value, &result);
736+ NAPI_THROW_IF_FAILED(_env, status, false);
737+ return result;
738+}
739+
740+inline bool Value::IsBuffer() const {
741+ if (IsEmpty()) {
742+ return false;
743+ }
744+
745+ bool result;
746+ napi_status status = napi_is_buffer(_env, _value, &result);
747+ NAPI_THROW_IF_FAILED(_env, status, false);
748+ return result;
749+}
750+
751+inline bool Value::IsExternal() const {
752+ return Type() == napi_external;
753+}
754+
755+template <typename T>
756+inline T Value::As() const {
757+#ifdef NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS
758+ T::CheckCast(_env, _value);
759+#endif
760+ return T(_env, _value);
761+}
762+
763+inline MaybeOrValue<Boolean> Value::ToBoolean() const {
764+ napi_value result;
765+ napi_status status = napi_coerce_to_bool(_env, _value, &result);
766+ NAPI_RETURN_OR_THROW_IF_FAILED(
767+ _env, status, Napi::Boolean(_env, result), Napi::Boolean);
768+}
769+
770+inline MaybeOrValue<Number> Value::ToNumber() const {
771+ napi_value result;
772+ napi_status status = napi_coerce_to_number(_env, _value, &result);
773+ NAPI_RETURN_OR_THROW_IF_FAILED(
774+ _env, status, Napi::Number(_env, result), Napi::Number);
775+}
776+
777+inline MaybeOrValue<String> Value::ToString() const {
778+ napi_value result;
779+ napi_status status = napi_coerce_to_string(_env, _value, &result);
780+ NAPI_RETURN_OR_THROW_IF_FAILED(
781+ _env, status, Napi::String(_env, result), Napi::String);
782+}
783+
784+inline MaybeOrValue<Object> Value::ToObject() const {
785+ napi_value result;
786+ napi_status status = napi_coerce_to_object(_env, _value, &result);
787+ NAPI_RETURN_OR_THROW_IF_FAILED(
788+ _env, status, Napi::Object(_env, result), Napi::Object);
789+}
790+
791+////////////////////////////////////////////////////////////////////////////////
792+// Boolean class
793+////////////////////////////////////////////////////////////////////////////////
794+
795+inline Boolean Boolean::New(napi_env env, bool val) {
796+ napi_value value;
797+ napi_status status = napi_get_boolean(env, val, &value);
798+ NAPI_THROW_IF_FAILED(env, status, Boolean());
799+ return Boolean(env, value);
800+}
801+
802+inline void Boolean::CheckCast(napi_env env, napi_value value) {
803+ NAPI_CHECK(value != nullptr, "Boolean::CheckCast", "empty value");
804+
805+ napi_valuetype type;
806+ napi_status status = napi_typeof(env, value, &type);
807+ NAPI_CHECK(status == napi_ok, "Boolean::CheckCast", "napi_typeof failed");
808+ NAPI_CHECK(
809+ type == napi_boolean, "Boolean::CheckCast", "value is not napi_boolean");
810+}
811+
812+inline Boolean::Boolean() : Napi::Value() {}
813+
814+inline Boolean::Boolean(napi_env env, napi_value value)
815+ : Napi::Value(env, value) {}
816+
817+inline Boolean::operator bool() const {
818+ return Value();
819+}
820+
821+inline bool Boolean::Value() const {
822+ bool result;
823+ napi_status status = napi_get_value_bool(_env, _value, &result);
824+ NAPI_THROW_IF_FAILED(_env, status, false);
825+ return result;
826+}
827+
828+////////////////////////////////////////////////////////////////////////////////
829+// Number class
830+////////////////////////////////////////////////////////////////////////////////
831+
832+inline Number Number::New(napi_env env, double val) {
833+ napi_value value;
834+ napi_status status = napi_create_double(env, val, &value);
835+ NAPI_THROW_IF_FAILED(env, status, Number());
836+ return Number(env, value);
837+}
838+
839+inline void Number::CheckCast(napi_env env, napi_value value) {
840+ NAPI_CHECK(value != nullptr, "Number::CheckCast", "empty value");
841+
842+ napi_valuetype type;
843+ napi_status status = napi_typeof(env, value, &type);
844+ NAPI_CHECK(status == napi_ok, "Number::CheckCast", "napi_typeof failed");
845+ NAPI_CHECK(
846+ type == napi_number, "Number::CheckCast", "value is not napi_number");
847+}
848+
849+inline Number::Number() : Value() {}
850+
851+inline Number::Number(napi_env env, napi_value value) : Value(env, value) {}
852+
853+inline Number::operator int32_t() const {
854+ return Int32Value();
855+}
856+
857+inline Number::operator uint32_t() const {
858+ return Uint32Value();
859+}
860+
861+inline Number::operator int64_t() const {
862+ return Int64Value();
863+}
864+
865+inline Number::operator float() const {
866+ return FloatValue();
867+}
868+
869+inline Number::operator double() const {
870+ return DoubleValue();
871+}
872+
873+inline int32_t Number::Int32Value() const {
874+ int32_t result;
875+ napi_status status = napi_get_value_int32(_env, _value, &result);
876+ NAPI_THROW_IF_FAILED(_env, status, 0);
877+ return result;
878+}
879+
880+inline uint32_t Number::Uint32Value() const {
881+ uint32_t result;
882+ napi_status status = napi_get_value_uint32(_env, _value, &result);
883+ NAPI_THROW_IF_FAILED(_env, status, 0);
884+ return result;
885+}
886+
887+inline int64_t Number::Int64Value() const {
888+ int64_t result;
889+ napi_status status = napi_get_value_int64(_env, _value, &result);
890+ NAPI_THROW_IF_FAILED(_env, status, 0);
891+ return result;
892+}
893+
894+inline float Number::FloatValue() const {
895+ return static_cast<float>(DoubleValue());
896+}
897+
898+inline double Number::DoubleValue() const {
899+ double result;
900+ napi_status status = napi_get_value_double(_env, _value, &result);
901+ NAPI_THROW_IF_FAILED(_env, status, 0);
902+ return result;
903+}
904+
905+#if NAPI_VERSION > 5
906+////////////////////////////////////////////////////////////////////////////////
907+// BigInt Class
908+////////////////////////////////////////////////////////////////////////////////
909+
910+inline BigInt BigInt::New(napi_env env, int64_t val) {
911+ napi_value value;
912+ napi_status status = napi_create_bigint_int64(env, val, &value);
913+ NAPI_THROW_IF_FAILED(env, status, BigInt());
914+ return BigInt(env, value);
915+}
916+
917+inline BigInt BigInt::New(napi_env env, uint64_t val) {
918+ napi_value value;
919+ napi_status status = napi_create_bigint_uint64(env, val, &value);
920+ NAPI_THROW_IF_FAILED(env, status, BigInt());
921+ return BigInt(env, value);
922+}
923+
924+inline BigInt BigInt::New(napi_env env,
925+ int sign_bit,
926+ size_t word_count,
927+ const uint64_t* words) {
928+ napi_value value;
929+ napi_status status =
930+ napi_create_bigint_words(env, sign_bit, word_count, words, &value);
931+ NAPI_THROW_IF_FAILED(env, status, BigInt());
932+ return BigInt(env, value);
933+}
934+
935+inline void BigInt::CheckCast(napi_env env, napi_value value) {
936+ NAPI_CHECK(value != nullptr, "BigInt::CheckCast", "empty value");
937+
938+ napi_valuetype type;
939+ napi_status status = napi_typeof(env, value, &type);
940+ NAPI_CHECK(status == napi_ok, "BigInt::CheckCast", "napi_typeof failed");
941+ NAPI_CHECK(
942+ type == napi_bigint, "BigInt::CheckCast", "value is not napi_bigint");
943+}
944+
945+inline BigInt::BigInt() : Value() {}
946+
947+inline BigInt::BigInt(napi_env env, napi_value value) : Value(env, value) {}
948+
949+inline int64_t BigInt::Int64Value(bool* lossless) const {
950+ int64_t result;
951+ napi_status status =
952+ napi_get_value_bigint_int64(_env, _value, &result, lossless);
953+ NAPI_THROW_IF_FAILED(_env, status, 0);
954+ return result;
955+}
956+
957+inline uint64_t BigInt::Uint64Value(bool* lossless) const {
958+ uint64_t result;
959+ napi_status status =
960+ napi_get_value_bigint_uint64(_env, _value, &result, lossless);
961+ NAPI_THROW_IF_FAILED(_env, status, 0);
962+ return result;
963+}
964+
965+inline size_t BigInt::WordCount() const {
966+ size_t word_count;
967+ napi_status status =
968+ napi_get_value_bigint_words(_env, _value, nullptr, &word_count, nullptr);
969+ NAPI_THROW_IF_FAILED(_env, status, 0);
970+ return word_count;
971+}
972+
973+inline void BigInt::ToWords(int* sign_bit,
974+ size_t* word_count,
975+ uint64_t* words) {
976+ napi_status status =
977+ napi_get_value_bigint_words(_env, _value, sign_bit, word_count, words);
978+ NAPI_THROW_IF_FAILED_VOID(_env, status);
979+}
980+#endif // NAPI_VERSION > 5
981+
982+#if (NAPI_VERSION > 4)
983+////////////////////////////////////////////////////////////////////////////////
984+// Date Class
985+////////////////////////////////////////////////////////////////////////////////
986+
987+inline Date Date::New(napi_env env, double val) {
988+ napi_value value;
989+ napi_status status = napi_create_date(env, val, &value);
990+ NAPI_THROW_IF_FAILED(env, status, Date());
991+ return Date(env, value);
992+}
993+
994+inline void Date::CheckCast(napi_env env, napi_value value) {
995+ NAPI_CHECK(value != nullptr, "Date::CheckCast", "empty value");
996+
997+ bool result;
998+ napi_status status = napi_is_date(env, value, &result);
999+ NAPI_CHECK(status == napi_ok, "Date::CheckCast", "napi_is_date failed");
1000+ NAPI_CHECK(result, "Date::CheckCast", "value is not date");
1001+}
1002+
1003+inline Date::Date() : Value() {}
1004+
1005+inline Date::Date(napi_env env, napi_value value) : Value(env, value) {}
1006+
1007+inline Date::operator double() const {
1008+ return ValueOf();
1009+}
1010+
1011+inline double Date::ValueOf() const {
1012+ double result;
1013+ napi_status status = napi_get_date_value(_env, _value, &result);
1014+ NAPI_THROW_IF_FAILED(_env, status, 0);
1015+ return result;
1016+}
1017+#endif
1018+
1019+////////////////////////////////////////////////////////////////////////////////
1020+// Name class
1021+////////////////////////////////////////////////////////////////////////////////
1022+inline void Name::CheckCast(napi_env env, napi_value value) {
1023+ NAPI_CHECK(value != nullptr, "Name::CheckCast", "empty value");
1024+
1025+ napi_valuetype type;
1026+ napi_status status = napi_typeof(env, value, &type);
1027+ NAPI_CHECK(status == napi_ok, "Name::CheckCast", "napi_typeof failed");
1028+ NAPI_CHECK(type == napi_string || type == napi_symbol,
1029+ "Name::CheckCast",
1030+ "value is not napi_string or napi_symbol");
1031+}
1032+
1033+inline Name::Name() : Value() {}
1034+
1035+inline Name::Name(napi_env env, napi_value value) : Value(env, value) {}
1036+
1037+////////////////////////////////////////////////////////////////////////////////
1038+// String class
1039+////////////////////////////////////////////////////////////////////////////////
1040+
1041+inline String String::New(napi_env env, const std::string& val) {
1042+ return String::New(env, val.c_str(), val.size());
1043+}
1044+
1045+inline String String::New(napi_env env, const std::u16string& val) {
1046+ return String::New(env, val.c_str(), val.size());
1047+}
1048+
1049+inline String String::New(napi_env env, const char* val) {
1050+ // TODO(@gabrielschulhof) Remove if-statement when core's error handling is
1051+ // available in all supported versions.
1052+ if (val == nullptr) {
1053+ // Throw an error that looks like it came from core.
1054+ NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());
1055+ }
1056+ napi_value value;
1057+ napi_status status =
1058+ napi_create_string_utf8(env, val, std::strlen(val), &value);
1059+ NAPI_THROW_IF_FAILED(env, status, String());
1060+ return String(env, value);
1061+}
1062+
1063+inline String String::New(napi_env env, const char16_t* val) {
1064+ napi_value value;
1065+ // TODO(@gabrielschulhof) Remove if-statement when core's error handling is
1066+ // available in all supported versions.
1067+ if (val == nullptr) {
1068+ // Throw an error that looks like it came from core.
1069+ NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());
1070+ }
1071+ napi_status status =
1072+ napi_create_string_utf16(env, val, std::u16string(val).size(), &value);
1073+ NAPI_THROW_IF_FAILED(env, status, String());
1074+ return String(env, value);
1075+}
1076+
1077+inline String String::New(napi_env env, const char* val, size_t length) {
1078+ napi_value value;
1079+ napi_status status = napi_create_string_utf8(env, val, length, &value);
1080+ NAPI_THROW_IF_FAILED(env, status, String());
1081+ return String(env, value);
1082+}
1083+
1084+inline String String::New(napi_env env, const char16_t* val, size_t length) {
1085+ napi_value value;
1086+ napi_status status = napi_create_string_utf16(env, val, length, &value);
1087+ NAPI_THROW_IF_FAILED(env, status, String());
1088+ return String(env, value);
1089+}
1090+
1091+inline void String::CheckCast(napi_env env, napi_value value) {
1092+ NAPI_CHECK(value != nullptr, "String::CheckCast", "empty value");
1093+
1094+ napi_valuetype type;
1095+ napi_status status = napi_typeof(env, value, &type);
1096+ NAPI_CHECK(status == napi_ok, "String::CheckCast", "napi_typeof failed");
1097+ NAPI_CHECK(
1098+ type == napi_string, "String::CheckCast", "value is not napi_string");
1099+}
1100+
1101+inline String::String() : Name() {}
1102+
1103+inline String::String(napi_env env, napi_value value) : Name(env, value) {}
1104+
1105+inline String::operator std::string() const {
1106+ return Utf8Value();
1107+}
1108+
1109+inline String::operator std::u16string() const {
1110+ return Utf16Value();
1111+}
1112+
1113+inline std::string String::Utf8Value() const {
1114+ size_t length;
1115+ napi_status status =
1116+ napi_get_value_string_utf8(_env, _value, nullptr, 0, &length);
1117+ NAPI_THROW_IF_FAILED(_env, status, "");
1118+
1119+ std::string value;
1120+ value.reserve(length + 1);
1121+ value.resize(length);
1122+ status = napi_get_value_string_utf8(
1123+ _env, _value, &value[0], value.capacity(), nullptr);
1124+ NAPI_THROW_IF_FAILED(_env, status, "");
1125+ return value;
1126+}
1127+
1128+inline std::u16string String::Utf16Value() const {
1129+ size_t length;
1130+ napi_status status =
1131+ napi_get_value_string_utf16(_env, _value, nullptr, 0, &length);
1132+ NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT(""));
1133+
1134+ std::u16string value;
1135+ value.reserve(length + 1);
1136+ value.resize(length);
1137+ status = napi_get_value_string_utf16(
1138+ _env, _value, &value[0], value.capacity(), nullptr);
1139+ NAPI_THROW_IF_FAILED(_env, status, NAPI_WIDE_TEXT(""));
1140+ return value;
1141+}
1142+
1143+////////////////////////////////////////////////////////////////////////////////
1144+// Symbol class
1145+////////////////////////////////////////////////////////////////////////////////
1146+
1147+inline Symbol Symbol::New(napi_env env, const char* description) {
1148+ napi_value descriptionValue = description != nullptr
1149+ ? String::New(env, description)
1150+ : static_cast<napi_value>(nullptr);
1151+ return Symbol::New(env, descriptionValue);
1152+}
1153+
1154+inline Symbol Symbol::New(napi_env env, const std::string& description) {
1155+ napi_value descriptionValue = String::New(env, description);
1156+ return Symbol::New(env, descriptionValue);
1157+}
1158+
1159+inline Symbol Symbol::New(napi_env env, String description) {
1160+ napi_value descriptionValue = description;
1161+ return Symbol::New(env, descriptionValue);
1162+}
1163+
1164+inline Symbol Symbol::New(napi_env env, napi_value description) {
1165+ napi_value value;
1166+ napi_status status = napi_create_symbol(env, description, &value);
1167+ NAPI_THROW_IF_FAILED(env, status, Symbol());
1168+ return Symbol(env, value);
1169+}
1170+
1171+inline MaybeOrValue<Symbol> Symbol::WellKnown(napi_env env,
1172+ const std::string& name) {
1173+#if defined(NODE_ADDON_API_ENABLE_MAYBE)
1174+ Value symbol_obj;
1175+ Value symbol_value;
1176+ if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
1177+ symbol_obj.As<Object>().Get(name).UnwrapTo(&symbol_value)) {
1178+ return Just<Symbol>(symbol_value.As<Symbol>());
1179+ }
1180+ return Nothing<Symbol>();
1181+#else
1182+ return Napi::Env(env)
1183+ .Global()
1184+ .Get("Symbol")
1185+ .As<Object>()
1186+ .Get(name)
1187+ .As<Symbol>();
1188+#endif
1189+}
1190+
1191+inline MaybeOrValue<Symbol> Symbol::For(napi_env env,
1192+ const std::string& description) {
1193+ napi_value descriptionValue = String::New(env, description);
1194+ return Symbol::For(env, descriptionValue);
1195+}
1196+
1197+inline MaybeOrValue<Symbol> Symbol::For(napi_env env, const char* description) {
1198+ napi_value descriptionValue = String::New(env, description);
1199+ return Symbol::For(env, descriptionValue);
1200+}
1201+
1202+inline MaybeOrValue<Symbol> Symbol::For(napi_env env, String description) {
1203+ return Symbol::For(env, static_cast<napi_value>(description));
1204+}
1205+
1206+inline MaybeOrValue<Symbol> Symbol::For(napi_env env, napi_value description) {
1207+#if defined(NODE_ADDON_API_ENABLE_MAYBE)
1208+ Value symbol_obj;
1209+ Value symbol_for_value;
1210+ Value symbol_value;
1211+ if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
1212+ symbol_obj.As<Object>().Get("for").UnwrapTo(&symbol_for_value) &&
1213+ symbol_for_value.As<Function>()
1214+ .Call(symbol_obj, {description})
1215+ .UnwrapTo(&symbol_value)) {
1216+ return Just<Symbol>(symbol_value.As<Symbol>());
1217+ }
1218+ return Nothing<Symbol>();
1219+#else
1220+ Object symbol_obj = Napi::Env(env).Global().Get("Symbol").As<Object>();
1221+ return symbol_obj.Get("for")
1222+ .As<Function>()
1223+ .Call(symbol_obj, {description})
1224+ .As<Symbol>();
1225+#endif
1226+}
1227+
1228+inline void Symbol::CheckCast(napi_env env, napi_value value) {
1229+ NAPI_CHECK(value != nullptr, "Symbol::CheckCast", "empty value");
1230+
1231+ napi_valuetype type;
1232+ napi_status status = napi_typeof(env, value, &type);
1233+ NAPI_CHECK(status == napi_ok, "Symbol::CheckCast", "napi_typeof failed");
1234+ NAPI_CHECK(
1235+ type == napi_symbol, "Symbol::CheckCast", "value is not napi_symbol");
1236+}
1237+
1238+inline Symbol::Symbol() : Name() {}
1239+
1240+inline Symbol::Symbol(napi_env env, napi_value value) : Name(env, value) {}
1241+
1242+////////////////////////////////////////////////////////////////////////////////
1243+// Automagic value creation
1244+////////////////////////////////////////////////////////////////////////////////
1245+
1246+namespace details {
1247+template <typename T>
1248+struct vf_number {
1249+ static Number From(napi_env env, T value) {
1250+ return Number::New(env, static_cast<double>(value));
1251+ }
1252+};
1253+
1254+template <>
1255+struct vf_number<bool> {
1256+ static Boolean From(napi_env env, bool value) {
1257+ return Boolean::New(env, value);
1258+ }
1259+};
1260+
1261+struct vf_utf8_charp {
1262+ static String From(napi_env env, const char* value) {
1263+ return String::New(env, value);
1264+ }
1265+};
1266+
1267+struct vf_utf16_charp {
1268+ static String From(napi_env env, const char16_t* value) {
1269+ return String::New(env, value);
1270+ }
1271+};
1272+struct vf_utf8_string {
1273+ static String From(napi_env env, const std::string& value) {
1274+ return String::New(env, value);
1275+ }
1276+};
1277+
1278+struct vf_utf16_string {
1279+ static String From(napi_env env, const std::u16string& value) {
1280+ return String::New(env, value);
1281+ }
1282+};
1283+
1284+template <typename T>
1285+struct vf_fallback {
1286+ static Value From(napi_env env, const T& value) { return Value(env, value); }
1287+};
1288+
1289+template <typename...>
1290+struct disjunction : std::false_type {};
1291+template <typename B>
1292+struct disjunction<B> : B {};
1293+template <typename B, typename... Bs>
1294+struct disjunction<B, Bs...>
1295+ : std::conditional<bool(B::value), B, disjunction<Bs...>>::type {};
1296+
1297+template <typename T>
1298+struct can_make_string
1299+ : disjunction<typename std::is_convertible<T, const char*>::type,
1300+ typename std::is_convertible<T, const char16_t*>::type,
1301+ typename std::is_convertible<T, std::string>::type,
1302+ typename std::is_convertible<T, std::u16string>::type> {};
1303+} // namespace details
1304+
1305+template <typename T>
1306+Value Value::From(napi_env env, const T& value) {
1307+ using Helper = typename std::conditional<
1308+ std::is_integral<T>::value || std::is_floating_point<T>::value,
1309+ details::vf_number<T>,
1310+ typename std::conditional<details::can_make_string<T>::value,
1311+ String,
1312+ details::vf_fallback<T>>::type>::type;
1313+ return Helper::From(env, value);
1314+}
1315+
1316+template <typename T>
1317+String String::From(napi_env env, const T& value) {
1318+ struct Dummy {};
1319+ using Helper = typename std::conditional<
1320+ std::is_convertible<T, const char*>::value,
1321+ details::vf_utf8_charp,
1322+ typename std::conditional<
1323+ std::is_convertible<T, const char16_t*>::value,
1324+ details::vf_utf16_charp,
1325+ typename std::conditional<
1326+ std::is_convertible<T, std::string>::value,
1327+ details::vf_utf8_string,
1328+ typename std::conditional<
1329+ std::is_convertible<T, std::u16string>::value,
1330+ details::vf_utf16_string,
1331+ Dummy>::type>::type>::type>::type;
1332+ return Helper::From(env, value);
1333+}
1334+
1335+////////////////////////////////////////////////////////////////////////////////
1336+// TypeTaggable class
1337+////////////////////////////////////////////////////////////////////////////////
1338+
1339+inline TypeTaggable::TypeTaggable() : Value() {}
1340+
1341+inline TypeTaggable::TypeTaggable(napi_env _env, napi_value _value)
1342+ : Value(_env, _value) {}
1343+
1344+#if NAPI_VERSION >= 8
1345+
1346+inline void TypeTaggable::TypeTag(const napi_type_tag* type_tag) const {
1347+ napi_status status = napi_type_tag_object(_env, _value, type_tag);
1348+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1349+}
1350+
1351+inline bool TypeTaggable::CheckTypeTag(const napi_type_tag* type_tag) const {
1352+ bool result;
1353+ napi_status status =
1354+ napi_check_object_type_tag(_env, _value, type_tag, &result);
1355+ NAPI_THROW_IF_FAILED(_env, status, false);
1356+ return result;
1357+}
1358+
1359+#endif // NAPI_VERSION >= 8
1360+
1361+////////////////////////////////////////////////////////////////////////////////
1362+// Object class
1363+////////////////////////////////////////////////////////////////////////////////
1364+
1365+template <typename Key>
1366+inline Object::PropertyLValue<Key>::operator Value() const {
1367+ MaybeOrValue<Value> val = Object(_env, _object).Get(_key);
1368+#ifdef NODE_ADDON_API_ENABLE_MAYBE
1369+ return val.Unwrap();
1370+#else
1371+ return val;
1372+#endif
1373+}
1374+
1375+template <typename Key>
1376+template <typename ValueType>
1377+inline Object::PropertyLValue<Key>& Object::PropertyLValue<Key>::operator=(
1378+ ValueType value) {
1379+#ifdef NODE_ADDON_API_ENABLE_MAYBE
1380+ MaybeOrValue<bool> result =
1381+#endif
1382+ Object(_env, _object).Set(_key, value);
1383+#ifdef NODE_ADDON_API_ENABLE_MAYBE
1384+ result.Unwrap();
1385+#endif
1386+ return *this;
1387+}
1388+
1389+template <typename Key>
1390+inline Object::PropertyLValue<Key>::PropertyLValue(Object object, Key key)
1391+ : _env(object.Env()), _object(object), _key(key) {}
1392+
1393+inline Object Object::New(napi_env env) {
1394+ napi_value value;
1395+ napi_status status = napi_create_object(env, &value);
1396+ NAPI_THROW_IF_FAILED(env, status, Object());
1397+ return Object(env, value);
1398+}
1399+
1400+inline void Object::CheckCast(napi_env env, napi_value value) {
1401+ NAPI_CHECK(value != nullptr, "Object::CheckCast", "empty value");
1402+
1403+ napi_valuetype type;
1404+ napi_status status = napi_typeof(env, value, &type);
1405+ NAPI_CHECK(status == napi_ok, "Object::CheckCast", "napi_typeof failed");
1406+ NAPI_CHECK(
1407+ type == napi_object, "Object::CheckCast", "value is not napi_object");
1408+}
1409+
1410+inline Object::Object() : TypeTaggable() {}
1411+
1412+inline Object::Object(napi_env env, napi_value value)
1413+ : TypeTaggable(env, value) {}
1414+
1415+inline Object::PropertyLValue<std::string> Object::operator[](
1416+ const char* utf8name) {
1417+ return PropertyLValue<std::string>(*this, utf8name);
1418+}
1419+
1420+inline Object::PropertyLValue<std::string> Object::operator[](
1421+ const std::string& utf8name) {
1422+ return PropertyLValue<std::string>(*this, utf8name);
1423+}
1424+
1425+inline Object::PropertyLValue<uint32_t> Object::operator[](uint32_t index) {
1426+ return PropertyLValue<uint32_t>(*this, index);
1427+}
1428+
1429+inline Object::PropertyLValue<Value> Object::operator[](Value index) const {
1430+ return PropertyLValue<Value>(*this, index);
1431+}
1432+
1433+inline MaybeOrValue<Value> Object::operator[](const char* utf8name) const {
1434+ return Get(utf8name);
1435+}
1436+
1437+inline MaybeOrValue<Value> Object::operator[](
1438+ const std::string& utf8name) const {
1439+ return Get(utf8name);
1440+}
1441+
1442+inline MaybeOrValue<Value> Object::operator[](uint32_t index) const {
1443+ return Get(index);
1444+}
1445+
1446+inline MaybeOrValue<bool> Object::Has(napi_value key) const {
1447+ bool result;
1448+ napi_status status = napi_has_property(_env, _value, key, &result);
1449+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1450+}
1451+
1452+inline MaybeOrValue<bool> Object::Has(Value key) const {
1453+ bool result;
1454+ napi_status status = napi_has_property(_env, _value, key, &result);
1455+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1456+}
1457+
1458+inline MaybeOrValue<bool> Object::Has(const char* utf8name) const {
1459+ bool result;
1460+ napi_status status = napi_has_named_property(_env, _value, utf8name, &result);
1461+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1462+}
1463+
1464+inline MaybeOrValue<bool> Object::Has(const std::string& utf8name) const {
1465+ return Has(utf8name.c_str());
1466+}
1467+
1468+inline MaybeOrValue<bool> Object::HasOwnProperty(napi_value key) const {
1469+ bool result;
1470+ napi_status status = napi_has_own_property(_env, _value, key, &result);
1471+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1472+}
1473+
1474+inline MaybeOrValue<bool> Object::HasOwnProperty(Value key) const {
1475+ bool result;
1476+ napi_status status = napi_has_own_property(_env, _value, key, &result);
1477+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1478+}
1479+
1480+inline MaybeOrValue<bool> Object::HasOwnProperty(const char* utf8name) const {
1481+ napi_value key;
1482+ napi_status status =
1483+ napi_create_string_utf8(_env, utf8name, std::strlen(utf8name), &key);
1484+ NAPI_MAYBE_THROW_IF_FAILED(_env, status, bool);
1485+ return HasOwnProperty(key);
1486+}
1487+
1488+inline MaybeOrValue<bool> Object::HasOwnProperty(
1489+ const std::string& utf8name) const {
1490+ return HasOwnProperty(utf8name.c_str());
1491+}
1492+
1493+inline MaybeOrValue<Value> Object::Get(napi_value key) const {
1494+ napi_value result;
1495+ napi_status status = napi_get_property(_env, _value, key, &result);
1496+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1497+}
1498+
1499+inline MaybeOrValue<Value> Object::Get(Value key) const {
1500+ napi_value result;
1501+ napi_status status = napi_get_property(_env, _value, key, &result);
1502+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1503+}
1504+
1505+inline MaybeOrValue<Value> Object::Get(const char* utf8name) const {
1506+ napi_value result;
1507+ napi_status status = napi_get_named_property(_env, _value, utf8name, &result);
1508+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1509+}
1510+
1511+inline MaybeOrValue<Value> Object::Get(const std::string& utf8name) const {
1512+ return Get(utf8name.c_str());
1513+}
1514+
1515+template <typename ValueType>
1516+inline MaybeOrValue<bool> Object::Set(napi_value key,
1517+ const ValueType& value) const {
1518+ napi_status status =
1519+ napi_set_property(_env, _value, key, Value::From(_env, value));
1520+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1521+}
1522+
1523+template <typename ValueType>
1524+inline MaybeOrValue<bool> Object::Set(Value key, const ValueType& value) const {
1525+ napi_status status =
1526+ napi_set_property(_env, _value, key, Value::From(_env, value));
1527+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1528+}
1529+
1530+template <typename ValueType>
1531+inline MaybeOrValue<bool> Object::Set(const char* utf8name,
1532+ const ValueType& value) const {
1533+ napi_status status =
1534+ napi_set_named_property(_env, _value, utf8name, Value::From(_env, value));
1535+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1536+}
1537+
1538+template <typename ValueType>
1539+inline MaybeOrValue<bool> Object::Set(const std::string& utf8name,
1540+ const ValueType& value) const {
1541+ return Set(utf8name.c_str(), value);
1542+}
1543+
1544+inline MaybeOrValue<bool> Object::Delete(napi_value key) const {
1545+ bool result;
1546+ napi_status status = napi_delete_property(_env, _value, key, &result);
1547+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1548+}
1549+
1550+inline MaybeOrValue<bool> Object::Delete(Value key) const {
1551+ bool result;
1552+ napi_status status = napi_delete_property(_env, _value, key, &result);
1553+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1554+}
1555+
1556+inline MaybeOrValue<bool> Object::Delete(const char* utf8name) const {
1557+ return Delete(String::New(_env, utf8name));
1558+}
1559+
1560+inline MaybeOrValue<bool> Object::Delete(const std::string& utf8name) const {
1561+ return Delete(String::New(_env, utf8name));
1562+}
1563+
1564+inline MaybeOrValue<bool> Object::Has(uint32_t index) const {
1565+ bool result;
1566+ napi_status status = napi_has_element(_env, _value, index, &result);
1567+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1568+}
1569+
1570+inline MaybeOrValue<Value> Object::Get(uint32_t index) const {
1571+ napi_value value;
1572+ napi_status status = napi_get_element(_env, _value, index, &value);
1573+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, value), Value);
1574+}
1575+
1576+template <typename ValueType>
1577+inline MaybeOrValue<bool> Object::Set(uint32_t index,
1578+ const ValueType& value) const {
1579+ napi_status status =
1580+ napi_set_element(_env, _value, index, Value::From(_env, value));
1581+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1582+}
1583+
1584+inline MaybeOrValue<bool> Object::Delete(uint32_t index) const {
1585+ bool result;
1586+ napi_status status = napi_delete_element(_env, _value, index, &result);
1587+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1588+}
1589+
1590+inline MaybeOrValue<Array> Object::GetPropertyNames() const {
1591+ napi_value result;
1592+ napi_status status = napi_get_property_names(_env, _value, &result);
1593+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Array(_env, result), Array);
1594+}
1595+
1596+inline MaybeOrValue<bool> Object::DefineProperty(
1597+ const PropertyDescriptor& property) const {
1598+ napi_status status = napi_define_properties(
1599+ _env,
1600+ _value,
1601+ 1,
1602+ reinterpret_cast<const napi_property_descriptor*>(&property));
1603+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1604+}
1605+
1606+inline MaybeOrValue<bool> Object::DefineProperties(
1607+ const std::initializer_list<PropertyDescriptor>& properties) const {
1608+ napi_status status = napi_define_properties(
1609+ _env,
1610+ _value,
1611+ properties.size(),
1612+ reinterpret_cast<const napi_property_descriptor*>(properties.begin()));
1613+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1614+}
1615+
1616+inline MaybeOrValue<bool> Object::DefineProperties(
1617+ const std::vector<PropertyDescriptor>& properties) const {
1618+ napi_status status = napi_define_properties(
1619+ _env,
1620+ _value,
1621+ properties.size(),
1622+ reinterpret_cast<const napi_property_descriptor*>(properties.data()));
1623+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1624+}
1625+
1626+inline MaybeOrValue<bool> Object::InstanceOf(
1627+ const Function& constructor) const {
1628+ bool result;
1629+ napi_status status = napi_instanceof(_env, _value, constructor, &result);
1630+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1631+}
1632+
1633+template <typename Finalizer, typename T>
1634+inline void Object::AddFinalizer(Finalizer finalizeCallback, T* data) const {
1635+ details::FinalizeData<T, Finalizer>* finalizeData =
1636+ new details::FinalizeData<T, Finalizer>(
1637+ {std::move(finalizeCallback), nullptr});
1638+ napi_status status =
1639+ details::AttachData<T, details::FinalizeData<T, Finalizer>::Wrapper>(
1640+ _env, *this, data, finalizeData);
1641+ if (status != napi_ok) {
1642+ delete finalizeData;
1643+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1644+ }
1645+}
1646+
1647+template <typename Finalizer, typename T, typename Hint>
1648+inline void Object::AddFinalizer(Finalizer finalizeCallback,
1649+ T* data,
1650+ Hint* finalizeHint) const {
1651+ details::FinalizeData<T, Finalizer, Hint>* finalizeData =
1652+ new details::FinalizeData<T, Finalizer, Hint>(
1653+ {std::move(finalizeCallback), finalizeHint});
1654+ napi_status status = details::
1655+ AttachData<T, details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>(
1656+ _env, *this, data, finalizeData);
1657+ if (status != napi_ok) {
1658+ delete finalizeData;
1659+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1660+ }
1661+}
1662+
1663+#ifdef NAPI_CPP_EXCEPTIONS
1664+inline Object::const_iterator::const_iterator(const Object* object,
1665+ const Type type) {
1666+ _object = object;
1667+ _keys = object->GetPropertyNames();
1668+ _index = type == Type::BEGIN ? 0 : _keys.Length();
1669+}
1670+
1671+inline Object::const_iterator Napi::Object::begin() const {
1672+ const_iterator it(this, Object::const_iterator::Type::BEGIN);
1673+ return it;
1674+}
1675+
1676+inline Object::const_iterator Napi::Object::end() const {
1677+ const_iterator it(this, Object::const_iterator::Type::END);
1678+ return it;
1679+}
1680+
1681+inline Object::const_iterator& Object::const_iterator::operator++() {
1682+ ++_index;
1683+ return *this;
1684+}
1685+
1686+inline bool Object::const_iterator::operator==(
1687+ const const_iterator& other) const {
1688+ return _index == other._index;
1689+}
1690+
1691+inline bool Object::const_iterator::operator!=(
1692+ const const_iterator& other) const {
1693+ return _index != other._index;
1694+}
1695+
1696+inline const std::pair<Value, Object::PropertyLValue<Value>>
1697+Object::const_iterator::operator*() const {
1698+ const Value key = _keys[_index];
1699+ const PropertyLValue<Value> value = (*_object)[key];
1700+ return {key, value};
1701+}
1702+
1703+inline Object::iterator::iterator(Object* object, const Type type) {
1704+ _object = object;
1705+ _keys = object->GetPropertyNames();
1706+ _index = type == Type::BEGIN ? 0 : _keys.Length();
1707+}
1708+
1709+inline Object::iterator Napi::Object::begin() {
1710+ iterator it(this, Object::iterator::Type::BEGIN);
1711+ return it;
1712+}
1713+
1714+inline Object::iterator Napi::Object::end() {
1715+ iterator it(this, Object::iterator::Type::END);
1716+ return it;
1717+}
1718+
1719+inline Object::iterator& Object::iterator::operator++() {
1720+ ++_index;
1721+ return *this;
1722+}
1723+
1724+inline bool Object::iterator::operator==(const iterator& other) const {
1725+ return _index == other._index;
1726+}
1727+
1728+inline bool Object::iterator::operator!=(const iterator& other) const {
1729+ return _index != other._index;
1730+}
1731+
1732+inline std::pair<Value, Object::PropertyLValue<Value>>
1733+Object::iterator::operator*() {
1734+ Value key = _keys[_index];
1735+ PropertyLValue<Value> value = (*_object)[key];
1736+ return {key, value};
1737+}
1738+#endif // NAPI_CPP_EXCEPTIONS
1739+
1740+#if NAPI_VERSION >= 8
1741+inline MaybeOrValue<bool> Object::Freeze() const {
1742+ napi_status status = napi_object_freeze(_env, _value);
1743+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1744+}
1745+
1746+inline MaybeOrValue<bool> Object::Seal() const {
1747+ napi_status status = napi_object_seal(_env, _value);
1748+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1749+}
1750+#endif // NAPI_VERSION >= 8
1751+
1752+////////////////////////////////////////////////////////////////////////////////
1753+// External class
1754+////////////////////////////////////////////////////////////////////////////////
1755+
1756+template <typename T>
1757+inline External<T> External<T>::New(napi_env env, T* data) {
1758+ napi_value value;
1759+ napi_status status =
1760+ napi_create_external(env, data, nullptr, nullptr, &value);
1761+ NAPI_THROW_IF_FAILED(env, status, External());
1762+ return External(env, value);
1763+}
1764+
1765+template <typename T>
1766+template <typename Finalizer>
1767+inline External<T> External<T>::New(napi_env env,
1768+ T* data,
1769+ Finalizer finalizeCallback) {
1770+ napi_value value;
1771+ details::FinalizeData<T, Finalizer>* finalizeData =
1772+ new details::FinalizeData<T, Finalizer>(
1773+ {std::move(finalizeCallback), nullptr});
1774+ napi_status status =
1775+ napi_create_external(env,
1776+ data,
1777+ details::FinalizeData<T, Finalizer>::Wrapper,
1778+ finalizeData,
1779+ &value);
1780+ if (status != napi_ok) {
1781+ delete finalizeData;
1782+ NAPI_THROW_IF_FAILED(env, status, External());
1783+ }
1784+ return External(env, value);
1785+}
1786+
1787+template <typename T>
1788+template <typename Finalizer, typename Hint>
1789+inline External<T> External<T>::New(napi_env env,
1790+ T* data,
1791+ Finalizer finalizeCallback,
1792+ Hint* finalizeHint) {
1793+ napi_value value;
1794+ details::FinalizeData<T, Finalizer, Hint>* finalizeData =
1795+ new details::FinalizeData<T, Finalizer, Hint>(
1796+ {std::move(finalizeCallback), finalizeHint});
1797+ napi_status status = napi_create_external(
1798+ env,
1799+ data,
1800+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
1801+ finalizeData,
1802+ &value);
1803+ if (status != napi_ok) {
1804+ delete finalizeData;
1805+ NAPI_THROW_IF_FAILED(env, status, External());
1806+ }
1807+ return External(env, value);
1808+}
1809+
1810+template <typename T>
1811+inline void External<T>::CheckCast(napi_env env, napi_value value) {
1812+ NAPI_CHECK(value != nullptr, "External::CheckCast", "empty value");
1813+
1814+ napi_valuetype type;
1815+ napi_status status = napi_typeof(env, value, &type);
1816+ NAPI_CHECK(status == napi_ok, "External::CheckCast", "napi_typeof failed");
1817+ NAPI_CHECK(type == napi_external,
1818+ "External::CheckCast",
1819+ "value is not napi_external");
1820+}
1821+
1822+template <typename T>
1823+inline External<T>::External() : TypeTaggable() {}
1824+
1825+template <typename T>
1826+inline External<T>::External(napi_env env, napi_value value)
1827+ : TypeTaggable(env, value) {}
1828+
1829+template <typename T>
1830+inline T* External<T>::Data() const {
1831+ void* data;
1832+ napi_status status = napi_get_value_external(_env, _value, &data);
1833+ NAPI_THROW_IF_FAILED(_env, status, nullptr);
1834+ return reinterpret_cast<T*>(data);
1835+}
1836+
1837+////////////////////////////////////////////////////////////////////////////////
1838+// Array class
1839+////////////////////////////////////////////////////////////////////////////////
1840+
1841+inline Array Array::New(napi_env env) {
1842+ napi_value value;
1843+ napi_status status = napi_create_array(env, &value);
1844+ NAPI_THROW_IF_FAILED(env, status, Array());
1845+ return Array(env, value);
1846+}
1847+
1848+inline Array Array::New(napi_env env, size_t length) {
1849+ napi_value value;
1850+ napi_status status = napi_create_array_with_length(env, length, &value);
1851+ NAPI_THROW_IF_FAILED(env, status, Array());
1852+ return Array(env, value);
1853+}
1854+
1855+inline void Array::CheckCast(napi_env env, napi_value value) {
1856+ NAPI_CHECK(value != nullptr, "Array::CheckCast", "empty value");
1857+
1858+ bool result;
1859+ napi_status status = napi_is_array(env, value, &result);
1860+ NAPI_CHECK(status == napi_ok, "Array::CheckCast", "napi_is_array failed");
1861+ NAPI_CHECK(result, "Array::CheckCast", "value is not array");
1862+}
1863+
1864+inline Array::Array() : Object() {}
1865+
1866+inline Array::Array(napi_env env, napi_value value) : Object(env, value) {}
1867+
1868+inline uint32_t Array::Length() const {
1869+ uint32_t result;
1870+ napi_status status = napi_get_array_length(_env, _value, &result);
1871+ NAPI_THROW_IF_FAILED(_env, status, 0);
1872+ return result;
1873+}
1874+
1875+////////////////////////////////////////////////////////////////////////////////
1876+// ArrayBuffer class
1877+////////////////////////////////////////////////////////////////////////////////
1878+
1879+inline ArrayBuffer ArrayBuffer::New(napi_env env, size_t byteLength) {
1880+ napi_value value;
1881+ void* data;
1882+ napi_status status = napi_create_arraybuffer(env, byteLength, &data, &value);
1883+ NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1884+
1885+ return ArrayBuffer(env, value);
1886+}
1887+
1888+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1889+inline ArrayBuffer ArrayBuffer::New(napi_env env,
1890+ void* externalData,
1891+ size_t byteLength) {
1892+ napi_value value;
1893+ napi_status status = napi_create_external_arraybuffer(
1894+ env, externalData, byteLength, nullptr, nullptr, &value);
1895+ NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1896+
1897+ return ArrayBuffer(env, value);
1898+}
1899+
1900+template <typename Finalizer>
1901+inline ArrayBuffer ArrayBuffer::New(napi_env env,
1902+ void* externalData,
1903+ size_t byteLength,
1904+ Finalizer finalizeCallback) {
1905+ napi_value value;
1906+ details::FinalizeData<void, Finalizer>* finalizeData =
1907+ new details::FinalizeData<void, Finalizer>(
1908+ {std::move(finalizeCallback), nullptr});
1909+ napi_status status = napi_create_external_arraybuffer(
1910+ env,
1911+ externalData,
1912+ byteLength,
1913+ details::FinalizeData<void, Finalizer>::Wrapper,
1914+ finalizeData,
1915+ &value);
1916+ if (status != napi_ok) {
1917+ delete finalizeData;
1918+ NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1919+ }
1920+
1921+ return ArrayBuffer(env, value);
1922+}
1923+
1924+template <typename Finalizer, typename Hint>
1925+inline ArrayBuffer ArrayBuffer::New(napi_env env,
1926+ void* externalData,
1927+ size_t byteLength,
1928+ Finalizer finalizeCallback,
1929+ Hint* finalizeHint) {
1930+ napi_value value;
1931+ details::FinalizeData<void, Finalizer, Hint>* finalizeData =
1932+ new details::FinalizeData<void, Finalizer, Hint>(
1933+ {std::move(finalizeCallback), finalizeHint});
1934+ napi_status status = napi_create_external_arraybuffer(
1935+ env,
1936+ externalData,
1937+ byteLength,
1938+ details::FinalizeData<void, Finalizer, Hint>::WrapperWithHint,
1939+ finalizeData,
1940+ &value);
1941+ if (status != napi_ok) {
1942+ delete finalizeData;
1943+ NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1944+ }
1945+
1946+ return ArrayBuffer(env, value);
1947+}
1948+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1949+
1950+inline void ArrayBuffer::CheckCast(napi_env env, napi_value value) {
1951+ NAPI_CHECK(value != nullptr, "ArrayBuffer::CheckCast", "empty value");
1952+
1953+ bool result;
1954+ napi_status status = napi_is_arraybuffer(env, value, &result);
1955+ NAPI_CHECK(status == napi_ok,
1956+ "ArrayBuffer::CheckCast",
1957+ "napi_is_arraybuffer failed");
1958+ NAPI_CHECK(result, "ArrayBuffer::CheckCast", "value is not arraybuffer");
1959+}
1960+
1961+inline ArrayBuffer::ArrayBuffer() : Object() {}
1962+
1963+inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value)
1964+ : Object(env, value) {}
1965+
1966+inline void* ArrayBuffer::Data() {
1967+ void* data;
1968+ napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr);
1969+ NAPI_THROW_IF_FAILED(_env, status, nullptr);
1970+ return data;
1971+}
1972+
1973+inline size_t ArrayBuffer::ByteLength() {
1974+ size_t length;
1975+ napi_status status =
1976+ napi_get_arraybuffer_info(_env, _value, nullptr, &length);
1977+ NAPI_THROW_IF_FAILED(_env, status, 0);
1978+ return length;
1979+}
1980+
1981+#if NAPI_VERSION >= 7
1982+inline bool ArrayBuffer::IsDetached() const {
1983+ bool detached;
1984+ napi_status status = napi_is_detached_arraybuffer(_env, _value, &detached);
1985+ NAPI_THROW_IF_FAILED(_env, status, false);
1986+ return detached;
1987+}
1988+
1989+inline void ArrayBuffer::Detach() {
1990+ napi_status status = napi_detach_arraybuffer(_env, _value);
1991+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1992+}
1993+#endif // NAPI_VERSION >= 7
1994+
1995+////////////////////////////////////////////////////////////////////////////////
1996+// DataView class
1997+////////////////////////////////////////////////////////////////////////////////
1998+inline DataView DataView::New(napi_env env, Napi::ArrayBuffer arrayBuffer) {
1999+ return New(env, arrayBuffer, 0, arrayBuffer.ByteLength());
2000+}
2001+
2002+inline DataView DataView::New(napi_env env,
2003+ Napi::ArrayBuffer arrayBuffer,
2004+ size_t byteOffset) {
2005+ if (byteOffset > arrayBuffer.ByteLength()) {
2006+ NAPI_THROW(RangeError::New(
2007+ env, "Start offset is outside the bounds of the buffer"),
2008+ DataView());
2009+ }
2010+ return New(
2011+ env, arrayBuffer, byteOffset, arrayBuffer.ByteLength() - byteOffset);
2012+}
2013+
2014+inline DataView DataView::New(napi_env env,
2015+ Napi::ArrayBuffer arrayBuffer,
2016+ size_t byteOffset,
2017+ size_t byteLength) {
2018+ if (byteOffset + byteLength > arrayBuffer.ByteLength()) {
2019+ NAPI_THROW(RangeError::New(env, "Invalid DataView length"), DataView());
2020+ }
2021+ napi_value value;
2022+ napi_status status =
2023+ napi_create_dataview(env, byteLength, arrayBuffer, byteOffset, &value);
2024+ NAPI_THROW_IF_FAILED(env, status, DataView());
2025+ return DataView(env, value);
2026+}
2027+
2028+inline void DataView::CheckCast(napi_env env, napi_value value) {
2029+ NAPI_CHECK(value != nullptr, "DataView::CheckCast", "empty value");
2030+
2031+ bool result;
2032+ napi_status status = napi_is_dataview(env, value, &result);
2033+ NAPI_CHECK(
2034+ status == napi_ok, "DataView::CheckCast", "napi_is_dataview failed");
2035+ NAPI_CHECK(result, "DataView::CheckCast", "value is not dataview");
2036+}
2037+
2038+inline DataView::DataView() : Object() {}
2039+
2040+inline DataView::DataView(napi_env env, napi_value value) : Object(env, value) {
2041+ napi_status status = napi_get_dataview_info(_env,
2042+ _value /* dataView */,
2043+ &_length /* byteLength */,
2044+ &_data /* data */,
2045+ nullptr /* arrayBuffer */,
2046+ nullptr /* byteOffset */);
2047+ NAPI_THROW_IF_FAILED_VOID(_env, status);
2048+}
2049+
2050+inline Napi::ArrayBuffer DataView::ArrayBuffer() const {
2051+ napi_value arrayBuffer;
2052+ napi_status status = napi_get_dataview_info(_env,
2053+ _value /* dataView */,
2054+ nullptr /* byteLength */,
2055+ nullptr /* data */,
2056+ &arrayBuffer /* arrayBuffer */,
2057+ nullptr /* byteOffset */);
2058+ NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer());
2059+ return Napi::ArrayBuffer(_env, arrayBuffer);
2060+}
2061+
2062+inline size_t DataView::ByteOffset() const {
2063+ size_t byteOffset;
2064+ napi_status status = napi_get_dataview_info(_env,
2065+ _value /* dataView */,
2066+ nullptr /* byteLength */,
2067+ nullptr /* data */,
2068+ nullptr /* arrayBuffer */,
2069+ &byteOffset /* byteOffset */);
2070+ NAPI_THROW_IF_FAILED(_env, status, 0);
2071+ return byteOffset;
2072+}
2073+
2074+inline size_t DataView::ByteLength() const {
2075+ return _length;
2076+}
2077+
2078+inline void* DataView::Data() const {
2079+ return _data;
2080+}
2081+
2082+inline float DataView::GetFloat32(size_t byteOffset) const {
2083+ return ReadData<float>(byteOffset);
2084+}
2085+
2086+inline double DataView::GetFloat64(size_t byteOffset) const {
2087+ return ReadData<double>(byteOffset);
2088+}
2089+
2090+inline int8_t DataView::GetInt8(size_t byteOffset) const {
2091+ return ReadData<int8_t>(byteOffset);
2092+}
2093+
2094+inline int16_t DataView::GetInt16(size_t byteOffset) const {
2095+ return ReadData<int16_t>(byteOffset);
2096+}
2097+
2098+inline int32_t DataView::GetInt32(size_t byteOffset) const {
2099+ return ReadData<int32_t>(byteOffset);
2100+}
2101+
2102+inline uint8_t DataView::GetUint8(size_t byteOffset) const {
2103+ return ReadData<uint8_t>(byteOffset);
2104+}
2105+
2106+inline uint16_t DataView::GetUint16(size_t byteOffset) const {
2107+ return ReadData<uint16_t>(byteOffset);
2108+}
2109+
2110+inline uint32_t DataView::GetUint32(size_t byteOffset) const {
2111+ return ReadData<uint32_t>(byteOffset);
2112+}
2113+
2114+inline void DataView::SetFloat32(size_t byteOffset, float value) const {
2115+ WriteData<float>(byteOffset, value);
2116+}
2117+
2118+inline void DataView::SetFloat64(size_t byteOffset, double value) const {
2119+ WriteData<double>(byteOffset, value);
2120+}
2121+
2122+inline void DataView::SetInt8(size_t byteOffset, int8_t value) const {
2123+ WriteData<int8_t>(byteOffset, value);
2124+}
2125+
2126+inline void DataView::SetInt16(size_t byteOffset, int16_t value) const {
2127+ WriteData<int16_t>(byteOffset, value);
2128+}
2129+
2130+inline void DataView::SetInt32(size_t byteOffset, int32_t value) const {
2131+ WriteData<int32_t>(byteOffset, value);
2132+}
2133+
2134+inline void DataView::SetUint8(size_t byteOffset, uint8_t value) const {
2135+ WriteData<uint8_t>(byteOffset, value);
2136+}
2137+
2138+inline void DataView::SetUint16(size_t byteOffset, uint16_t value) const {
2139+ WriteData<uint16_t>(byteOffset, value);
2140+}
2141+
2142+inline void DataView::SetUint32(size_t byteOffset, uint32_t value) const {
2143+ WriteData<uint32_t>(byteOffset, value);
2144+}
2145+
2146+template <typename T>
2147+inline T DataView::ReadData(size_t byteOffset) const {
2148+ if (byteOffset + sizeof(T) > _length ||
2149+ byteOffset + sizeof(T) < byteOffset) { // overflow
2150+ NAPI_THROW(
2151+ RangeError::New(_env, "Offset is outside the bounds of the DataView"),
2152+ 0);
2153+ }
2154+
2155+ return *reinterpret_cast<T*>(static_cast<uint8_t*>(_data) + byteOffset);
2156+}
2157+
2158+template <typename T>
2159+inline void DataView::WriteData(size_t byteOffset, T value) const {
2160+ if (byteOffset + sizeof(T) > _length ||
2161+ byteOffset + sizeof(T) < byteOffset) { // overflow
2162+ NAPI_THROW_VOID(
2163+ RangeError::New(_env, "Offset is outside the bounds of the DataView"));
2164+ }
2165+
2166+ *reinterpret_cast<T*>(static_cast<uint8_t*>(_data) + byteOffset) = value;
2167+}
2168+
2169+////////////////////////////////////////////////////////////////////////////////
2170+// TypedArray class
2171+////////////////////////////////////////////////////////////////////////////////
2172+inline void TypedArray::CheckCast(napi_env env, napi_value value) {
2173+ NAPI_CHECK(value != nullptr, "TypedArray::CheckCast", "empty value");
2174+
2175+ bool result;
2176+ napi_status status = napi_is_typedarray(env, value, &result);
2177+ NAPI_CHECK(
2178+ status == napi_ok, "TypedArray::CheckCast", "napi_is_typedarray failed");
2179+ NAPI_CHECK(result, "TypedArray::CheckCast", "value is not typedarray");
2180+}
2181+
2182+inline TypedArray::TypedArray()
2183+ : Object(), _type(napi_typedarray_type::napi_int8_array), _length(0) {}
2184+
2185+inline TypedArray::TypedArray(napi_env env, napi_value value)
2186+ : Object(env, value),
2187+ _type(napi_typedarray_type::napi_int8_array),
2188+ _length(0) {
2189+ if (value != nullptr) {
2190+ napi_status status =
2191+ napi_get_typedarray_info(_env,
2192+ _value,
2193+ &const_cast<TypedArray*>(this)->_type,
2194+ &const_cast<TypedArray*>(this)->_length,
2195+ nullptr,
2196+ nullptr,
2197+ nullptr);
2198+ NAPI_THROW_IF_FAILED_VOID(_env, status);
2199+ }
2200+}
2201+
2202+inline TypedArray::TypedArray(napi_env env,
2203+ napi_value value,
2204+ napi_typedarray_type type,
2205+ size_t length)
2206+ : Object(env, value), _type(type), _length(length) {}
2207+
2208+inline napi_typedarray_type TypedArray::TypedArrayType() const {
2209+ return _type;
2210+}
2211+
2212+inline uint8_t TypedArray::ElementSize() const {
2213+ switch (_type) {
2214+ case napi_int8_array:
2215+ case napi_uint8_array:
2216+ case napi_uint8_clamped_array:
2217+ return 1;
2218+ case napi_int16_array:
2219+ case napi_uint16_array:
2220+ return 2;
2221+ case napi_int32_array:
2222+ case napi_uint32_array:
2223+ case napi_float32_array:
2224+ return 4;
2225+ case napi_float64_array:
2226+#if (NAPI_VERSION > 5)
2227+ case napi_bigint64_array:
2228+ case napi_biguint64_array:
2229+#endif // (NAPI_VERSION > 5)
2230+ return 8;
2231+ default:
2232+ return 0;
2233+ }
2234+}
2235+
2236+inline size_t TypedArray::ElementLength() const {
2237+ return _length;
2238+}
2239+
2240+inline size_t TypedArray::ByteOffset() const {
2241+ size_t byteOffset;
2242+ napi_status status = napi_get_typedarray_info(
2243+ _env, _value, nullptr, nullptr, nullptr, nullptr, &byteOffset);
2244+ NAPI_THROW_IF_FAILED(_env, status, 0);
2245+ return byteOffset;
2246+}
2247+
2248+inline size_t TypedArray::ByteLength() const {
2249+ return ElementSize() * ElementLength();
2250+}
2251+
2252+inline Napi::ArrayBuffer TypedArray::ArrayBuffer() const {
2253+ napi_value arrayBuffer;
2254+ napi_status status = napi_get_typedarray_info(
2255+ _env, _value, nullptr, nullptr, nullptr, &arrayBuffer, nullptr);
2256+ NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer());
2257+ return Napi::ArrayBuffer(_env, arrayBuffer);
2258+}
2259+
2260+////////////////////////////////////////////////////////////////////////////////
2261+// TypedArrayOf<T> class
2262+////////////////////////////////////////////////////////////////////////////////
2263+template <typename T>
2264+inline void TypedArrayOf<T>::CheckCast(napi_env env, napi_value value) {
2265+ TypedArray::CheckCast(env, value);
2266+ napi_typedarray_type type;
2267+ napi_status status = napi_get_typedarray_info(
2268+ env, value, &type, nullptr, nullptr, nullptr, nullptr);
2269+ NAPI_CHECK(status == napi_ok,
2270+ "TypedArrayOf::CheckCast",
2271+ "napi_is_typedarray failed");
2272+
2273+ NAPI_CHECK(
2274+ (type == TypedArrayTypeForPrimitiveType<T>() ||
2275+ (type == napi_uint8_clamped_array && std::is_same<T, uint8_t>::value)),
2276+ "TypedArrayOf::CheckCast",
2277+ "Array type must match the template parameter. (Uint8 arrays may "
2278+ "optionally have the \"clamped\" array type.)");
2279+}
2280+
2281+template <typename T>
2282+inline TypedArrayOf<T> TypedArrayOf<T>::New(napi_env env,
2283+ size_t elementLength,
2284+ napi_typedarray_type type) {
2285+ Napi::ArrayBuffer arrayBuffer =
2286+ Napi::ArrayBuffer::New(env, elementLength * sizeof(T));
2287+ return New(env, elementLength, arrayBuffer, 0, type);
2288+}
2289+
2290+template <typename T>
2291+inline TypedArrayOf<T> TypedArrayOf<T>::New(napi_env env,
2292+ size_t elementLength,
2293+ Napi::ArrayBuffer arrayBuffer,
2294+ size_t bufferOffset,
2295+ napi_typedarray_type type) {
2296+ napi_value value;
2297+ napi_status status = napi_create_typedarray(
2298+ env, type, elementLength, arrayBuffer, bufferOffset, &value);
2299+ NAPI_THROW_IF_FAILED(env, status, TypedArrayOf<T>());
2300+
2301+ return TypedArrayOf<T>(
2302+ env,
2303+ value,
2304+ type,
2305+ elementLength,
2306+ reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(arrayBuffer.Data()) +
2307+ bufferOffset));
2308+}
2309+
2310+template <typename T>
2311+inline TypedArrayOf<T>::TypedArrayOf() : TypedArray(), _data(nullptr) {}
2312+
2313+template <typename T>
2314+inline TypedArrayOf<T>::TypedArrayOf(napi_env env, napi_value value)
2315+ : TypedArray(env, value), _data(nullptr) {
2316+ napi_status status = napi_ok;
2317+ if (value != nullptr) {
2318+ void* data = nullptr;
2319+ status = napi_get_typedarray_info(
2320+ _env, _value, &_type, &_length, &data, nullptr, nullptr);
2321+ _data = static_cast<T*>(data);
2322+ } else {
2323+ _type = TypedArrayTypeForPrimitiveType<T>();
2324+ _length = 0;
2325+ }
2326+ NAPI_THROW_IF_FAILED_VOID(_env, status);
2327+}
2328+
2329+template <typename T>
2330+inline TypedArrayOf<T>::TypedArrayOf(napi_env env,
2331+ napi_value value,
2332+ napi_typedarray_type type,
2333+ size_t length,
2334+ T* data)
2335+ : TypedArray(env, value, type, length), _data(data) {
2336+ if (!(type == TypedArrayTypeForPrimitiveType<T>() ||
2337+ (type == napi_uint8_clamped_array &&
2338+ std::is_same<T, uint8_t>::value))) {
2339+ NAPI_THROW_VOID(TypeError::New(
2340+ env,
2341+ "Array type must match the template parameter. "
2342+ "(Uint8 arrays may optionally have the \"clamped\" array type.)"));
2343+ }
2344+}
2345+
2346+template <typename T>
2347+inline T& TypedArrayOf<T>::operator[](size_t index) {
2348+ return _data[index];
2349+}
2350+
2351+template <typename T>
2352+inline const T& TypedArrayOf<T>::operator[](size_t index) const {
2353+ return _data[index];
2354+}
2355+
2356+template <typename T>
2357+inline T* TypedArrayOf<T>::Data() {
2358+ return _data;
2359+}
2360+
2361+template <typename T>
2362+inline const T* TypedArrayOf<T>::Data() const {
2363+ return _data;
2364+}
2365+
2366+////////////////////////////////////////////////////////////////////////////////
2367+// Function class
2368+////////////////////////////////////////////////////////////////////////////////
2369+
2370+template <typename CbData>
2371+inline napi_status CreateFunction(napi_env env,
2372+ const char* utf8name,
2373+ napi_callback cb,
2374+ CbData* data,
2375+ napi_value* result) {
2376+ napi_status status =
2377+ napi_create_function(env, utf8name, NAPI_AUTO_LENGTH, cb, data, result);
2378+ if (status == napi_ok) {
2379+ status = Napi::details::AttachData(env, *result, data);
2380+ }
2381+
2382+ return status;
2383+}
2384+
2385+template <Function::VoidCallback cb>
2386+inline Function Function::New(napi_env env, const char* utf8name, void* data) {
2387+ napi_value result = nullptr;
2388+ napi_status status = napi_create_function(env,
2389+ utf8name,
2390+ NAPI_AUTO_LENGTH,
2391+ details::TemplatedVoidCallback<cb>,
2392+ data,
2393+ &result);
2394+ NAPI_THROW_IF_FAILED(env, status, Function());
2395+ return Function(env, result);
2396+}
2397+
2398+template <Function::Callback cb>
2399+inline Function Function::New(napi_env env, const char* utf8name, void* data) {
2400+ napi_value result = nullptr;
2401+ napi_status status = napi_create_function(env,
2402+ utf8name,
2403+ NAPI_AUTO_LENGTH,
2404+ details::TemplatedCallback<cb>,
2405+ data,
2406+ &result);
2407+ NAPI_THROW_IF_FAILED(env, status, Function());
2408+ return Function(env, result);
2409+}
2410+
2411+template <Function::VoidCallback cb>
2412+inline Function Function::New(napi_env env,
2413+ const std::string& utf8name,
2414+ void* data) {
2415+ return Function::New<cb>(env, utf8name.c_str(), data);
2416+}
2417+
2418+template <Function::Callback cb>
2419+inline Function Function::New(napi_env env,
2420+ const std::string& utf8name,
2421+ void* data) {
2422+ return Function::New<cb>(env, utf8name.c_str(), data);
2423+}
2424+
2425+template <typename Callable>
2426+inline Function Function::New(napi_env env,
2427+ Callable cb,
2428+ const char* utf8name,
2429+ void* data) {
2430+ using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr)));
2431+ using CbData = details::CallbackData<Callable, ReturnType>;
2432+ auto callbackData = new CbData{std::move(cb), data};
2433+
2434+ napi_value value;
2435+ napi_status status =
2436+ CreateFunction(env, utf8name, CbData::Wrapper, callbackData, &value);
2437+ if (status != napi_ok) {
2438+ delete callbackData;
2439+ NAPI_THROW_IF_FAILED(env, status, Function());
2440+ }
2441+
2442+ return Function(env, value);
2443+}
2444+
2445+template <typename Callable>
2446+inline Function Function::New(napi_env env,
2447+ Callable cb,
2448+ const std::string& utf8name,
2449+ void* data) {
2450+ return New(env, cb, utf8name.c_str(), data);
2451+}
2452+
2453+inline void Function::CheckCast(napi_env env, napi_value value) {
2454+ NAPI_CHECK(value != nullptr, "Function::CheckCast", "empty value");
2455+
2456+ napi_valuetype type;
2457+ napi_status status = napi_typeof(env, value, &type);
2458+ NAPI_CHECK(status == napi_ok, "Function::CheckCast", "napi_typeof failed");
2459+ NAPI_CHECK(type == napi_function,
2460+ "Function::CheckCast",
2461+ "value is not napi_function");
2462+}
2463+
2464+inline Function::Function() : Object() {}
2465+
2466+inline Function::Function(napi_env env, napi_value value)
2467+ : Object(env, value) {}
2468+
2469+inline MaybeOrValue<Value> Function::operator()(
2470+ const std::initializer_list<napi_value>& args) const {
2471+ return Call(Env().Undefined(), args);
2472+}
2473+
2474+inline MaybeOrValue<Value> Function::Call(
2475+ const std::initializer_list<napi_value>& args) const {
2476+ return Call(Env().Undefined(), args);
2477+}
2478+
2479+inline MaybeOrValue<Value> Function::Call(
2480+ const std::vector<napi_value>& args) const {
2481+ return Call(Env().Undefined(), args);
2482+}
2483+
2484+inline MaybeOrValue<Value> Function::Call(
2485+ const std::vector<Value>& args) const {
2486+ return Call(Env().Undefined(), args);
2487+}
2488+
2489+inline MaybeOrValue<Value> Function::Call(size_t argc,
2490+ const napi_value* args) const {
2491+ return Call(Env().Undefined(), argc, args);
2492+}
2493+
2494+inline MaybeOrValue<Value> Function::Call(
2495+ napi_value recv, const std::initializer_list<napi_value>& args) const {
2496+ return Call(recv, args.size(), args.begin());
2497+}
2498+
2499+inline MaybeOrValue<Value> Function::Call(
2500+ napi_value recv, const std::vector<napi_value>& args) const {
2501+ return Call(recv, args.size(), args.data());
2502+}
2503+
2504+inline MaybeOrValue<Value> Function::Call(
2505+ napi_value recv, const std::vector<Value>& args) const {
2506+ const size_t argc = args.size();
2507+ const size_t stackArgsCount = 6;
2508+ napi_value stackArgs[stackArgsCount];
2509+ std::vector<napi_value> heapArgs;
2510+ napi_value* argv;
2511+ if (argc <= stackArgsCount) {
2512+ argv = stackArgs;
2513+ } else {
2514+ heapArgs.resize(argc);
2515+ argv = heapArgs.data();
2516+ }
2517+
2518+ for (size_t index = 0; index < argc; index++) {
2519+ argv[index] = static_cast<napi_value>(args[index]);
2520+ }
2521+
2522+ return Call(recv, argc, argv);
2523+}
2524+
2525+inline MaybeOrValue<Value> Function::Call(napi_value recv,
2526+ size_t argc,
2527+ const napi_value* args) const {
2528+ napi_value result;
2529+ napi_status status =
2530+ napi_call_function(_env, recv, _value, argc, args, &result);
2531+ NAPI_RETURN_OR_THROW_IF_FAILED(
2532+ _env, status, Napi::Value(_env, result), Napi::Value);
2533+}
2534+
2535+inline MaybeOrValue<Value> Function::MakeCallback(
2536+ napi_value recv,
2537+ const std::initializer_list<napi_value>& args,
2538+ napi_async_context context) const {
2539+ return MakeCallback(recv, args.size(), args.begin(), context);
2540+}
2541+
2542+inline MaybeOrValue<Value> Function::MakeCallback(
2543+ napi_value recv,
2544+ const std::vector<napi_value>& args,
2545+ napi_async_context context) const {
2546+ return MakeCallback(recv, args.size(), args.data(), context);
2547+}
2548+
2549+inline MaybeOrValue<Value> Function::MakeCallback(
2550+ napi_value recv,
2551+ size_t argc,
2552+ const napi_value* args,
2553+ napi_async_context context) const {
2554+ napi_value result;
2555+ napi_status status =
2556+ napi_make_callback(_env, context, recv, _value, argc, args, &result);
2557+ NAPI_RETURN_OR_THROW_IF_FAILED(
2558+ _env, status, Napi::Value(_env, result), Napi::Value);
2559+}
2560+
2561+inline MaybeOrValue<Object> Function::New(
2562+ const std::initializer_list<napi_value>& args) const {
2563+ return New(args.size(), args.begin());
2564+}
2565+
2566+inline MaybeOrValue<Object> Function::New(
2567+ const std::vector<napi_value>& args) const {
2568+ return New(args.size(), args.data());
2569+}
2570+
2571+inline MaybeOrValue<Object> Function::New(size_t argc,
2572+ const napi_value* args) const {
2573+ napi_value result;
2574+ napi_status status = napi_new_instance(_env, _value, argc, args, &result);
2575+ NAPI_RETURN_OR_THROW_IF_FAILED(
2576+ _env, status, Napi::Object(_env, result), Napi::Object);
2577+}
2578+
2579+////////////////////////////////////////////////////////////////////////////////
2580+// Promise class
2581+////////////////////////////////////////////////////////////////////////////////
2582+
2583+inline Promise::Deferred Promise::Deferred::New(napi_env env) {
2584+ return Promise::Deferred(env);
2585+}
2586+
2587+inline Promise::Deferred::Deferred(napi_env env) : _env(env) {
2588+ napi_status status = napi_create_promise(_env, &_deferred, &_promise);
2589+ NAPI_THROW_IF_FAILED_VOID(_env, status);
2590+}
2591+
2592+inline Promise Promise::Deferred::Promise() const {
2593+ return Napi::Promise(_env, _promise);
2594+}
2595+
2596+inline Napi::Env Promise::Deferred::Env() const {
2597+ return Napi::Env(_env);
2598+}
2599+
2600+inline void Promise::Deferred::Resolve(napi_value value) const {
2601+ napi_status status = napi_resolve_deferred(_env, _deferred, value);
2602+ NAPI_THROW_IF_FAILED_VOID(_env, status);
2603+}
2604+
2605+inline void Promise::Deferred::Reject(napi_value value) const {
2606+ napi_status status = napi_reject_deferred(_env, _deferred, value);
2607+ NAPI_THROW_IF_FAILED_VOID(_env, status);
2608+}
2609+
2610+inline void Promise::CheckCast(napi_env env, napi_value value) {
2611+ NAPI_CHECK(value != nullptr, "Promise::CheckCast", "empty value");
2612+
2613+ bool result;
2614+ napi_status status = napi_is_promise(env, value, &result);
2615+ NAPI_CHECK(status == napi_ok, "Promise::CheckCast", "napi_is_promise failed");
2616+ NAPI_CHECK(result, "Promise::CheckCast", "value is not promise");
2617+}
2618+
2619+inline Promise::Promise(napi_env env, napi_value value) : Object(env, value) {}
2620+
2621+////////////////////////////////////////////////////////////////////////////////
2622+// Buffer<T> class
2623+////////////////////////////////////////////////////////////////////////////////
2624+
2625+template <typename T>
2626+inline Buffer<T> Buffer<T>::New(napi_env env, size_t length) {
2627+ napi_value value;
2628+ void* data;
2629+ napi_status status =
2630+ napi_create_buffer(env, length * sizeof(T), &data, &value);
2631+ NAPI_THROW_IF_FAILED(env, status, Buffer<T>());
2632+ return Buffer(env, value);
2633+}
2634+
2635+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2636+template <typename T>
2637+inline Buffer<T> Buffer<T>::New(napi_env env, T* data, size_t length) {
2638+ napi_value value;
2639+ napi_status status = napi_create_external_buffer(
2640+ env, length * sizeof(T), data, nullptr, nullptr, &value);
2641+ NAPI_THROW_IF_FAILED(env, status, Buffer<T>());
2642+ return Buffer(env, value);
2643+}
2644+
2645+template <typename T>
2646+template <typename Finalizer>
2647+inline Buffer<T> Buffer<T>::New(napi_env env,
2648+ T* data,
2649+ size_t length,
2650+ Finalizer finalizeCallback) {
2651+ napi_value value;
2652+ details::FinalizeData<T, Finalizer>* finalizeData =
2653+ new details::FinalizeData<T, Finalizer>(
2654+ {std::move(finalizeCallback), nullptr});
2655+ napi_status status =
2656+ napi_create_external_buffer(env,
2657+ length * sizeof(T),
2658+ data,
2659+ details::FinalizeData<T, Finalizer>::Wrapper,
2660+ finalizeData,
2661+ &value);
2662+ if (status != napi_ok) {
2663+ delete finalizeData;
2664+ NAPI_THROW_IF_FAILED(env, status, Buffer());
2665+ }
2666+ return Buffer(env, value);
2667+}
2668+
2669+template <typename T>
2670+template <typename Finalizer, typename Hint>
2671+inline Buffer<T> Buffer<T>::New(napi_env env,
2672+ T* data,
2673+ size_t length,
2674+ Finalizer finalizeCallback,
2675+ Hint* finalizeHint) {
2676+ napi_value value;
2677+ details::FinalizeData<T, Finalizer, Hint>* finalizeData =
2678+ new details::FinalizeData<T, Finalizer, Hint>(
2679+ {std::move(finalizeCallback), finalizeHint});
2680+ napi_status status = napi_create_external_buffer(
2681+ env,
2682+ length * sizeof(T),
2683+ data,
2684+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2685+ finalizeData,
2686+ &value);
2687+ if (status != napi_ok) {
2688+ delete finalizeData;
2689+ NAPI_THROW_IF_FAILED(env, status, Buffer());
2690+ }
2691+ return Buffer(env, value);
2692+}
2693+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2694+
2695+template <typename T>
2696+inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env, T* data, size_t length) {
2697+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2698+ napi_value value;
2699+ napi_status status = napi_create_external_buffer(
2700+ env, length * sizeof(T), data, nullptr, nullptr, &value);
2701+ if (status == details::napi_no_external_buffers_allowed) {
2702+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2703+ // If we can't create an external buffer, we'll just copy the data.
2704+ return Buffer<T>::Copy(env, data, length);
2705+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2706+ }
2707+ NAPI_THROW_IF_FAILED(env, status, Buffer<T>());
2708+ return Buffer(env, value);
2709+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2710+}
2711+
2712+template <typename T>
2713+template <typename Finalizer>
2714+inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2715+ T* data,
2716+ size_t length,
2717+ Finalizer finalizeCallback) {
2718+ details::FinalizeData<T, Finalizer>* finalizeData =
2719+ new details::FinalizeData<T, Finalizer>(
2720+ {std::move(finalizeCallback), nullptr});
2721+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2722+ napi_value value;
2723+ napi_status status =
2724+ napi_create_external_buffer(env,
2725+ length * sizeof(T),
2726+ data,
2727+ details::FinalizeData<T, Finalizer>::Wrapper,
2728+ finalizeData,
2729+ &value);
2730+ if (status == details::napi_no_external_buffers_allowed) {
2731+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2732+ // If we can't create an external buffer, we'll just copy the data.
2733+ Buffer<T> ret = Buffer<T>::Copy(env, data, length);
2734+ details::FinalizeData<T, Finalizer>::Wrapper(env, data, finalizeData);
2735+ return ret;
2736+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2737+ }
2738+ if (status != napi_ok) {
2739+ delete finalizeData;
2740+ NAPI_THROW_IF_FAILED(env, status, Buffer());
2741+ }
2742+ return Buffer(env, value);
2743+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2744+}
2745+
2746+template <typename T>
2747+template <typename Finalizer, typename Hint>
2748+inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2749+ T* data,
2750+ size_t length,
2751+ Finalizer finalizeCallback,
2752+ Hint* finalizeHint) {
2753+ details::FinalizeData<T, Finalizer, Hint>* finalizeData =
2754+ new details::FinalizeData<T, Finalizer, Hint>(
2755+ {std::move(finalizeCallback), finalizeHint});
2756+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2757+ napi_value value;
2758+ napi_status status = napi_create_external_buffer(
2759+ env,
2760+ length * sizeof(T),
2761+ data,
2762+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2763+ finalizeData,
2764+ &value);
2765+ if (status == details::napi_no_external_buffers_allowed) {
2766+#endif
2767+ // If we can't create an external buffer, we'll just copy the data.
2768+ Buffer<T> ret = Buffer<T>::Copy(env, data, length);
2769+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint(
2770+ env, data, finalizeData);
2771+ return ret;
2772+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2773+ }
2774+ if (status != napi_ok) {
2775+ delete finalizeData;
2776+ NAPI_THROW_IF_FAILED(env, status, Buffer());
2777+ }
2778+ return Buffer(env, value);
2779+#endif
2780+}
2781+
2782+template <typename T>
2783+inline Buffer<T> Buffer<T>::Copy(napi_env env, const T* data, size_t length) {
2784+ napi_value value;
2785+ napi_status status =
2786+ napi_create_buffer_copy(env, length * sizeof(T), data, nullptr, &value);
2787+ NAPI_THROW_IF_FAILED(env, status, Buffer<T>());
2788+ return Buffer<T>(env, value);
2789+}
2790+
2791+template <typename T>
2792+inline void Buffer<T>::CheckCast(napi_env env, napi_value value) {
2793+ NAPI_CHECK(value != nullptr, "Buffer::CheckCast", "empty value");
2794+
2795+ bool result;
2796+ napi_status status = napi_is_buffer(env, value, &result);
2797+ NAPI_CHECK(status == napi_ok, "Buffer::CheckCast", "napi_is_buffer failed");
2798+ NAPI_CHECK(result, "Buffer::CheckCast", "value is not buffer");
2799+}
2800+
2801+template <typename T>
2802+inline Buffer<T>::Buffer() : Uint8Array() {}
2803+
2804+template <typename T>
2805+inline Buffer<T>::Buffer(napi_env env, napi_value value)
2806+ : Uint8Array(env, value) {}
2807+
2808+template <typename T>
2809+inline size_t Buffer<T>::Length() const {
2810+ return ByteLength() / sizeof(T);
2811+}
2812+
2813+template <typename T>
2814+inline T* Buffer<T>::Data() const {
2815+ return reinterpret_cast<T*>(const_cast<uint8_t*>(Uint8Array::Data()));
2816+}
2817+
2818+////////////////////////////////////////////////////////////////////////////////
2819+// Error class
2820+////////////////////////////////////////////////////////////////////////////////
2821+
2822+inline Error Error::New(napi_env env) {
2823+ napi_status status;
2824+ napi_value error = nullptr;
2825+ bool is_exception_pending;
2826+ napi_extended_error_info last_error_info_copy;
2827+
2828+ {
2829+ // We must retrieve the last error info before doing anything else because
2830+ // doing anything else will replace the last error info.
2831+ const napi_extended_error_info* last_error_info;
2832+ status = napi_get_last_error_info(env, &last_error_info);
2833+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
2834+
2835+ // All fields of the `napi_extended_error_info` structure gets reset in
2836+ // subsequent Node-API function calls on the same `env`. This includes a
2837+ // call to `napi_is_exception_pending()`. So here it is necessary to make a
2838+ // copy of the information as the `error_code` field is used later on.
2839+ memcpy(&last_error_info_copy,
2840+ last_error_info,
2841+ sizeof(napi_extended_error_info));
2842+ }
2843+
2844+ status = napi_is_exception_pending(env, &is_exception_pending);
2845+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
2846+
2847+ // A pending exception takes precedence over any internal error status.
2848+ if (is_exception_pending) {
2849+ status = napi_get_and_clear_last_exception(env, &error);
2850+ NAPI_FATAL_IF_FAILED(
2851+ status, "Error::New", "napi_get_and_clear_last_exception");
2852+ } else {
2853+ const char* error_message = last_error_info_copy.error_message != nullptr
2854+ ? last_error_info_copy.error_message
2855+ : "Error in native callback";
2856+
2857+ napi_value message;
2858+ status = napi_create_string_utf8(
2859+ env, error_message, std::strlen(error_message), &message);
2860+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_string_utf8");
2861+
2862+ switch (last_error_info_copy.error_code) {
2863+ case napi_object_expected:
2864+ case napi_string_expected:
2865+ case napi_boolean_expected:
2866+ case napi_number_expected:
2867+ status = napi_create_type_error(env, nullptr, message, &error);
2868+ break;
2869+ default:
2870+ status = napi_create_error(env, nullptr, message, &error);
2871+ break;
2872+ }
2873+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_error");
2874+ }
2875+
2876+ return Error(env, error);
2877+}
2878+
2879+inline Error Error::New(napi_env env, const char* message) {
2880+ return Error::New<Error>(
2881+ env, message, std::strlen(message), napi_create_error);
2882+}
2883+
2884+inline Error Error::New(napi_env env, const std::string& message) {
2885+ return Error::New<Error>(
2886+ env, message.c_str(), message.size(), napi_create_error);
2887+}
2888+
2889+inline NAPI_NO_RETURN void Error::Fatal(const char* location,
2890+ const char* message) {
2891+ napi_fatal_error(location, NAPI_AUTO_LENGTH, message, NAPI_AUTO_LENGTH);
2892+}
2893+
2894+inline Error::Error() : ObjectReference() {}
2895+
2896+inline Error::Error(napi_env env, napi_value value)
2897+ : ObjectReference(env, nullptr) {
2898+ if (value != nullptr) {
2899+ // Attempting to create a reference on the error object.
2900+ // If it's not a Object/Function/Symbol, this call will return an error
2901+ // status.
2902+ napi_status status = napi_create_reference(env, value, 1, &_ref);
2903+
2904+ if (status != napi_ok) {
2905+ napi_value wrappedErrorObj;
2906+
2907+ // Create an error object
2908+ status = napi_create_object(env, &wrappedErrorObj);
2909+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_create_object");
2910+
2911+ // property flag that we attach to show the error object is wrapped
2912+ napi_property_descriptor wrapObjFlag = {
2913+ ERROR_WRAP_VALUE(), // Unique GUID identifier since Symbol isn't a
2914+ // viable option
2915+ nullptr,
2916+ nullptr,
2917+ nullptr,
2918+ nullptr,
2919+ Value::From(env, value),
2920+ napi_enumerable,
2921+ nullptr};
2922+
2923+ status = napi_define_properties(env, wrappedErrorObj, 1, &wrapObjFlag);
2924+#ifdef NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
2925+ if (status == napi_pending_exception) {
2926+ // Test if the pending exception was reported because the environment is
2927+ // shutting down. We assume that a status of napi_pending_exception
2928+ // coupled with the absence of an actual pending exception means that
2929+ // the environment is shutting down. If so, we replace the
2930+ // napi_pending_exception status with napi_ok.
2931+ bool is_exception_pending = false;
2932+ status = napi_is_exception_pending(env, &is_exception_pending);
2933+ if (status == napi_ok && !is_exception_pending) {
2934+ status = napi_ok;
2935+ } else {
2936+ status = napi_pending_exception;
2937+ }
2938+ }
2939+#endif // NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
2940+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_define_properties");
2941+
2942+ // Create a reference on the newly wrapped object
2943+ status = napi_create_reference(env, wrappedErrorObj, 1, &_ref);
2944+ }
2945+
2946+ // Avoid infinite recursion in the failure case.
2947+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_create_reference");
2948+ }
2949+}
2950+
2951+inline Object Error::Value() const {
2952+ if (_ref == nullptr) {
2953+ return Object(_env, nullptr);
2954+ }
2955+
2956+ napi_value refValue;
2957+ napi_status status = napi_get_reference_value(_env, _ref, &refValue);
2958+ NAPI_THROW_IF_FAILED(_env, status, Object());
2959+
2960+ napi_valuetype type;
2961+ status = napi_typeof(_env, refValue, &type);
2962+ NAPI_THROW_IF_FAILED(_env, status, Object());
2963+
2964+ // If refValue isn't a symbol, then we proceed to whether the refValue has the
2965+ // wrapped error flag
2966+ if (type != napi_symbol) {
2967+ // We are checking if the object is wrapped
2968+ bool isWrappedObject = false;
2969+
2970+ status = napi_has_property(_env,
2971+ refValue,
2972+ String::From(_env, ERROR_WRAP_VALUE()),
2973+ &isWrappedObject);
2974+
2975+ // Don't care about status
2976+ if (isWrappedObject) {
2977+ napi_value unwrappedValue;
2978+ status = napi_get_property(_env,
2979+ refValue,
2980+ String::From(_env, ERROR_WRAP_VALUE()),
2981+ &unwrappedValue);
2982+ NAPI_THROW_IF_FAILED(_env, status, Object());
2983+
2984+ return Object(_env, unwrappedValue);
2985+ }
2986+ }
2987+
2988+ return Object(_env, refValue);
2989+}
2990+
2991+inline Error::Error(Error&& other) : ObjectReference(std::move(other)) {}
2992+
2993+inline Error& Error::operator=(Error&& other) {
2994+ static_cast<Reference<Object>*>(this)->operator=(std::move(other));
2995+ return *this;
2996+}
2997+
2998+inline Error::Error(const Error& other) : ObjectReference(other) {}
2999+
3000+inline Error& Error::operator=(const Error& other) {
3001+ Reset();
3002+
3003+ _env = other.Env();
3004+ HandleScope scope(_env);
3005+
3006+ napi_value value = other.Value();
3007+ if (value != nullptr) {
3008+ napi_status status = napi_create_reference(_env, value, 1, &_ref);
3009+ NAPI_THROW_IF_FAILED(_env, status, *this);
3010+ }
3011+
3012+ return *this;
3013+}
3014+
3015+inline const std::string& Error::Message() const NAPI_NOEXCEPT {
3016+ if (_message.size() == 0 && _env != nullptr) {
3017+#ifdef NAPI_CPP_EXCEPTIONS
3018+ try {
3019+ _message = Get("message").As<String>();
3020+ } catch (...) {
3021+ // Catch all errors here, to include e.g. a std::bad_alloc from
3022+ // the std::string::operator=, because this method may not throw.
3023+ }
3024+#else // NAPI_CPP_EXCEPTIONS
3025+#if defined(NODE_ADDON_API_ENABLE_MAYBE)
3026+ Napi::Value message_val;
3027+ if (Get("message").UnwrapTo(&message_val)) {
3028+ _message = message_val.As<String>();
3029+ }
3030+#else
3031+ _message = Get("message").As<String>();
3032+#endif
3033+#endif // NAPI_CPP_EXCEPTIONS
3034+ }
3035+ return _message;
3036+}
3037+
3038+// we created an object on the &_ref
3039+inline void Error::ThrowAsJavaScriptException() const {
3040+ HandleScope scope(_env);
3041+ if (!IsEmpty()) {
3042+#ifdef NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
3043+ bool pendingException = false;
3044+
3045+ // check if there is already a pending exception. If so don't try to throw a
3046+ // new one as that is not allowed/possible
3047+ napi_status status = napi_is_exception_pending(_env, &pendingException);
3048+
3049+ if ((status != napi_ok) ||
3050+ ((status == napi_ok) && (pendingException == false))) {
3051+ // We intentionally don't use `NAPI_THROW_*` macros here to ensure
3052+ // that there is no possible recursion as `ThrowAsJavaScriptException`
3053+ // is part of `NAPI_THROW_*` macro definition for noexcept.
3054+
3055+ status = napi_throw(_env, Value());
3056+
3057+ if (status == napi_pending_exception) {
3058+ // The environment must be terminating as we checked earlier and there
3059+ // was no pending exception. In this case continuing will result
3060+ // in a fatal error and there is nothing the author has done incorrectly
3061+ // in their code that is worth flagging through a fatal error
3062+ return;
3063+ }
3064+ } else {
3065+ status = napi_pending_exception;
3066+ }
3067+#else
3068+ // We intentionally don't use `NAPI_THROW_*` macros here to ensure
3069+ // that there is no possible recursion as `ThrowAsJavaScriptException`
3070+ // is part of `NAPI_THROW_*` macro definition for noexcept.
3071+
3072+ napi_status status = napi_throw(_env, Value());
3073+#endif
3074+
3075+#ifdef NAPI_CPP_EXCEPTIONS
3076+ if (status != napi_ok) {
3077+ throw Error::New(_env);
3078+ }
3079+#else // NAPI_CPP_EXCEPTIONS
3080+ NAPI_FATAL_IF_FAILED(
3081+ status, "Error::ThrowAsJavaScriptException", "napi_throw");
3082+#endif // NAPI_CPP_EXCEPTIONS
3083+ }
3084+}
3085+
3086+#ifdef NAPI_CPP_EXCEPTIONS
3087+
3088+inline const char* Error::what() const NAPI_NOEXCEPT {
3089+ return Message().c_str();
3090+}
3091+
3092+#endif // NAPI_CPP_EXCEPTIONS
3093+
3094+inline const char* Error::ERROR_WRAP_VALUE() NAPI_NOEXCEPT {
3095+ return "4bda9e7e-4913-4dbc-95de-891cbf66598e-errorVal";
3096+}
3097+
3098+template <typename TError>
3099+inline TError Error::New(napi_env env,
3100+ const char* message,
3101+ size_t length,
3102+ create_error_fn create_error) {
3103+ napi_value str;
3104+ napi_status status = napi_create_string_utf8(env, message, length, &str);
3105+ NAPI_THROW_IF_FAILED(env, status, TError());
3106+
3107+ napi_value error;
3108+ status = create_error(env, nullptr, str, &error);
3109+ NAPI_THROW_IF_FAILED(env, status, TError());
3110+
3111+ return TError(env, error);
3112+}
3113+
3114+inline TypeError TypeError::New(napi_env env, const char* message) {
3115+ return Error::New<TypeError>(
3116+ env, message, std::strlen(message), napi_create_type_error);
3117+}
3118+
3119+inline TypeError TypeError::New(napi_env env, const std::string& message) {
3120+ return Error::New<TypeError>(
3121+ env, message.c_str(), message.size(), napi_create_type_error);
3122+}
3123+
3124+inline TypeError::TypeError() : Error() {}
3125+
3126+inline TypeError::TypeError(napi_env env, napi_value value)
3127+ : Error(env, value) {}
3128+
3129+inline RangeError RangeError::New(napi_env env, const char* message) {
3130+ return Error::New<RangeError>(
3131+ env, message, std::strlen(message), napi_create_range_error);
3132+}
3133+
3134+inline RangeError RangeError::New(napi_env env, const std::string& message) {
3135+ return Error::New<RangeError>(
3136+ env, message.c_str(), message.size(), napi_create_range_error);
3137+}
3138+
3139+inline RangeError::RangeError() : Error() {}
3140+
3141+inline RangeError::RangeError(napi_env env, napi_value value)
3142+ : Error(env, value) {}
3143+
3144+#if NAPI_VERSION > 8
3145+inline SyntaxError SyntaxError::New(napi_env env, const char* message) {
3146+ return Error::New<SyntaxError>(
3147+ env, message, std::strlen(message), node_api_create_syntax_error);
3148+}
3149+
3150+inline SyntaxError SyntaxError::New(napi_env env, const std::string& message) {
3151+ return Error::New<SyntaxError>(
3152+ env, message.c_str(), message.size(), node_api_create_syntax_error);
3153+}
3154+
3155+inline SyntaxError::SyntaxError() : Error() {}
3156+
3157+inline SyntaxError::SyntaxError(napi_env env, napi_value value)
3158+ : Error(env, value) {}
3159+#endif // NAPI_VERSION > 8
3160+
3161+////////////////////////////////////////////////////////////////////////////////
3162+// Reference<T> class
3163+////////////////////////////////////////////////////////////////////////////////
3164+
3165+template <typename T>
3166+inline Reference<T> Reference<T>::New(const T& value,
3167+ uint32_t initialRefcount) {
3168+ napi_env env = value.Env();
3169+ napi_value val = value;
3170+
3171+ if (val == nullptr) {
3172+ return Reference<T>(env, nullptr);
3173+ }
3174+
3175+ napi_ref ref;
3176+ napi_status status = napi_create_reference(env, value, initialRefcount, &ref);
3177+ NAPI_THROW_IF_FAILED(env, status, Reference<T>());
3178+
3179+ return Reference<T>(env, ref);
3180+}
3181+
3182+template <typename T>
3183+inline Reference<T>::Reference()
3184+ : _env(nullptr), _ref(nullptr), _suppressDestruct(false) {}
3185+
3186+template <typename T>
3187+inline Reference<T>::Reference(napi_env env, napi_ref ref)
3188+ : _env(env), _ref(ref), _suppressDestruct(false) {}
3189+
3190+template <typename T>
3191+inline Reference<T>::~Reference() {
3192+ if (_ref != nullptr) {
3193+ if (!_suppressDestruct) {
3194+ napi_delete_reference(_env, _ref);
3195+ }
3196+
3197+ _ref = nullptr;
3198+ }
3199+}
3200+
3201+template <typename T>
3202+inline Reference<T>::Reference(Reference<T>&& other)
3203+ : _env(other._env),
3204+ _ref(other._ref),
3205+ _suppressDestruct(other._suppressDestruct) {
3206+ other._env = nullptr;
3207+ other._ref = nullptr;
3208+ other._suppressDestruct = false;
3209+}
3210+
3211+template <typename T>
3212+inline Reference<T>& Reference<T>::operator=(Reference<T>&& other) {
3213+ Reset();
3214+ _env = other._env;
3215+ _ref = other._ref;
3216+ _suppressDestruct = other._suppressDestruct;
3217+ other._env = nullptr;
3218+ other._ref = nullptr;
3219+ other._suppressDestruct = false;
3220+ return *this;
3221+}
3222+
3223+template <typename T>
3224+inline Reference<T>::Reference(const Reference<T>& other)
3225+ : _env(other._env), _ref(nullptr), _suppressDestruct(false) {
3226+ HandleScope scope(_env);
3227+
3228+ napi_value value = other.Value();
3229+ if (value != nullptr) {
3230+ // Copying is a limited scenario (currently only used for Error object) and
3231+ // always creates a strong reference to the given value even if the incoming
3232+ // reference is weak.
3233+ napi_status status = napi_create_reference(_env, value, 1, &_ref);
3234+ NAPI_FATAL_IF_FAILED(
3235+ status, "Reference<T>::Reference", "napi_create_reference");
3236+ }
3237+}
3238+
3239+template <typename T>
3240+inline Reference<T>::operator napi_ref() const {
3241+ return _ref;
3242+}
3243+
3244+template <typename T>
3245+inline bool Reference<T>::operator==(const Reference<T>& other) const {
3246+ HandleScope scope(_env);
3247+ return this->Value().StrictEquals(other.Value());
3248+}
3249+
3250+template <typename T>
3251+inline bool Reference<T>::operator!=(const Reference<T>& other) const {
3252+ return !this->operator==(other);
3253+}
3254+
3255+template <typename T>
3256+inline Napi::Env Reference<T>::Env() const {
3257+ return Napi::Env(_env);
3258+}
3259+
3260+template <typename T>
3261+inline bool Reference<T>::IsEmpty() const {
3262+ return _ref == nullptr;
3263+}
3264+
3265+template <typename T>
3266+inline T Reference<T>::Value() const {
3267+ if (_ref == nullptr) {
3268+ return T(_env, nullptr);
3269+ }
3270+
3271+ napi_value value;
3272+ napi_status status = napi_get_reference_value(_env, _ref, &value);
3273+ NAPI_THROW_IF_FAILED(_env, status, T());
3274+ return T(_env, value);
3275+}
3276+
3277+template <typename T>
3278+inline uint32_t Reference<T>::Ref() const {
3279+ uint32_t result;
3280+ napi_status status = napi_reference_ref(_env, _ref, &result);
3281+ NAPI_THROW_IF_FAILED(_env, status, 0);
3282+ return result;
3283+}
3284+
3285+template <typename T>
3286+inline uint32_t Reference<T>::Unref() const {
3287+ uint32_t result;
3288+ napi_status status = napi_reference_unref(_env, _ref, &result);
3289+ NAPI_THROW_IF_FAILED(_env, status, 0);
3290+ return result;
3291+}
3292+
3293+template <typename T>
3294+inline void Reference<T>::Reset() {
3295+ if (_ref != nullptr) {
3296+ napi_status status = napi_delete_reference(_env, _ref);
3297+ NAPI_THROW_IF_FAILED_VOID(_env, status);
3298+ _ref = nullptr;
3299+ }
3300+}
3301+
3302+template <typename T>
3303+inline void Reference<T>::Reset(const T& value, uint32_t refcount) {
3304+ Reset();
3305+ _env = value.Env();
3306+
3307+ napi_value val = value;
3308+ if (val != nullptr) {
3309+ napi_status status = napi_create_reference(_env, value, refcount, &_ref);
3310+ NAPI_THROW_IF_FAILED_VOID(_env, status);
3311+ }
3312+}
3313+
3314+template <typename T>
3315+inline void Reference<T>::SuppressDestruct() {
3316+ _suppressDestruct = true;
3317+}
3318+
3319+template <typename T>
3320+inline Reference<T> Weak(T value) {
3321+ return Reference<T>::New(value, 0);
3322+}
3323+
3324+inline ObjectReference Weak(Object value) {
3325+ return Reference<Object>::New(value, 0);
3326+}
3327+
3328+inline FunctionReference Weak(Function value) {
3329+ return Reference<Function>::New(value, 0);
3330+}
3331+
3332+template <typename T>
3333+inline Reference<T> Persistent(T value) {
3334+ return Reference<T>::New(value, 1);
3335+}
3336+
3337+inline ObjectReference Persistent(Object value) {
3338+ return Reference<Object>::New(value, 1);
3339+}
3340+
3341+inline FunctionReference Persistent(Function value) {
3342+ return Reference<Function>::New(value, 1);
3343+}
3344+
3345+////////////////////////////////////////////////////////////////////////////////
3346+// ObjectReference class
3347+////////////////////////////////////////////////////////////////////////////////
3348+
3349+inline ObjectReference::ObjectReference() : Reference<Object>() {}
3350+
3351+inline ObjectReference::ObjectReference(napi_env env, napi_ref ref)
3352+ : Reference<Object>(env, ref) {}
3353+
3354+inline ObjectReference::ObjectReference(Reference<Object>&& other)
3355+ : Reference<Object>(std::move(other)) {}
3356+
3357+inline ObjectReference& ObjectReference::operator=(Reference<Object>&& other) {
3358+ static_cast<Reference<Object>*>(this)->operator=(std::move(other));
3359+ return *this;
3360+}
3361+
3362+inline ObjectReference::ObjectReference(ObjectReference&& other)
3363+ : Reference<Object>(std::move(other)) {}
3364+
3365+inline ObjectReference& ObjectReference::operator=(ObjectReference&& other) {
3366+ static_cast<Reference<Object>*>(this)->operator=(std::move(other));
3367+ return *this;
3368+}
3369+
3370+inline ObjectReference::ObjectReference(const ObjectReference& other)
3371+ : Reference<Object>(other) {}
3372+
3373+inline MaybeOrValue<Napi::Value> ObjectReference::Get(
3374+ const char* utf8name) const {
3375+ EscapableHandleScope scope(_env);
3376+ MaybeOrValue<Napi::Value> result = Value().Get(utf8name);
3377+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3378+ if (result.IsJust()) {
3379+ return Just(scope.Escape(result.Unwrap()));
3380+ }
3381+ return result;
3382+#else
3383+ if (scope.Env().IsExceptionPending()) {
3384+ return Value();
3385+ }
3386+ return scope.Escape(result);
3387+#endif
3388+}
3389+
3390+inline MaybeOrValue<Napi::Value> ObjectReference::Get(
3391+ const std::string& utf8name) const {
3392+ EscapableHandleScope scope(_env);
3393+ MaybeOrValue<Napi::Value> result = Value().Get(utf8name);
3394+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3395+ if (result.IsJust()) {
3396+ return Just(scope.Escape(result.Unwrap()));
3397+ }
3398+ return result;
3399+#else
3400+ if (scope.Env().IsExceptionPending()) {
3401+ return Value();
3402+ }
3403+ return scope.Escape(result);
3404+#endif
3405+}
3406+
3407+inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3408+ napi_value value) const {
3409+ HandleScope scope(_env);
3410+ return Value().Set(utf8name, value);
3411+}
3412+
3413+inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3414+ Napi::Value value) const {
3415+ HandleScope scope(_env);
3416+ return Value().Set(utf8name, value);
3417+}
3418+
3419+inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3420+ const char* utf8value) const {
3421+ HandleScope scope(_env);
3422+ return Value().Set(utf8name, utf8value);
3423+}
3424+
3425+inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3426+ bool boolValue) const {
3427+ HandleScope scope(_env);
3428+ return Value().Set(utf8name, boolValue);
3429+}
3430+
3431+inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3432+ double numberValue) const {
3433+ HandleScope scope(_env);
3434+ return Value().Set(utf8name, numberValue);
3435+}
3436+
3437+inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3438+ napi_value value) const {
3439+ HandleScope scope(_env);
3440+ return Value().Set(utf8name, value);
3441+}
3442+
3443+inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3444+ Napi::Value value) const {
3445+ HandleScope scope(_env);
3446+ return Value().Set(utf8name, value);
3447+}
3448+
3449+inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3450+ std::string& utf8value) const {
3451+ HandleScope scope(_env);
3452+ return Value().Set(utf8name, utf8value);
3453+}
3454+
3455+inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3456+ bool boolValue) const {
3457+ HandleScope scope(_env);
3458+ return Value().Set(utf8name, boolValue);
3459+}
3460+
3461+inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3462+ double numberValue) const {
3463+ HandleScope scope(_env);
3464+ return Value().Set(utf8name, numberValue);
3465+}
3466+
3467+inline MaybeOrValue<Napi::Value> ObjectReference::Get(uint32_t index) const {
3468+ EscapableHandleScope scope(_env);
3469+ MaybeOrValue<Napi::Value> result = Value().Get(index);
3470+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3471+ if (result.IsJust()) {
3472+ return Just(scope.Escape(result.Unwrap()));
3473+ }
3474+ return result;
3475+#else
3476+ if (scope.Env().IsExceptionPending()) {
3477+ return Value();
3478+ }
3479+ return scope.Escape(result);
3480+#endif
3481+}
3482+
3483+inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3484+ napi_value value) const {
3485+ HandleScope scope(_env);
3486+ return Value().Set(index, value);
3487+}
3488+
3489+inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3490+ Napi::Value value) const {
3491+ HandleScope scope(_env);
3492+ return Value().Set(index, value);
3493+}
3494+
3495+inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3496+ const char* utf8value) const {
3497+ HandleScope scope(_env);
3498+ return Value().Set(index, utf8value);
3499+}
3500+
3501+inline MaybeOrValue<bool> ObjectReference::Set(
3502+ uint32_t index, const std::string& utf8value) const {
3503+ HandleScope scope(_env);
3504+ return Value().Set(index, utf8value);
3505+}
3506+
3507+inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3508+ bool boolValue) const {
3509+ HandleScope scope(_env);
3510+ return Value().Set(index, boolValue);
3511+}
3512+
3513+inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3514+ double numberValue) const {
3515+ HandleScope scope(_env);
3516+ return Value().Set(index, numberValue);
3517+}
3518+
3519+////////////////////////////////////////////////////////////////////////////////
3520+// FunctionReference class
3521+////////////////////////////////////////////////////////////////////////////////
3522+
3523+inline FunctionReference::FunctionReference() : Reference<Function>() {}
3524+
3525+inline FunctionReference::FunctionReference(napi_env env, napi_ref ref)
3526+ : Reference<Function>(env, ref) {}
3527+
3528+inline FunctionReference::FunctionReference(Reference<Function>&& other)
3529+ : Reference<Function>(std::move(other)) {}
3530+
3531+inline FunctionReference& FunctionReference::operator=(
3532+ Reference<Function>&& other) {
3533+ static_cast<Reference<Function>*>(this)->operator=(std::move(other));
3534+ return *this;
3535+}
3536+
3537+inline FunctionReference::FunctionReference(FunctionReference&& other)
3538+ : Reference<Function>(std::move(other)) {}
3539+
3540+inline FunctionReference& FunctionReference::operator=(
3541+ FunctionReference&& other) {
3542+ static_cast<Reference<Function>*>(this)->operator=(std::move(other));
3543+ return *this;
3544+}
3545+
3546+inline MaybeOrValue<Napi::Value> FunctionReference::operator()(
3547+ const std::initializer_list<napi_value>& args) const {
3548+ EscapableHandleScope scope(_env);
3549+ MaybeOrValue<Napi::Value> result = Value()(args);
3550+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3551+ if (result.IsJust()) {
3552+ return Just(scope.Escape(result.Unwrap()));
3553+ }
3554+ return result;
3555+#else
3556+ if (scope.Env().IsExceptionPending()) {
3557+ return Value();
3558+ }
3559+ return scope.Escape(result);
3560+#endif
3561+}
3562+
3563+inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3564+ const std::initializer_list<napi_value>& args) const {
3565+ EscapableHandleScope scope(_env);
3566+ MaybeOrValue<Napi::Value> result = Value().Call(args);
3567+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3568+ if (result.IsJust()) {
3569+ return Just(scope.Escape(result.Unwrap()));
3570+ }
3571+ return result;
3572+#else
3573+ if (scope.Env().IsExceptionPending()) {
3574+ return Value();
3575+ }
3576+ return scope.Escape(result);
3577+#endif
3578+}
3579+
3580+inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3581+ const std::vector<napi_value>& args) const {
3582+ EscapableHandleScope scope(_env);
3583+ MaybeOrValue<Napi::Value> result = Value().Call(args);
3584+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3585+ if (result.IsJust()) {
3586+ return Just(scope.Escape(result.Unwrap()));
3587+ }
3588+ return result;
3589+#else
3590+ if (scope.Env().IsExceptionPending()) {
3591+ return Value();
3592+ }
3593+ return scope.Escape(result);
3594+#endif
3595+}
3596+
3597+inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3598+ napi_value recv, const std::initializer_list<napi_value>& args) const {
3599+ EscapableHandleScope scope(_env);
3600+ MaybeOrValue<Napi::Value> result = Value().Call(recv, args);
3601+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3602+ if (result.IsJust()) {
3603+ return Just(scope.Escape(result.Unwrap()));
3604+ }
3605+ return result;
3606+#else
3607+ if (scope.Env().IsExceptionPending()) {
3608+ return Value();
3609+ }
3610+ return scope.Escape(result);
3611+#endif
3612+}
3613+
3614+inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3615+ napi_value recv, const std::vector<napi_value>& args) const {
3616+ EscapableHandleScope scope(_env);
3617+ MaybeOrValue<Napi::Value> result = Value().Call(recv, args);
3618+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3619+ if (result.IsJust()) {
3620+ return Just(scope.Escape(result.Unwrap()));
3621+ }
3622+ return result;
3623+#else
3624+ if (scope.Env().IsExceptionPending()) {
3625+ return Value();
3626+ }
3627+ return scope.Escape(result);
3628+#endif
3629+}
3630+
3631+inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3632+ napi_value recv, size_t argc, const napi_value* args) const {
3633+ EscapableHandleScope scope(_env);
3634+ MaybeOrValue<Napi::Value> result = Value().Call(recv, argc, args);
3635+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3636+ if (result.IsJust()) {
3637+ return Just(scope.Escape(result.Unwrap()));
3638+ }
3639+ return result;
3640+#else
3641+ if (scope.Env().IsExceptionPending()) {
3642+ return Value();
3643+ }
3644+ return scope.Escape(result);
3645+#endif
3646+}
3647+
3648+inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
3649+ napi_value recv,
3650+ const std::initializer_list<napi_value>& args,
3651+ napi_async_context context) const {
3652+ EscapableHandleScope scope(_env);
3653+ MaybeOrValue<Napi::Value> result = Value().MakeCallback(recv, args, context);
3654+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3655+ if (result.IsJust()) {
3656+ return Just(scope.Escape(result.Unwrap()));
3657+ }
3658+
3659+ return result;
3660+#else
3661+ if (scope.Env().IsExceptionPending()) {
3662+ return Value();
3663+ }
3664+ return scope.Escape(result);
3665+#endif
3666+}
3667+
3668+inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
3669+ napi_value recv,
3670+ const std::vector<napi_value>& args,
3671+ napi_async_context context) const {
3672+ EscapableHandleScope scope(_env);
3673+ MaybeOrValue<Napi::Value> result = Value().MakeCallback(recv, args, context);
3674+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3675+ if (result.IsJust()) {
3676+ return Just(scope.Escape(result.Unwrap()));
3677+ }
3678+ return result;
3679+#else
3680+ if (scope.Env().IsExceptionPending()) {
3681+ return Value();
3682+ }
3683+ return scope.Escape(result);
3684+#endif
3685+}
3686+
3687+inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
3688+ napi_value recv,
3689+ size_t argc,
3690+ const napi_value* args,
3691+ napi_async_context context) const {
3692+ EscapableHandleScope scope(_env);
3693+ MaybeOrValue<Napi::Value> result =
3694+ Value().MakeCallback(recv, argc, args, context);
3695+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3696+ if (result.IsJust()) {
3697+ return Just(scope.Escape(result.Unwrap()));
3698+ }
3699+ return result;
3700+#else
3701+ if (scope.Env().IsExceptionPending()) {
3702+ return Value();
3703+ }
3704+ return scope.Escape(result);
3705+#endif
3706+}
3707+
3708+inline MaybeOrValue<Object> FunctionReference::New(
3709+ const std::initializer_list<napi_value>& args) const {
3710+ EscapableHandleScope scope(_env);
3711+ MaybeOrValue<Object> result = Value().New(args);
3712+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3713+ if (result.IsJust()) {
3714+ return Just(scope.Escape(result.Unwrap()).As<Object>());
3715+ }
3716+ return result;
3717+#else
3718+ if (scope.Env().IsExceptionPending()) {
3719+ return Object();
3720+ }
3721+ return scope.Escape(result).As<Object>();
3722+#endif
3723+}
3724+
3725+inline MaybeOrValue<Object> FunctionReference::New(
3726+ const std::vector<napi_value>& args) const {
3727+ EscapableHandleScope scope(_env);
3728+ MaybeOrValue<Object> result = Value().New(args);
3729+#ifdef NODE_ADDON_API_ENABLE_MAYBE
3730+ if (result.IsJust()) {
3731+ return Just(scope.Escape(result.Unwrap()).As<Object>());
3732+ }
3733+ return result;
3734+#else
3735+ if (scope.Env().IsExceptionPending()) {
3736+ return Object();
3737+ }
3738+ return scope.Escape(result).As<Object>();
3739+#endif
3740+}
3741+
3742+////////////////////////////////////////////////////////////////////////////////
3743+// CallbackInfo class
3744+////////////////////////////////////////////////////////////////////////////////
3745+
3746+inline CallbackInfo::CallbackInfo(napi_env env, napi_callback_info info)
3747+ : _env(env),
3748+ _info(info),
3749+ _this(nullptr),
3750+ _dynamicArgs(nullptr),
3751+ _data(nullptr) {
3752+ _argc = _staticArgCount;
3753+ _argv = _staticArgs;
3754+ napi_status status =
3755+ napi_get_cb_info(env, info, &_argc, _argv, &_this, &_data);
3756+ NAPI_THROW_IF_FAILED_VOID(_env, status);
3757+
3758+ if (_argc > _staticArgCount) {
3759+ // Use either a fixed-size array (on the stack) or a dynamically-allocated
3760+ // array (on the heap) depending on the number of args.
3761+ _dynamicArgs = new napi_value[_argc];
3762+ _argv = _dynamicArgs;
3763+
3764+ status = napi_get_cb_info(env, info, &_argc, _argv, nullptr, nullptr);
3765+ NAPI_THROW_IF_FAILED_VOID(_env, status);
3766+ }
3767+}
3768+
3769+inline CallbackInfo::~CallbackInfo() {
3770+ if (_dynamicArgs != nullptr) {
3771+ delete[] _dynamicArgs;
3772+ }
3773+}
3774+
3775+inline CallbackInfo::operator napi_callback_info() const {
3776+ return _info;
3777+}
3778+
3779+inline Value CallbackInfo::NewTarget() const {
3780+ napi_value newTarget;
3781+ napi_status status = napi_get_new_target(_env, _info, &newTarget);
3782+ NAPI_THROW_IF_FAILED(_env, status, Value());
3783+ return Value(_env, newTarget);
3784+}
3785+
3786+inline bool CallbackInfo::IsConstructCall() const {
3787+ return !NewTarget().IsEmpty();
3788+}
3789+
3790+inline Napi::Env CallbackInfo::Env() const {
3791+ return Napi::Env(_env);
3792+}
3793+
3794+inline size_t CallbackInfo::Length() const {
3795+ return _argc;
3796+}
3797+
3798+inline const Value CallbackInfo::operator[](size_t index) const {
3799+ return index < _argc ? Value(_env, _argv[index]) : Env().Undefined();
3800+}
3801+
3802+inline Value CallbackInfo::This() const {
3803+ if (_this == nullptr) {
3804+ return Env().Undefined();
3805+ }
3806+ return Object(_env, _this);
3807+}
3808+
3809+inline void* CallbackInfo::Data() const {
3810+ return _data;
3811+}
3812+
3813+inline void CallbackInfo::SetData(void* data) {
3814+ _data = data;
3815+}
3816+
3817+////////////////////////////////////////////////////////////////////////////////
3818+// PropertyDescriptor class
3819+////////////////////////////////////////////////////////////////////////////////
3820+
3821+template <typename PropertyDescriptor::GetterCallback Getter>
3822+PropertyDescriptor PropertyDescriptor::Accessor(
3823+ const char* utf8name, napi_property_attributes attributes, void* data) {
3824+ napi_property_descriptor desc = napi_property_descriptor();
3825+
3826+ desc.utf8name = utf8name;
3827+ desc.getter = details::TemplatedCallback<Getter>;
3828+ desc.attributes = attributes;
3829+ desc.data = data;
3830+
3831+ return desc;
3832+}
3833+
3834+template <typename PropertyDescriptor::GetterCallback Getter>
3835+PropertyDescriptor PropertyDescriptor::Accessor(
3836+ const std::string& utf8name,
3837+ napi_property_attributes attributes,
3838+ void* data) {
3839+ return Accessor<Getter>(utf8name.c_str(), attributes, data);
3840+}
3841+
3842+template <typename PropertyDescriptor::GetterCallback Getter>
3843+PropertyDescriptor PropertyDescriptor::Accessor(
3844+ Name name, napi_property_attributes attributes, void* data) {
3845+ napi_property_descriptor desc = napi_property_descriptor();
3846+
3847+ desc.name = name;
3848+ desc.getter = details::TemplatedCallback<Getter>;
3849+ desc.attributes = attributes;
3850+ desc.data = data;
3851+
3852+ return desc;
3853+}
3854+
3855+template <typename PropertyDescriptor::GetterCallback Getter,
3856+ typename PropertyDescriptor::SetterCallback Setter>
3857+PropertyDescriptor PropertyDescriptor::Accessor(
3858+ const char* utf8name, napi_property_attributes attributes, void* data) {
3859+ napi_property_descriptor desc = napi_property_descriptor();
3860+
3861+ desc.utf8name = utf8name;
3862+ desc.getter = details::TemplatedCallback<Getter>;
3863+ desc.setter = details::TemplatedVoidCallback<Setter>;
3864+ desc.attributes = attributes;
3865+ desc.data = data;
3866+
3867+ return desc;
3868+}
3869+
3870+template <typename PropertyDescriptor::GetterCallback Getter,
3871+ typename PropertyDescriptor::SetterCallback Setter>
3872+PropertyDescriptor PropertyDescriptor::Accessor(
3873+ const std::string& utf8name,
3874+ napi_property_attributes attributes,
3875+ void* data) {
3876+ return Accessor<Getter, Setter>(utf8name.c_str(), attributes, data);
3877+}
3878+
3879+template <typename PropertyDescriptor::GetterCallback Getter,
3880+ typename PropertyDescriptor::SetterCallback Setter>
3881+PropertyDescriptor PropertyDescriptor::Accessor(
3882+ Name name, napi_property_attributes attributes, void* data) {
3883+ napi_property_descriptor desc = napi_property_descriptor();
3884+
3885+ desc.name = name;
3886+ desc.getter = details::TemplatedCallback<Getter>;
3887+ desc.setter = details::TemplatedVoidCallback<Setter>;
3888+ desc.attributes = attributes;
3889+ desc.data = data;
3890+
3891+ return desc;
3892+}
3893+
3894+template <typename Getter>
3895+inline PropertyDescriptor PropertyDescriptor::Accessor(
3896+ Napi::Env env,
3897+ Napi::Object object,
3898+ const char* utf8name,
3899+ Getter getter,
3900+ napi_property_attributes attributes,
3901+ void* data) {
3902+ using CbData = details::CallbackData<Getter, Napi::Value>;
3903+ auto callbackData = new CbData({getter, data});
3904+
3905+ napi_status status = AttachData(env, object, callbackData);
3906+ if (status != napi_ok) {
3907+ delete callbackData;
3908+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
3909+ }
3910+
3911+ return PropertyDescriptor({utf8name,
3912+ nullptr,
3913+ nullptr,
3914+ CbData::Wrapper,
3915+ nullptr,
3916+ nullptr,
3917+ attributes,
3918+ callbackData});
3919+}
3920+
3921+template <typename Getter>
3922+inline PropertyDescriptor PropertyDescriptor::Accessor(
3923+ Napi::Env env,
3924+ Napi::Object object,
3925+ const std::string& utf8name,
3926+ Getter getter,
3927+ napi_property_attributes attributes,
3928+ void* data) {
3929+ return Accessor(env, object, utf8name.c_str(), getter, attributes, data);
3930+}
3931+
3932+template <typename Getter>
3933+inline PropertyDescriptor PropertyDescriptor::Accessor(
3934+ Napi::Env env,
3935+ Napi::Object object,
3936+ Name name,
3937+ Getter getter,
3938+ napi_property_attributes attributes,
3939+ void* data) {
3940+ using CbData = details::CallbackData<Getter, Napi::Value>;
3941+ auto callbackData = new CbData({getter, data});
3942+
3943+ napi_status status = AttachData(env, object, callbackData);
3944+ if (status != napi_ok) {
3945+ delete callbackData;
3946+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
3947+ }
3948+
3949+ return PropertyDescriptor({nullptr,
3950+ name,
3951+ nullptr,
3952+ CbData::Wrapper,
3953+ nullptr,
3954+ nullptr,
3955+ attributes,
3956+ callbackData});
3957+}
3958+
3959+template <typename Getter, typename Setter>
3960+inline PropertyDescriptor PropertyDescriptor::Accessor(
3961+ Napi::Env env,
3962+ Napi::Object object,
3963+ const char* utf8name,
3964+ Getter getter,
3965+ Setter setter,
3966+ napi_property_attributes attributes,
3967+ void* data) {
3968+ using CbData = details::AccessorCallbackData<Getter, Setter>;
3969+ auto callbackData = new CbData({getter, setter, data});
3970+
3971+ napi_status status = AttachData(env, object, callbackData);
3972+ if (status != napi_ok) {
3973+ delete callbackData;
3974+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
3975+ }
3976+
3977+ return PropertyDescriptor({utf8name,
3978+ nullptr,
3979+ nullptr,
3980+ CbData::GetterWrapper,
3981+ CbData::SetterWrapper,
3982+ nullptr,
3983+ attributes,
3984+ callbackData});
3985+}
3986+
3987+template <typename Getter, typename Setter>
3988+inline PropertyDescriptor PropertyDescriptor::Accessor(
3989+ Napi::Env env,
3990+ Napi::Object object,
3991+ const std::string& utf8name,
3992+ Getter getter,
3993+ Setter setter,
3994+ napi_property_attributes attributes,
3995+ void* data) {
3996+ return Accessor(
3997+ env, object, utf8name.c_str(), getter, setter, attributes, data);
3998+}
3999+
4000+template <typename Getter, typename Setter>
4001+inline PropertyDescriptor PropertyDescriptor::Accessor(
4002+ Napi::Env env,
4003+ Napi::Object object,
4004+ Name name,
4005+ Getter getter,
4006+ Setter setter,
4007+ napi_property_attributes attributes,
4008+ void* data) {
4009+ using CbData = details::AccessorCallbackData<Getter, Setter>;
4010+ auto callbackData = new CbData({getter, setter, data});
4011+
4012+ napi_status status = AttachData(env, object, callbackData);
4013+ if (status != napi_ok) {
4014+ delete callbackData;
4015+ NAPI_THROW_IF_FAILED(env, status, napi_property_descriptor());
4016+ }
4017+
4018+ return PropertyDescriptor({nullptr,
4019+ name,
4020+ nullptr,
4021+ CbData::GetterWrapper,
4022+ CbData::SetterWrapper,
4023+ nullptr,
4024+ attributes,
4025+ callbackData});
4026+}
4027+
4028+template <typename Callable>
4029+inline PropertyDescriptor PropertyDescriptor::Function(
4030+ Napi::Env env,
4031+ Napi::Object /*object*/,
4032+ const char* utf8name,
4033+ Callable cb,
4034+ napi_property_attributes attributes,
4035+ void* data) {
4036+ return PropertyDescriptor({utf8name,
4037+ nullptr,
4038+ nullptr,
4039+ nullptr,
4040+ nullptr,
4041+ Napi::Function::New(env, cb, utf8name, data),
4042+ attributes,
4043+ nullptr});
4044+}
4045+
4046+template <typename Callable>
4047+inline PropertyDescriptor PropertyDescriptor::Function(
4048+ Napi::Env env,
4049+ Napi::Object object,
4050+ const std::string& utf8name,
4051+ Callable cb,
4052+ napi_property_attributes attributes,
4053+ void* data) {
4054+ return Function(env, object, utf8name.c_str(), cb, attributes, data);
4055+}
4056+
4057+template <typename Callable>
4058+inline PropertyDescriptor PropertyDescriptor::Function(
4059+ Napi::Env env,
4060+ Napi::Object /*object*/,
4061+ Name name,
4062+ Callable cb,
4063+ napi_property_attributes attributes,
4064+ void* data) {
4065+ return PropertyDescriptor({nullptr,
4066+ name,
4067+ nullptr,
4068+ nullptr,
4069+ nullptr,
4070+ Napi::Function::New(env, cb, nullptr, data),
4071+ attributes,
4072+ nullptr});
4073+}
4074+
4075+inline PropertyDescriptor PropertyDescriptor::Value(
4076+ const char* utf8name,
4077+ napi_value value,
4078+ napi_property_attributes attributes) {
4079+ return PropertyDescriptor({utf8name,
4080+ nullptr,
4081+ nullptr,
4082+ nullptr,
4083+ nullptr,
4084+ value,
4085+ attributes,
4086+ nullptr});
4087+}
4088+
4089+inline PropertyDescriptor PropertyDescriptor::Value(
4090+ const std::string& utf8name,
4091+ napi_value value,
4092+ napi_property_attributes attributes) {
4093+ return Value(utf8name.c_str(), value, attributes);
4094+}
4095+
4096+inline PropertyDescriptor PropertyDescriptor::Value(
4097+ napi_value name, napi_value value, napi_property_attributes attributes) {
4098+ return PropertyDescriptor(
4099+ {nullptr, name, nullptr, nullptr, nullptr, value, attributes, nullptr});
4100+}
4101+
4102+inline PropertyDescriptor PropertyDescriptor::Value(
4103+ Name name, Napi::Value value, napi_property_attributes attributes) {
4104+ napi_value nameValue = name;
4105+ napi_value valueValue = value;
4106+ return PropertyDescriptor::Value(nameValue, valueValue, attributes);
4107+}
4108+
4109+inline PropertyDescriptor::PropertyDescriptor(napi_property_descriptor desc)
4110+ : _desc(desc) {}
4111+
4112+inline PropertyDescriptor::operator napi_property_descriptor&() {
4113+ return _desc;
4114+}
4115+
4116+inline PropertyDescriptor::operator const napi_property_descriptor&() const {
4117+ return _desc;
4118+}
4119+
4120+////////////////////////////////////////////////////////////////////////////////
4121+// InstanceWrap<T> class
4122+////////////////////////////////////////////////////////////////////////////////
4123+
4124+template <typename T>
4125+inline void InstanceWrap<T>::AttachPropData(
4126+ napi_env env, napi_value value, const napi_property_descriptor* prop) {
4127+ napi_status status;
4128+ if (!(prop->attributes & napi_static)) {
4129+ if (prop->method == T::InstanceVoidMethodCallbackWrapper) {
4130+ status = Napi::details::AttachData(
4131+ env, value, static_cast<InstanceVoidMethodCallbackData*>(prop->data));
4132+ NAPI_THROW_IF_FAILED_VOID(env, status);
4133+ } else if (prop->method == T::InstanceMethodCallbackWrapper) {
4134+ status = Napi::details::AttachData(
4135+ env, value, static_cast<InstanceMethodCallbackData*>(prop->data));
4136+ NAPI_THROW_IF_FAILED_VOID(env, status);
4137+ } else if (prop->getter == T::InstanceGetterCallbackWrapper ||
4138+ prop->setter == T::InstanceSetterCallbackWrapper) {
4139+ status = Napi::details::AttachData(
4140+ env, value, static_cast<InstanceAccessorCallbackData*>(prop->data));
4141+ NAPI_THROW_IF_FAILED_VOID(env, status);
4142+ }
4143+ }
4144+}
4145+
4146+template <typename T>
4147+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4148+ const char* utf8name,
4149+ InstanceVoidMethodCallback method,
4150+ napi_property_attributes attributes,
4151+ void* data) {
4152+ InstanceVoidMethodCallbackData* callbackData =
4153+ new InstanceVoidMethodCallbackData({method, data});
4154+
4155+ napi_property_descriptor desc = napi_property_descriptor();
4156+ desc.utf8name = utf8name;
4157+ desc.method = T::InstanceVoidMethodCallbackWrapper;
4158+ desc.data = callbackData;
4159+ desc.attributes = attributes;
4160+ return desc;
4161+}
4162+
4163+template <typename T>
4164+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4165+ const char* utf8name,
4166+ InstanceMethodCallback method,
4167+ napi_property_attributes attributes,
4168+ void* data) {
4169+ InstanceMethodCallbackData* callbackData =
4170+ new InstanceMethodCallbackData({method, data});
4171+
4172+ napi_property_descriptor desc = napi_property_descriptor();
4173+ desc.utf8name = utf8name;
4174+ desc.method = T::InstanceMethodCallbackWrapper;
4175+ desc.data = callbackData;
4176+ desc.attributes = attributes;
4177+ return desc;
4178+}
4179+
4180+template <typename T>
4181+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4182+ Symbol name,
4183+ InstanceVoidMethodCallback method,
4184+ napi_property_attributes attributes,
4185+ void* data) {
4186+ InstanceVoidMethodCallbackData* callbackData =
4187+ new InstanceVoidMethodCallbackData({method, data});
4188+
4189+ napi_property_descriptor desc = napi_property_descriptor();
4190+ desc.name = name;
4191+ desc.method = T::InstanceVoidMethodCallbackWrapper;
4192+ desc.data = callbackData;
4193+ desc.attributes = attributes;
4194+ return desc;
4195+}
4196+
4197+template <typename T>
4198+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4199+ Symbol name,
4200+ InstanceMethodCallback method,
4201+ napi_property_attributes attributes,
4202+ void* data) {
4203+ InstanceMethodCallbackData* callbackData =
4204+ new InstanceMethodCallbackData({method, data});
4205+
4206+ napi_property_descriptor desc = napi_property_descriptor();
4207+ desc.name = name;
4208+ desc.method = T::InstanceMethodCallbackWrapper;
4209+ desc.data = callbackData;
4210+ desc.attributes = attributes;
4211+ return desc;
4212+}
4213+
4214+template <typename T>
4215+template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
4216+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4217+ const char* utf8name, napi_property_attributes attributes, void* data) {
4218+ napi_property_descriptor desc = napi_property_descriptor();
4219+ desc.utf8name = utf8name;
4220+ desc.method = details::TemplatedInstanceVoidCallback<T, method>;
4221+ desc.data = data;
4222+ desc.attributes = attributes;
4223+ return desc;
4224+}
4225+
4226+template <typename T>
4227+template <typename InstanceWrap<T>::InstanceMethodCallback method>
4228+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4229+ const char* utf8name, napi_property_attributes attributes, void* data) {
4230+ napi_property_descriptor desc = napi_property_descriptor();
4231+ desc.utf8name = utf8name;
4232+ desc.method = details::TemplatedInstanceCallback<T, method>;
4233+ desc.data = data;
4234+ desc.attributes = attributes;
4235+ return desc;
4236+}
4237+
4238+template <typename T>
4239+template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
4240+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4241+ Symbol name, napi_property_attributes attributes, void* data) {
4242+ napi_property_descriptor desc = napi_property_descriptor();
4243+ desc.name = name;
4244+ desc.method = details::TemplatedInstanceVoidCallback<T, method>;
4245+ desc.data = data;
4246+ desc.attributes = attributes;
4247+ return desc;
4248+}
4249+
4250+template <typename T>
4251+template <typename InstanceWrap<T>::InstanceMethodCallback method>
4252+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
4253+ Symbol name, napi_property_attributes attributes, void* data) {
4254+ napi_property_descriptor desc = napi_property_descriptor();
4255+ desc.name = name;
4256+ desc.method = details::TemplatedInstanceCallback<T, method>;
4257+ desc.data = data;
4258+ desc.attributes = attributes;
4259+ return desc;
4260+}
4261+
4262+template <typename T>
4263+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
4264+ const char* utf8name,
4265+ InstanceGetterCallback getter,
4266+ InstanceSetterCallback setter,
4267+ napi_property_attributes attributes,
4268+ void* data) {
4269+ InstanceAccessorCallbackData* callbackData =
4270+ new InstanceAccessorCallbackData({getter, setter, data});
4271+
4272+ napi_property_descriptor desc = napi_property_descriptor();
4273+ desc.utf8name = utf8name;
4274+ desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
4275+ desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
4276+ desc.data = callbackData;
4277+ desc.attributes = attributes;
4278+ return desc;
4279+}
4280+
4281+template <typename T>
4282+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
4283+ Symbol name,
4284+ InstanceGetterCallback getter,
4285+ InstanceSetterCallback setter,
4286+ napi_property_attributes attributes,
4287+ void* data) {
4288+ InstanceAccessorCallbackData* callbackData =
4289+ new InstanceAccessorCallbackData({getter, setter, data});
4290+
4291+ napi_property_descriptor desc = napi_property_descriptor();
4292+ desc.name = name;
4293+ desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
4294+ desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
4295+ desc.data = callbackData;
4296+ desc.attributes = attributes;
4297+ return desc;
4298+}
4299+
4300+template <typename T>
4301+template <typename InstanceWrap<T>::InstanceGetterCallback getter,
4302+ typename InstanceWrap<T>::InstanceSetterCallback setter>
4303+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
4304+ const char* utf8name, napi_property_attributes attributes, void* data) {
4305+ napi_property_descriptor desc = napi_property_descriptor();
4306+ desc.utf8name = utf8name;
4307+ desc.getter = details::TemplatedInstanceCallback<T, getter>;
4308+ desc.setter = This::WrapSetter(This::SetterTag<setter>());
4309+ desc.data = data;
4310+ desc.attributes = attributes;
4311+ return desc;
4312+}
4313+
4314+template <typename T>
4315+template <typename InstanceWrap<T>::InstanceGetterCallback getter,
4316+ typename InstanceWrap<T>::InstanceSetterCallback setter>
4317+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
4318+ Symbol name, napi_property_attributes attributes, void* data) {
4319+ napi_property_descriptor desc = napi_property_descriptor();
4320+ desc.name = name;
4321+ desc.getter = details::TemplatedInstanceCallback<T, getter>;
4322+ desc.setter = This::WrapSetter(This::SetterTag<setter>());
4323+ desc.data = data;
4324+ desc.attributes = attributes;
4325+ return desc;
4326+}
4327+
4328+template <typename T>
4329+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
4330+ const char* utf8name,
4331+ Napi::Value value,
4332+ napi_property_attributes attributes) {
4333+ napi_property_descriptor desc = napi_property_descriptor();
4334+ desc.utf8name = utf8name;
4335+ desc.value = value;
4336+ desc.attributes = attributes;
4337+ return desc;
4338+}
4339+
4340+template <typename T>
4341+inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
4342+ Symbol name, Napi::Value value, napi_property_attributes attributes) {
4343+ napi_property_descriptor desc = napi_property_descriptor();
4344+ desc.name = name;
4345+ desc.value = value;
4346+ desc.attributes = attributes;
4347+ return desc;
4348+}
4349+
4350+template <typename T>
4351+inline napi_value InstanceWrap<T>::InstanceVoidMethodCallbackWrapper(
4352+ napi_env env, napi_callback_info info) {
4353+ return details::WrapCallback([&] {
4354+ CallbackInfo callbackInfo(env, info);
4355+ InstanceVoidMethodCallbackData* callbackData =
4356+ reinterpret_cast<InstanceVoidMethodCallbackData*>(callbackInfo.Data());
4357+ callbackInfo.SetData(callbackData->data);
4358+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4359+ auto cb = callbackData->callback;
4360+ if (instance) (instance->*cb)(callbackInfo);
4361+ return nullptr;
4362+ });
4363+}
4364+
4365+template <typename T>
4366+inline napi_value InstanceWrap<T>::InstanceMethodCallbackWrapper(
4367+ napi_env env, napi_callback_info info) {
4368+ return details::WrapCallback([&] {
4369+ CallbackInfo callbackInfo(env, info);
4370+ InstanceMethodCallbackData* callbackData =
4371+ reinterpret_cast<InstanceMethodCallbackData*>(callbackInfo.Data());
4372+ callbackInfo.SetData(callbackData->data);
4373+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4374+ auto cb = callbackData->callback;
4375+ return instance ? (instance->*cb)(callbackInfo) : Napi::Value();
4376+ });
4377+}
4378+
4379+template <typename T>
4380+inline napi_value InstanceWrap<T>::InstanceGetterCallbackWrapper(
4381+ napi_env env, napi_callback_info info) {
4382+ return details::WrapCallback([&] {
4383+ CallbackInfo callbackInfo(env, info);
4384+ InstanceAccessorCallbackData* callbackData =
4385+ reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
4386+ callbackInfo.SetData(callbackData->data);
4387+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4388+ auto cb = callbackData->getterCallback;
4389+ return instance ? (instance->*cb)(callbackInfo) : Napi::Value();
4390+ });
4391+}
4392+
4393+template <typename T>
4394+inline napi_value InstanceWrap<T>::InstanceSetterCallbackWrapper(
4395+ napi_env env, napi_callback_info info) {
4396+ return details::WrapCallback([&] {
4397+ CallbackInfo callbackInfo(env, info);
4398+ InstanceAccessorCallbackData* callbackData =
4399+ reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
4400+ callbackInfo.SetData(callbackData->data);
4401+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4402+ auto cb = callbackData->setterCallback;
4403+ if (instance) (instance->*cb)(callbackInfo, callbackInfo[0]);
4404+ return nullptr;
4405+ });
4406+}
4407+
4408+template <typename T>
4409+template <typename InstanceWrap<T>::InstanceSetterCallback method>
4410+inline napi_value InstanceWrap<T>::WrappedMethod(
4411+ napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
4412+ return details::WrapCallback([&] {
4413+ const CallbackInfo cbInfo(env, info);
4414+ T* instance = T::Unwrap(cbInfo.This().As<Object>());
4415+ if (instance) (instance->*method)(cbInfo, cbInfo[0]);
4416+ return nullptr;
4417+ });
4418+}
4419+
4420+////////////////////////////////////////////////////////////////////////////////
4421+// ObjectWrap<T> class
4422+////////////////////////////////////////////////////////////////////////////////
4423+
4424+template <typename T>
4425+inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4426+ napi_env env = callbackInfo.Env();
4427+ napi_value wrapper = callbackInfo.This();
4428+ napi_status status;
4429+ napi_ref ref;
4430+ T* instance = static_cast<T*>(this);
4431+ status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
4432+ NAPI_THROW_IF_FAILED_VOID(env, status);
4433+
4434+ Reference<Object>* instanceRef = instance;
4435+ *instanceRef = Reference<Object>(env, ref);
4436+}
4437+
4438+template <typename T>
4439+inline ObjectWrap<T>::~ObjectWrap() {
4440+ // If the JS object still exists at this point, remove the finalizer added
4441+ // through `napi_wrap()`.
4442+ if (!IsEmpty()) {
4443+ Object object = Value();
4444+ // It is not valid to call `napi_remove_wrap()` with an empty `object`.
4445+ // This happens e.g. during garbage collection.
4446+ if (!object.IsEmpty() && _construction_failed) {
4447+ napi_remove_wrap(Env(), object, nullptr);
4448+ }
4449+ }
4450+}
4451+
4452+template <typename T>
4453+inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
4454+ void* unwrapped;
4455+ napi_status status = napi_unwrap(wrapper.Env(), wrapper, &unwrapped);
4456+ NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
4457+ return static_cast<T*>(unwrapped);
4458+}
4459+
4460+template <typename T>
4461+inline Function ObjectWrap<T>::DefineClass(
4462+ Napi::Env env,
4463+ const char* utf8name,
4464+ const size_t props_count,
4465+ const napi_property_descriptor* descriptors,
4466+ void* data) {
4467+ napi_status status;
4468+ std::vector<napi_property_descriptor> props(props_count);
4469+
4470+ // We copy the descriptors to a local array because before defining the class
4471+ // we must replace static method property descriptors with value property
4472+ // descriptors such that the value is a function-valued `napi_value` created
4473+ // with `CreateFunction()`.
4474+ //
4475+ // This replacement could be made for instance methods as well, but V8 aborts
4476+ // if we do that, because it expects methods defined on the prototype template
4477+ // to have `FunctionTemplate`s.
4478+ for (size_t index = 0; index < props_count; index++) {
4479+ props[index] = descriptors[index];
4480+ napi_property_descriptor* prop = &props[index];
4481+ if (prop->method == T::StaticMethodCallbackWrapper) {
4482+ status =
4483+ CreateFunction(env,
4484+ utf8name,
4485+ prop->method,
4486+ static_cast<StaticMethodCallbackData*>(prop->data),
4487+ &(prop->value));
4488+ NAPI_THROW_IF_FAILED(env, status, Function());
4489+ prop->method = nullptr;
4490+ prop->data = nullptr;
4491+ } else if (prop->method == T::StaticVoidMethodCallbackWrapper) {
4492+ status =
4493+ CreateFunction(env,
4494+ utf8name,
4495+ prop->method,
4496+ static_cast<StaticVoidMethodCallbackData*>(prop->data),
4497+ &(prop->value));
4498+ NAPI_THROW_IF_FAILED(env, status, Function());
4499+ prop->method = nullptr;
4500+ prop->data = nullptr;
4501+ }
4502+ }
4503+
4504+ napi_value value;
4505+ status = napi_define_class(env,
4506+ utf8name,
4507+ NAPI_AUTO_LENGTH,
4508+ T::ConstructorCallbackWrapper,
4509+ data,
4510+ props_count,
4511+ props.data(),
4512+ &value);
4513+ NAPI_THROW_IF_FAILED(env, status, Function());
4514+
4515+ // After defining the class we iterate once more over the property descriptors
4516+ // and attach the data associated with accessors and instance methods to the
4517+ // newly created JavaScript class.
4518+ for (size_t idx = 0; idx < props_count; idx++) {
4519+ const napi_property_descriptor* prop = &props[idx];
4520+
4521+ if (prop->getter == T::StaticGetterCallbackWrapper ||
4522+ prop->setter == T::StaticSetterCallbackWrapper) {
4523+ status = Napi::details::AttachData(
4524+ env, value, static_cast<StaticAccessorCallbackData*>(prop->data));
4525+ NAPI_THROW_IF_FAILED(env, status, Function());
4526+ } else {
4527+ // InstanceWrap<T>::AttachPropData is responsible for attaching the data
4528+ // of instance methods and accessors.
4529+ T::AttachPropData(env, value, prop);
4530+ }
4531+ }
4532+
4533+ return Function(env, value);
4534+}
4535+
4536+template <typename T>
4537+inline Function ObjectWrap<T>::DefineClass(
4538+ Napi::Env env,
4539+ const char* utf8name,
4540+ const std::initializer_list<ClassPropertyDescriptor<T>>& properties,
4541+ void* data) {
4542+ return DefineClass(
4543+ env,
4544+ utf8name,
4545+ properties.size(),
4546+ reinterpret_cast<const napi_property_descriptor*>(properties.begin()),
4547+ data);
4548+}
4549+
4550+template <typename T>
4551+inline Function ObjectWrap<T>::DefineClass(
4552+ Napi::Env env,
4553+ const char* utf8name,
4554+ const std::vector<ClassPropertyDescriptor<T>>& properties,
4555+ void* data) {
4556+ return DefineClass(
4557+ env,
4558+ utf8name,
4559+ properties.size(),
4560+ reinterpret_cast<const napi_property_descriptor*>(properties.data()),
4561+ data);
4562+}
4563+
4564+template <typename T>
4565+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4566+ const char* utf8name,
4567+ StaticVoidMethodCallback method,
4568+ napi_property_attributes attributes,
4569+ void* data) {
4570+ StaticVoidMethodCallbackData* callbackData =
4571+ new StaticVoidMethodCallbackData({method, data});
4572+
4573+ napi_property_descriptor desc = napi_property_descriptor();
4574+ desc.utf8name = utf8name;
4575+ desc.method = T::StaticVoidMethodCallbackWrapper;
4576+ desc.data = callbackData;
4577+ desc.attributes =
4578+ static_cast<napi_property_attributes>(attributes | napi_static);
4579+ return desc;
4580+}
4581+
4582+template <typename T>
4583+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4584+ const char* utf8name,
4585+ StaticMethodCallback method,
4586+ napi_property_attributes attributes,
4587+ void* data) {
4588+ StaticMethodCallbackData* callbackData =
4589+ new StaticMethodCallbackData({method, data});
4590+
4591+ napi_property_descriptor desc = napi_property_descriptor();
4592+ desc.utf8name = utf8name;
4593+ desc.method = T::StaticMethodCallbackWrapper;
4594+ desc.data = callbackData;
4595+ desc.attributes =
4596+ static_cast<napi_property_attributes>(attributes | napi_static);
4597+ return desc;
4598+}
4599+
4600+template <typename T>
4601+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4602+ Symbol name,
4603+ StaticVoidMethodCallback method,
4604+ napi_property_attributes attributes,
4605+ void* data) {
4606+ StaticVoidMethodCallbackData* callbackData =
4607+ new StaticVoidMethodCallbackData({method, data});
4608+
4609+ napi_property_descriptor desc = napi_property_descriptor();
4610+ desc.name = name;
4611+ desc.method = T::StaticVoidMethodCallbackWrapper;
4612+ desc.data = callbackData;
4613+ desc.attributes =
4614+ static_cast<napi_property_attributes>(attributes | napi_static);
4615+ return desc;
4616+}
4617+
4618+template <typename T>
4619+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4620+ Symbol name,
4621+ StaticMethodCallback method,
4622+ napi_property_attributes attributes,
4623+ void* data) {
4624+ StaticMethodCallbackData* callbackData =
4625+ new StaticMethodCallbackData({method, data});
4626+
4627+ napi_property_descriptor desc = napi_property_descriptor();
4628+ desc.name = name;
4629+ desc.method = T::StaticMethodCallbackWrapper;
4630+ desc.data = callbackData;
4631+ desc.attributes =
4632+ static_cast<napi_property_attributes>(attributes | napi_static);
4633+ return desc;
4634+}
4635+
4636+template <typename T>
4637+template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
4638+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4639+ const char* utf8name, napi_property_attributes attributes, void* data) {
4640+ napi_property_descriptor desc = napi_property_descriptor();
4641+ desc.utf8name = utf8name;
4642+ desc.method = details::TemplatedVoidCallback<method>;
4643+ desc.data = data;
4644+ desc.attributes =
4645+ static_cast<napi_property_attributes>(attributes | napi_static);
4646+ return desc;
4647+}
4648+
4649+template <typename T>
4650+template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
4651+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4652+ Symbol name, napi_property_attributes attributes, void* data) {
4653+ napi_property_descriptor desc = napi_property_descriptor();
4654+ desc.name = name;
4655+ desc.method = details::TemplatedVoidCallback<method>;
4656+ desc.data = data;
4657+ desc.attributes =
4658+ static_cast<napi_property_attributes>(attributes | napi_static);
4659+ return desc;
4660+}
4661+
4662+template <typename T>
4663+template <typename ObjectWrap<T>::StaticMethodCallback method>
4664+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4665+ const char* utf8name, napi_property_attributes attributes, void* data) {
4666+ napi_property_descriptor desc = napi_property_descriptor();
4667+ desc.utf8name = utf8name;
4668+ desc.method = details::TemplatedCallback<method>;
4669+ desc.data = data;
4670+ desc.attributes =
4671+ static_cast<napi_property_attributes>(attributes | napi_static);
4672+ return desc;
4673+}
4674+
4675+template <typename T>
4676+template <typename ObjectWrap<T>::StaticMethodCallback method>
4677+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4678+ Symbol name, napi_property_attributes attributes, void* data) {
4679+ napi_property_descriptor desc = napi_property_descriptor();
4680+ desc.name = name;
4681+ desc.method = details::TemplatedCallback<method>;
4682+ desc.data = data;
4683+ desc.attributes =
4684+ static_cast<napi_property_attributes>(attributes | napi_static);
4685+ return desc;
4686+}
4687+
4688+template <typename T>
4689+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4690+ const char* utf8name,
4691+ StaticGetterCallback getter,
4692+ StaticSetterCallback setter,
4693+ napi_property_attributes attributes,
4694+ void* data) {
4695+ StaticAccessorCallbackData* callbackData =
4696+ new StaticAccessorCallbackData({getter, setter, data});
4697+
4698+ napi_property_descriptor desc = napi_property_descriptor();
4699+ desc.utf8name = utf8name;
4700+ desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
4701+ desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
4702+ desc.data = callbackData;
4703+ desc.attributes =
4704+ static_cast<napi_property_attributes>(attributes | napi_static);
4705+ return desc;
4706+}
4707+
4708+template <typename T>
4709+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4710+ Symbol name,
4711+ StaticGetterCallback getter,
4712+ StaticSetterCallback setter,
4713+ napi_property_attributes attributes,
4714+ void* data) {
4715+ StaticAccessorCallbackData* callbackData =
4716+ new StaticAccessorCallbackData({getter, setter, data});
4717+
4718+ napi_property_descriptor desc = napi_property_descriptor();
4719+ desc.name = name;
4720+ desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
4721+ desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
4722+ desc.data = callbackData;
4723+ desc.attributes =
4724+ static_cast<napi_property_attributes>(attributes | napi_static);
4725+ return desc;
4726+}
4727+
4728+template <typename T>
4729+template <typename ObjectWrap<T>::StaticGetterCallback getter,
4730+ typename ObjectWrap<T>::StaticSetterCallback setter>
4731+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4732+ const char* utf8name, napi_property_attributes attributes, void* data) {
4733+ napi_property_descriptor desc = napi_property_descriptor();
4734+ desc.utf8name = utf8name;
4735+ desc.getter = details::TemplatedCallback<getter>;
4736+ desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
4737+ desc.data = data;
4738+ desc.attributes =
4739+ static_cast<napi_property_attributes>(attributes | napi_static);
4740+ return desc;
4741+}
4742+
4743+template <typename T>
4744+template <typename ObjectWrap<T>::StaticGetterCallback getter,
4745+ typename ObjectWrap<T>::StaticSetterCallback setter>
4746+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4747+ Symbol name, napi_property_attributes attributes, void* data) {
4748+ napi_property_descriptor desc = napi_property_descriptor();
4749+ desc.name = name;
4750+ desc.getter = details::TemplatedCallback<getter>;
4751+ desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
4752+ desc.data = data;
4753+ desc.attributes =
4754+ static_cast<napi_property_attributes>(attributes | napi_static);
4755+ return desc;
4756+}
4757+
4758+template <typename T>
4759+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticValue(
4760+ const char* utf8name,
4761+ Napi::Value value,
4762+ napi_property_attributes attributes) {
4763+ napi_property_descriptor desc = napi_property_descriptor();
4764+ desc.utf8name = utf8name;
4765+ desc.value = value;
4766+ desc.attributes =
4767+ static_cast<napi_property_attributes>(attributes | napi_static);
4768+ return desc;
4769+}
4770+
4771+template <typename T>
4772+inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticValue(
4773+ Symbol name, Napi::Value value, napi_property_attributes attributes) {
4774+ napi_property_descriptor desc = napi_property_descriptor();
4775+ desc.name = name;
4776+ desc.value = value;
4777+ desc.attributes =
4778+ static_cast<napi_property_attributes>(attributes | napi_static);
4779+ return desc;
4780+}
4781+
4782+template <typename T>
4783+inline Value ObjectWrap<T>::OnCalledAsFunction(
4784+ const Napi::CallbackInfo& callbackInfo) {
4785+ NAPI_THROW(
4786+ TypeError::New(callbackInfo.Env(),
4787+ "Class constructors cannot be invoked without 'new'"),
4788+ Napi::Value());
4789+}
4790+
4791+template <typename T>
4792+inline void ObjectWrap<T>::Finalize(Napi::Env /*env*/) {}
4793+
4794+template <typename T>
4795+inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
4796+ napi_env env, napi_callback_info info) {
4797+ napi_value new_target;
4798+ napi_status status = napi_get_new_target(env, info, &new_target);
4799+ if (status != napi_ok) return nullptr;
4800+
4801+ bool isConstructCall = (new_target != nullptr);
4802+ if (!isConstructCall) {
4803+ return details::WrapCallback(
4804+ [&] { return T::OnCalledAsFunction(CallbackInfo(env, info)); });
4805+ }
4806+
4807+ napi_value wrapper = details::WrapCallback([&] {
4808+ CallbackInfo callbackInfo(env, info);
4809+ T* instance = new T(callbackInfo);
4810+#ifdef NAPI_CPP_EXCEPTIONS
4811+ instance->_construction_failed = false;
4812+#else
4813+ if (callbackInfo.Env().IsExceptionPending()) {
4814+ // We need to clear the exception so that removing the wrap might work.
4815+ Error e = callbackInfo.Env().GetAndClearPendingException();
4816+ delete instance;
4817+ e.ThrowAsJavaScriptException();
4818+ } else {
4819+ instance->_construction_failed = false;
4820+ }
4821+#endif // NAPI_CPP_EXCEPTIONS
4822+ return callbackInfo.This();
4823+ });
4824+
4825+ return wrapper;
4826+}
4827+
4828+template <typename T>
4829+inline napi_value ObjectWrap<T>::StaticVoidMethodCallbackWrapper(
4830+ napi_env env, napi_callback_info info) {
4831+ return details::WrapCallback([&] {
4832+ CallbackInfo callbackInfo(env, info);
4833+ StaticVoidMethodCallbackData* callbackData =
4834+ reinterpret_cast<StaticVoidMethodCallbackData*>(callbackInfo.Data());
4835+ callbackInfo.SetData(callbackData->data);
4836+ callbackData->callback(callbackInfo);
4837+ return nullptr;
4838+ });
4839+}
4840+
4841+template <typename T>
4842+inline napi_value ObjectWrap<T>::StaticMethodCallbackWrapper(
4843+ napi_env env, napi_callback_info info) {
4844+ return details::WrapCallback([&] {
4845+ CallbackInfo callbackInfo(env, info);
4846+ StaticMethodCallbackData* callbackData =
4847+ reinterpret_cast<StaticMethodCallbackData*>(callbackInfo.Data());
4848+ callbackInfo.SetData(callbackData->data);
4849+ return callbackData->callback(callbackInfo);
4850+ });
4851+}
4852+
4853+template <typename T>
4854+inline napi_value ObjectWrap<T>::StaticGetterCallbackWrapper(
4855+ napi_env env, napi_callback_info info) {
4856+ return details::WrapCallback([&] {
4857+ CallbackInfo callbackInfo(env, info);
4858+ StaticAccessorCallbackData* callbackData =
4859+ reinterpret_cast<StaticAccessorCallbackData*>(callbackInfo.Data());
4860+ callbackInfo.SetData(callbackData->data);
4861+ return callbackData->getterCallback(callbackInfo);
4862+ });
4863+}
4864+
4865+template <typename T>
4866+inline napi_value ObjectWrap<T>::StaticSetterCallbackWrapper(
4867+ napi_env env, napi_callback_info info) {
4868+ return details::WrapCallback([&] {
4869+ CallbackInfo callbackInfo(env, info);
4870+ StaticAccessorCallbackData* callbackData =
4871+ reinterpret_cast<StaticAccessorCallbackData*>(callbackInfo.Data());
4872+ callbackInfo.SetData(callbackData->data);
4873+ callbackData->setterCallback(callbackInfo, callbackInfo[0]);
4874+ return nullptr;
4875+ });
4876+}
4877+
4878+template <typename T>
4879+inline void ObjectWrap<T>::FinalizeCallback(napi_env env,
4880+ void* data,
4881+ void* /*hint*/) {
4882+ HandleScope scope(env);
4883+ T* instance = static_cast<T*>(data);
4884+ instance->Finalize(Napi::Env(env));
4885+ delete instance;
4886+}
4887+
4888+template <typename T>
4889+template <typename ObjectWrap<T>::StaticSetterCallback method>
4890+inline napi_value ObjectWrap<T>::WrappedMethod(
4891+ napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
4892+ return details::WrapCallback([&] {
4893+ const CallbackInfo cbInfo(env, info);
4894+ method(cbInfo, cbInfo[0]);
4895+ return nullptr;
4896+ });
4897+}
4898+
4899+////////////////////////////////////////////////////////////////////////////////
4900+// HandleScope class
4901+////////////////////////////////////////////////////////////////////////////////
4902+
4903+inline HandleScope::HandleScope(napi_env env, napi_handle_scope scope)
4904+ : _env(env), _scope(scope) {}
4905+
4906+inline HandleScope::HandleScope(Napi::Env env) : _env(env) {
4907+ napi_status status = napi_open_handle_scope(_env, &_scope);
4908+ NAPI_THROW_IF_FAILED_VOID(_env, status);
4909+}
4910+
4911+inline HandleScope::~HandleScope() {
4912+ napi_status status = napi_close_handle_scope(_env, _scope);
4913+ NAPI_FATAL_IF_FAILED(
4914+ status, "HandleScope::~HandleScope", "napi_close_handle_scope");
4915+}
4916+
4917+inline HandleScope::operator napi_handle_scope() const {
4918+ return _scope;
4919+}
4920+
4921+inline Napi::Env HandleScope::Env() const {
4922+ return Napi::Env(_env);
4923+}
4924+
4925+////////////////////////////////////////////////////////////////////////////////
4926+// EscapableHandleScope class
4927+////////////////////////////////////////////////////////////////////////////////
4928+
4929+inline EscapableHandleScope::EscapableHandleScope(
4930+ napi_env env, napi_escapable_handle_scope scope)
4931+ : _env(env), _scope(scope) {}
4932+
4933+inline EscapableHandleScope::EscapableHandleScope(Napi::Env env) : _env(env) {
4934+ napi_status status = napi_open_escapable_handle_scope(_env, &_scope);
4935+ NAPI_THROW_IF_FAILED_VOID(_env, status);
4936+}
4937+
4938+inline EscapableHandleScope::~EscapableHandleScope() {
4939+ napi_status status = napi_close_escapable_handle_scope(_env, _scope);
4940+ NAPI_FATAL_IF_FAILED(status,
4941+ "EscapableHandleScope::~EscapableHandleScope",
4942+ "napi_close_escapable_handle_scope");
4943+}
4944+
4945+inline EscapableHandleScope::operator napi_escapable_handle_scope() const {
4946+ return _scope;
4947+}
4948+
4949+inline Napi::Env EscapableHandleScope::Env() const {
4950+ return Napi::Env(_env);
4951+}
4952+
4953+inline Value EscapableHandleScope::Escape(napi_value escapee) {
4954+ napi_value result;
4955+ napi_status status = napi_escape_handle(_env, _scope, escapee, &result);
4956+ NAPI_THROW_IF_FAILED(_env, status, Value());
4957+ return Value(_env, result);
4958+}
4959+
4960+#if (NAPI_VERSION > 2)
4961+////////////////////////////////////////////////////////////////////////////////
4962+// CallbackScope class
4963+////////////////////////////////////////////////////////////////////////////////
4964+
4965+inline CallbackScope::CallbackScope(napi_env env, napi_callback_scope scope)
4966+ : _env(env), _scope(scope) {}
4967+
4968+inline CallbackScope::CallbackScope(napi_env env, napi_async_context context)
4969+ : _env(env) {
4970+ napi_status status =
4971+ napi_open_callback_scope(_env, Object::New(env), context, &_scope);
4972+ NAPI_THROW_IF_FAILED_VOID(_env, status);
4973+}
4974+
4975+inline CallbackScope::~CallbackScope() {
4976+ napi_status status = napi_close_callback_scope(_env, _scope);
4977+ NAPI_FATAL_IF_FAILED(
4978+ status, "CallbackScope::~CallbackScope", "napi_close_callback_scope");
4979+}
4980+
4981+inline CallbackScope::operator napi_callback_scope() const {
4982+ return _scope;
4983+}
4984+
4985+inline Napi::Env CallbackScope::Env() const {
4986+ return Napi::Env(_env);
4987+}
4988+#endif
4989+
4990+////////////////////////////////////////////////////////////////////////////////
4991+// AsyncContext class
4992+////////////////////////////////////////////////////////////////////////////////
4993+
4994+inline AsyncContext::AsyncContext(napi_env env, const char* resource_name)
4995+ : AsyncContext(env, resource_name, Object::New(env)) {}
4996+
4997+inline AsyncContext::AsyncContext(napi_env env,
4998+ const char* resource_name,
4999+ const Object& resource)
5000+ : _env(env), _context(nullptr) {
5001+ napi_value resource_id;
5002+ napi_status status = napi_create_string_utf8(
5003+ _env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
5004+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5005+
5006+ status = napi_async_init(_env, resource, resource_id, &_context);
5007+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5008+}
5009+
5010+inline AsyncContext::~AsyncContext() {
5011+ if (_context != nullptr) {
5012+ napi_async_destroy(_env, _context);
5013+ _context = nullptr;
5014+ }
5015+}
5016+
5017+inline AsyncContext::AsyncContext(AsyncContext&& other) {
5018+ _env = other._env;
5019+ other._env = nullptr;
5020+ _context = other._context;
5021+ other._context = nullptr;
5022+}
5023+
5024+inline AsyncContext& AsyncContext::operator=(AsyncContext&& other) {
5025+ _env = other._env;
5026+ other._env = nullptr;
5027+ _context = other._context;
5028+ other._context = nullptr;
5029+ return *this;
5030+}
5031+
5032+inline AsyncContext::operator napi_async_context() const {
5033+ return _context;
5034+}
5035+
5036+inline Napi::Env AsyncContext::Env() const {
5037+ return Napi::Env(_env);
5038+}
5039+
5040+////////////////////////////////////////////////////////////////////////////////
5041+// AsyncWorker class
5042+////////////////////////////////////////////////////////////////////////////////
5043+
5044+#if NAPI_HAS_THREADS
5045+
5046+inline AsyncWorker::AsyncWorker(const Function& callback)
5047+ : AsyncWorker(callback, "generic") {}
5048+
5049+inline AsyncWorker::AsyncWorker(const Function& callback,
5050+ const char* resource_name)
5051+ : AsyncWorker(callback, resource_name, Object::New(callback.Env())) {}
5052+
5053+inline AsyncWorker::AsyncWorker(const Function& callback,
5054+ const char* resource_name,
5055+ const Object& resource)
5056+ : AsyncWorker(
5057+ Object::New(callback.Env()), callback, resource_name, resource) {}
5058+
5059+inline AsyncWorker::AsyncWorker(const Object& receiver,
5060+ const Function& callback)
5061+ : AsyncWorker(receiver, callback, "generic") {}
5062+
5063+inline AsyncWorker::AsyncWorker(const Object& receiver,
5064+ const Function& callback,
5065+ const char* resource_name)
5066+ : AsyncWorker(
5067+ receiver, callback, resource_name, Object::New(callback.Env())) {}
5068+
5069+inline AsyncWorker::AsyncWorker(const Object& receiver,
5070+ const Function& callback,
5071+ const char* resource_name,
5072+ const Object& resource)
5073+ : _env(callback.Env()),
5074+ _receiver(Napi::Persistent(receiver)),
5075+ _callback(Napi::Persistent(callback)),
5076+ _suppress_destruct(false) {
5077+ napi_value resource_id;
5078+ napi_status status = napi_create_string_latin1(
5079+ _env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
5080+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5081+
5082+ status = napi_create_async_work(_env,
5083+ resource,
5084+ resource_id,
5085+ OnAsyncWorkExecute,
5086+ OnAsyncWorkComplete,
5087+ this,
5088+ &_work);
5089+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5090+}
5091+
5092+inline AsyncWorker::AsyncWorker(Napi::Env env) : AsyncWorker(env, "generic") {}
5093+
5094+inline AsyncWorker::AsyncWorker(Napi::Env env, const char* resource_name)
5095+ : AsyncWorker(env, resource_name, Object::New(env)) {}
5096+
5097+inline AsyncWorker::AsyncWorker(Napi::Env env,
5098+ const char* resource_name,
5099+ const Object& resource)
5100+ : _env(env), _receiver(), _callback(), _suppress_destruct(false) {
5101+ napi_value resource_id;
5102+ napi_status status = napi_create_string_latin1(
5103+ _env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
5104+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5105+
5106+ status = napi_create_async_work(_env,
5107+ resource,
5108+ resource_id,
5109+ OnAsyncWorkExecute,
5110+ OnAsyncWorkComplete,
5111+ this,
5112+ &_work);
5113+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5114+}
5115+
5116+inline AsyncWorker::~AsyncWorker() {
5117+ if (_work != nullptr) {
5118+ napi_delete_async_work(_env, _work);
5119+ _work = nullptr;
5120+ }
5121+}
5122+
5123+inline void AsyncWorker::Destroy() {
5124+ delete this;
5125+}
5126+
5127+inline AsyncWorker::operator napi_async_work() const {
5128+ return _work;
5129+}
5130+
5131+inline Napi::Env AsyncWorker::Env() const {
5132+ return Napi::Env(_env);
5133+}
5134+
5135+inline void AsyncWorker::Queue() {
5136+ napi_status status = napi_queue_async_work(_env, _work);
5137+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5138+}
5139+
5140+inline void AsyncWorker::Cancel() {
5141+ napi_status status = napi_cancel_async_work(_env, _work);
5142+ NAPI_THROW_IF_FAILED_VOID(_env, status);
5143+}
5144+
5145+inline ObjectReference& AsyncWorker::Receiver() {
5146+ return _receiver;
5147+}
5148+
5149+inline FunctionReference& AsyncWorker::Callback() {
5150+ return _callback;
5151+}
5152+
5153+inline void AsyncWorker::SuppressDestruct() {
5154+ _suppress_destruct = true;
5155+}
5156+
5157+inline void AsyncWorker::OnOK() {
5158+ if (!_callback.IsEmpty()) {
5159+ _callback.Call(_receiver.Value(), GetResult(_callback.Env()));
5160+ }
5161+}
5162+
5163+inline void AsyncWorker::OnError(const Error& e) {
5164+ if (!_callback.IsEmpty()) {
5165+ _callback.Call(_receiver.Value(),
5166+ std::initializer_list<napi_value>{e.Value()});
5167+ }
5168+}
5169+
5170+inline void AsyncWorker::SetError(const std::string& error) {
5171+ _error = error;
5172+}
5173+
5174+inline std::vector<napi_value> AsyncWorker::GetResult(Napi::Env /*env*/) {
5175+ return {};
5176+}
5177+// The OnAsyncWorkExecute method receives an napi_env argument. However, do NOT
5178+// use it within this method, as it does not run on the JavaScript thread and
5179+// must not run any method that would cause JavaScript to run. In practice,
5180+// this means that almost any use of napi_env will be incorrect.
5181+inline void AsyncWorker::OnAsyncWorkExecute(napi_env env, void* asyncworker) {
5182+ AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
5183+ self->OnExecute(env);
5184+}
5185+// The OnExecute method receives an napi_env argument. However, do NOT
5186+// use it within this method, as it does not run on the JavaScript thread and
5187+// must not run any method that would cause JavaScript to run. In practice,
5188+// this means that almost any use of napi_env will be incorrect.
5189+inline void AsyncWorker::OnExecute(Napi::Env /*DO_NOT_USE*/) {
5190+#ifdef NAPI_CPP_EXCEPTIONS
5191+ try {
5192+ Execute();
5193+ } catch (const std::exception& e) {
5194+ SetError(e.what());
5195+ }
5196+#else // NAPI_CPP_EXCEPTIONS
5197+ Execute();
5198+#endif // NAPI_CPP_EXCEPTIONS
5199+}
5200+
5201+inline void AsyncWorker::OnAsyncWorkComplete(napi_env env,
5202+ napi_status status,
5203+ void* asyncworker) {
5204+ AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
5205+ self->OnWorkComplete(env, status);
5206+}
5207+inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) {
5208+ if (status != napi_cancelled) {
5209+ HandleScope scope(_env);
5210+ details::WrapCallback([&] {
5211+ if (_error.size() == 0) {
5212+ OnOK();
5213+ } else {
5214+ OnError(Error::New(_env, _error));
5215+ }
5216+ return nullptr;
5217+ });
5218+ }
5219+ if (!_suppress_destruct) {
5220+ Destroy();
5221+ }
5222+}
5223+
5224+#endif // NAPI_HAS_THREADS
5225+
5226+#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS)
5227+////////////////////////////////////////////////////////////////////////////////
5228+// TypedThreadSafeFunction<ContextType,DataType,CallJs> class
5229+////////////////////////////////////////////////////////////////////////////////
5230+
5231+// Starting with NAPI 5, the JavaScript function `func` parameter of
5232+// `napi_create_threadsafe_function` is optional.
5233+#if NAPI_VERSION > 4
5234+// static, with Callback [missing] Resource [missing] Finalizer [missing]
5235+template <typename ContextType,
5236+ typename DataType,
5237+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5238+template <typename ResourceString>
5239+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5240+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5241+ napi_env env,
5242+ ResourceString resourceName,
5243+ size_t maxQueueSize,
5244+ size_t initialThreadCount,
5245+ ContextType* context) {
5246+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5247+
5248+ napi_status status =
5249+ napi_create_threadsafe_function(env,
5250+ nullptr,
5251+ nullptr,
5252+ String::From(env, resourceName),
5253+ maxQueueSize,
5254+ initialThreadCount,
5255+ nullptr,
5256+ nullptr,
5257+ context,
5258+ CallJsInternal,
5259+ &tsfn._tsfn);
5260+ if (status != napi_ok) {
5261+ NAPI_THROW_IF_FAILED(
5262+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5263+ }
5264+
5265+ return tsfn;
5266+}
5267+
5268+// static, with Callback [missing] Resource [passed] Finalizer [missing]
5269+template <typename ContextType,
5270+ typename DataType,
5271+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5272+template <typename ResourceString>
5273+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5274+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5275+ napi_env env,
5276+ const Object& resource,
5277+ ResourceString resourceName,
5278+ size_t maxQueueSize,
5279+ size_t initialThreadCount,
5280+ ContextType* context) {
5281+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5282+
5283+ napi_status status =
5284+ napi_create_threadsafe_function(env,
5285+ nullptr,
5286+ resource,
5287+ String::From(env, resourceName),
5288+ maxQueueSize,
5289+ initialThreadCount,
5290+ nullptr,
5291+ nullptr,
5292+ context,
5293+ CallJsInternal,
5294+ &tsfn._tsfn);
5295+ if (status != napi_ok) {
5296+ NAPI_THROW_IF_FAILED(
5297+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5298+ }
5299+
5300+ return tsfn;
5301+}
5302+
5303+// static, with Callback [missing] Resource [missing] Finalizer [passed]
5304+template <typename ContextType,
5305+ typename DataType,
5306+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5307+template <typename ResourceString,
5308+ typename Finalizer,
5309+ typename FinalizerDataType>
5310+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5311+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5312+ napi_env env,
5313+ ResourceString resourceName,
5314+ size_t maxQueueSize,
5315+ size_t initialThreadCount,
5316+ ContextType* context,
5317+ Finalizer finalizeCallback,
5318+ FinalizerDataType* data) {
5319+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5320+
5321+ auto* finalizeData = new details::
5322+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5323+ {data, finalizeCallback});
5324+ napi_status status = napi_create_threadsafe_function(
5325+ env,
5326+ nullptr,
5327+ nullptr,
5328+ String::From(env, resourceName),
5329+ maxQueueSize,
5330+ initialThreadCount,
5331+ finalizeData,
5332+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5333+ FinalizeFinalizeWrapperWithDataAndContext,
5334+ context,
5335+ CallJsInternal,
5336+ &tsfn._tsfn);
5337+ if (status != napi_ok) {
5338+ delete finalizeData;
5339+ NAPI_THROW_IF_FAILED(
5340+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5341+ }
5342+
5343+ return tsfn;
5344+}
5345+
5346+// static, with Callback [missing] Resource [passed] Finalizer [passed]
5347+template <typename ContextType,
5348+ typename DataType,
5349+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5350+template <typename ResourceString,
5351+ typename Finalizer,
5352+ typename FinalizerDataType>
5353+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5354+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5355+ napi_env env,
5356+ const Object& resource,
5357+ ResourceString resourceName,
5358+ size_t maxQueueSize,
5359+ size_t initialThreadCount,
5360+ ContextType* context,
5361+ Finalizer finalizeCallback,
5362+ FinalizerDataType* data) {
5363+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5364+
5365+ auto* finalizeData = new details::
5366+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5367+ {data, finalizeCallback});
5368+ napi_status status = napi_create_threadsafe_function(
5369+ env,
5370+ nullptr,
5371+ resource,
5372+ String::From(env, resourceName),
5373+ maxQueueSize,
5374+ initialThreadCount,
5375+ finalizeData,
5376+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5377+ FinalizeFinalizeWrapperWithDataAndContext,
5378+ context,
5379+ CallJsInternal,
5380+ &tsfn._tsfn);
5381+ if (status != napi_ok) {
5382+ delete finalizeData;
5383+ NAPI_THROW_IF_FAILED(
5384+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5385+ }
5386+
5387+ return tsfn;
5388+}
5389+#endif
5390+
5391+// static, with Callback [passed] Resource [missing] Finalizer [missing]
5392+template <typename ContextType,
5393+ typename DataType,
5394+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5395+template <typename ResourceString>
5396+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5397+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5398+ napi_env env,
5399+ const Function& callback,
5400+ ResourceString resourceName,
5401+ size_t maxQueueSize,
5402+ size_t initialThreadCount,
5403+ ContextType* context) {
5404+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5405+
5406+ napi_status status =
5407+ napi_create_threadsafe_function(env,
5408+ callback,
5409+ nullptr,
5410+ String::From(env, resourceName),
5411+ maxQueueSize,
5412+ initialThreadCount,
5413+ nullptr,
5414+ nullptr,
5415+ context,
5416+ CallJsInternal,
5417+ &tsfn._tsfn);
5418+ if (status != napi_ok) {
5419+ NAPI_THROW_IF_FAILED(
5420+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5421+ }
5422+
5423+ return tsfn;
5424+}
5425+
5426+// static, with Callback [passed] Resource [passed] Finalizer [missing]
5427+template <typename ContextType,
5428+ typename DataType,
5429+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5430+template <typename ResourceString>
5431+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5432+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5433+ napi_env env,
5434+ const Function& callback,
5435+ const Object& resource,
5436+ ResourceString resourceName,
5437+ size_t maxQueueSize,
5438+ size_t initialThreadCount,
5439+ ContextType* context) {
5440+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5441+
5442+ napi_status status =
5443+ napi_create_threadsafe_function(env,
5444+ callback,
5445+ resource,
5446+ String::From(env, resourceName),
5447+ maxQueueSize,
5448+ initialThreadCount,
5449+ nullptr,
5450+ nullptr,
5451+ context,
5452+ CallJsInternal,
5453+ &tsfn._tsfn);
5454+ if (status != napi_ok) {
5455+ NAPI_THROW_IF_FAILED(
5456+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5457+ }
5458+
5459+ return tsfn;
5460+}
5461+
5462+// static, with Callback [passed] Resource [missing] Finalizer [passed]
5463+template <typename ContextType,
5464+ typename DataType,
5465+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5466+template <typename ResourceString,
5467+ typename Finalizer,
5468+ typename FinalizerDataType>
5469+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5470+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5471+ napi_env env,
5472+ const Function& callback,
5473+ ResourceString resourceName,
5474+ size_t maxQueueSize,
5475+ size_t initialThreadCount,
5476+ ContextType* context,
5477+ Finalizer finalizeCallback,
5478+ FinalizerDataType* data) {
5479+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5480+
5481+ auto* finalizeData = new details::
5482+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5483+ {data, finalizeCallback});
5484+ napi_status status = napi_create_threadsafe_function(
5485+ env,
5486+ callback,
5487+ nullptr,
5488+ String::From(env, resourceName),
5489+ maxQueueSize,
5490+ initialThreadCount,
5491+ finalizeData,
5492+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5493+ FinalizeFinalizeWrapperWithDataAndContext,
5494+ context,
5495+ CallJsInternal,
5496+ &tsfn._tsfn);
5497+ if (status != napi_ok) {
5498+ delete finalizeData;
5499+ NAPI_THROW_IF_FAILED(
5500+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5501+ }
5502+
5503+ return tsfn;
5504+}
5505+
5506+// static, with: Callback [passed] Resource [passed] Finalizer [passed]
5507+template <typename ContextType,
5508+ typename DataType,
5509+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5510+template <typename CallbackType,
5511+ typename ResourceString,
5512+ typename Finalizer,
5513+ typename FinalizerDataType>
5514+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5515+TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5516+ napi_env env,
5517+ CallbackType callback,
5518+ const Object& resource,
5519+ ResourceString resourceName,
5520+ size_t maxQueueSize,
5521+ size_t initialThreadCount,
5522+ ContextType* context,
5523+ Finalizer finalizeCallback,
5524+ FinalizerDataType* data) {
5525+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5526+
5527+ auto* finalizeData = new details::
5528+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5529+ {data, finalizeCallback});
5530+ napi_status status = napi_create_threadsafe_function(
5531+ env,
5532+ details::DefaultCallbackWrapper<
5533+ CallbackType,
5534+ TypedThreadSafeFunction<ContextType, DataType, CallJs>>(env,
5535+ callback),
5536+ resource,
5537+ String::From(env, resourceName),
5538+ maxQueueSize,
5539+ initialThreadCount,
5540+ finalizeData,
5541+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5542+ FinalizeFinalizeWrapperWithDataAndContext,
5543+ context,
5544+ CallJsInternal,
5545+ &tsfn._tsfn);
5546+ if (status != napi_ok) {
5547+ delete finalizeData;
5548+ NAPI_THROW_IF_FAILED(
5549+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5550+ }
5551+
5552+ return tsfn;
5553+}
5554+
5555+template <typename ContextType,
5556+ typename DataType,
5557+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5558+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
5559+ TypedThreadSafeFunction()
5560+ : _tsfn() {}
5561+
5562+template <typename ContextType,
5563+ typename DataType,
5564+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5565+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
5566+ TypedThreadSafeFunction(napi_threadsafe_function tsfn)
5567+ : _tsfn(tsfn) {}
5568+
5569+template <typename ContextType,
5570+ typename DataType,
5571+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5572+inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
5573+operator napi_threadsafe_function() const {
5574+ return _tsfn;
5575+}
5576+
5577+template <typename ContextType,
5578+ typename DataType,
5579+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5580+inline napi_status
5581+TypedThreadSafeFunction<ContextType, DataType, CallJs>::BlockingCall(
5582+ DataType* data) const {
5583+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking);
5584+}
5585+
5586+template <typename ContextType,
5587+ typename DataType,
5588+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5589+inline napi_status
5590+TypedThreadSafeFunction<ContextType, DataType, CallJs>::NonBlockingCall(
5591+ DataType* data) const {
5592+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking);
5593+}
5594+
5595+template <typename ContextType,
5596+ typename DataType,
5597+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5598+inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Ref(
5599+ napi_env env) const {
5600+ if (_tsfn != nullptr) {
5601+ napi_status status = napi_ref_threadsafe_function(env, _tsfn);
5602+ NAPI_THROW_IF_FAILED_VOID(env, status);
5603+ }
5604+}
5605+
5606+template <typename ContextType,
5607+ typename DataType,
5608+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5609+inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Unref(
5610+ napi_env env) const {
5611+ if (_tsfn != nullptr) {
5612+ napi_status status = napi_unref_threadsafe_function(env, _tsfn);
5613+ NAPI_THROW_IF_FAILED_VOID(env, status);
5614+ }
5615+}
5616+
5617+template <typename ContextType,
5618+ typename DataType,
5619+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5620+inline napi_status
5621+TypedThreadSafeFunction<ContextType, DataType, CallJs>::Acquire() const {
5622+ return napi_acquire_threadsafe_function(_tsfn);
5623+}
5624+
5625+template <typename ContextType,
5626+ typename DataType,
5627+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5628+inline napi_status
5629+TypedThreadSafeFunction<ContextType, DataType, CallJs>::Release() const {
5630+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_release);
5631+}
5632+
5633+template <typename ContextType,
5634+ typename DataType,
5635+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5636+inline napi_status
5637+TypedThreadSafeFunction<ContextType, DataType, CallJs>::Abort() const {
5638+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort);
5639+}
5640+
5641+template <typename ContextType,
5642+ typename DataType,
5643+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5644+inline ContextType*
5645+TypedThreadSafeFunction<ContextType, DataType, CallJs>::GetContext() const {
5646+ void* context;
5647+ napi_status status = napi_get_threadsafe_function_context(_tsfn, &context);
5648+ NAPI_FATAL_IF_FAILED(status,
5649+ "TypedThreadSafeFunction::GetContext",
5650+ "napi_get_threadsafe_function_context");
5651+ return static_cast<ContextType*>(context);
5652+}
5653+
5654+// static
5655+template <typename ContextType,
5656+ typename DataType,
5657+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5658+void TypedThreadSafeFunction<ContextType, DataType, CallJs>::CallJsInternal(
5659+ napi_env env, napi_value jsCallback, void* context, void* data) {
5660+ details::CallJsWrapper<ContextType, DataType, decltype(CallJs), CallJs>(
5661+ env, jsCallback, context, data);
5662+}
5663+
5664+#if NAPI_VERSION == 4
5665+// static
5666+template <typename ContextType,
5667+ typename DataType,
5668+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5669+Napi::Function
5670+TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
5671+ Napi::Env env) {
5672+ return Napi::Function::New(env, [](const CallbackInfo& cb) {});
5673+}
5674+
5675+// static
5676+template <typename ContextType,
5677+ typename DataType,
5678+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5679+Napi::Function
5680+TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
5681+ Napi::Env env, Napi::Function& callback) {
5682+ if (callback.IsEmpty()) {
5683+ return EmptyFunctionFactory(env);
5684+ }
5685+ return callback;
5686+}
5687+
5688+#else
5689+// static
5690+template <typename ContextType,
5691+ typename DataType,
5692+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5693+std::nullptr_t
5694+TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
5695+ Napi::Env /*env*/) {
5696+ return nullptr;
5697+}
5698+
5699+// static
5700+template <typename ContextType,
5701+ typename DataType,
5702+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5703+Napi::Function
5704+TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
5705+ Napi::Env /*env*/, Napi::Function& callback) {
5706+ return callback;
5707+}
5708+
5709+#endif
5710+
5711+////////////////////////////////////////////////////////////////////////////////
5712+// ThreadSafeFunction class
5713+////////////////////////////////////////////////////////////////////////////////
5714+
5715+// static
5716+template <typename ResourceString>
5717+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5718+ const Function& callback,
5719+ ResourceString resourceName,
5720+ size_t maxQueueSize,
5721+ size_t initialThreadCount) {
5722+ return New(
5723+ env, callback, Object(), resourceName, maxQueueSize, initialThreadCount);
5724+}
5725+
5726+// static
5727+template <typename ResourceString, typename ContextType>
5728+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5729+ const Function& callback,
5730+ ResourceString resourceName,
5731+ size_t maxQueueSize,
5732+ size_t initialThreadCount,
5733+ ContextType* context) {
5734+ return New(env,
5735+ callback,
5736+ Object(),
5737+ resourceName,
5738+ maxQueueSize,
5739+ initialThreadCount,
5740+ context);
5741+}
5742+
5743+// static
5744+template <typename ResourceString, typename Finalizer>
5745+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5746+ const Function& callback,
5747+ ResourceString resourceName,
5748+ size_t maxQueueSize,
5749+ size_t initialThreadCount,
5750+ Finalizer finalizeCallback) {
5751+ return New(env,
5752+ callback,
5753+ Object(),
5754+ resourceName,
5755+ maxQueueSize,
5756+ initialThreadCount,
5757+ finalizeCallback);
5758+}
5759+
5760+// static
5761+template <typename ResourceString,
5762+ typename Finalizer,
5763+ typename FinalizerDataType>
5764+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5765+ const Function& callback,
5766+ ResourceString resourceName,
5767+ size_t maxQueueSize,
5768+ size_t initialThreadCount,
5769+ Finalizer finalizeCallback,
5770+ FinalizerDataType* data) {
5771+ return New(env,
5772+ callback,
5773+ Object(),
5774+ resourceName,
5775+ maxQueueSize,
5776+ initialThreadCount,
5777+ finalizeCallback,
5778+ data);
5779+}
5780+
5781+// static
5782+template <typename ResourceString, typename ContextType, typename Finalizer>
5783+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5784+ const Function& callback,
5785+ ResourceString resourceName,
5786+ size_t maxQueueSize,
5787+ size_t initialThreadCount,
5788+ ContextType* context,
5789+ Finalizer finalizeCallback) {
5790+ return New(env,
5791+ callback,
5792+ Object(),
5793+ resourceName,
5794+ maxQueueSize,
5795+ initialThreadCount,
5796+ context,
5797+ finalizeCallback);
5798+}
5799+
5800+// static
5801+template <typename ResourceString,
5802+ typename ContextType,
5803+ typename Finalizer,
5804+ typename FinalizerDataType>
5805+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5806+ const Function& callback,
5807+ ResourceString resourceName,
5808+ size_t maxQueueSize,
5809+ size_t initialThreadCount,
5810+ ContextType* context,
5811+ Finalizer finalizeCallback,
5812+ FinalizerDataType* data) {
5813+ return New(env,
5814+ callback,
5815+ Object(),
5816+ resourceName,
5817+ maxQueueSize,
5818+ initialThreadCount,
5819+ context,
5820+ finalizeCallback,
5821+ data);
5822+}
5823+
5824+// static
5825+template <typename ResourceString>
5826+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5827+ const Function& callback,
5828+ const Object& resource,
5829+ ResourceString resourceName,
5830+ size_t maxQueueSize,
5831+ size_t initialThreadCount) {
5832+ return New(env,
5833+ callback,
5834+ resource,
5835+ resourceName,
5836+ maxQueueSize,
5837+ initialThreadCount,
5838+ static_cast<void*>(nullptr) /* context */);
5839+}
5840+
5841+// static
5842+template <typename ResourceString, typename ContextType>
5843+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5844+ const Function& callback,
5845+ const Object& resource,
5846+ ResourceString resourceName,
5847+ size_t maxQueueSize,
5848+ size_t initialThreadCount,
5849+ ContextType* context) {
5850+ return New(env,
5851+ callback,
5852+ resource,
5853+ resourceName,
5854+ maxQueueSize,
5855+ initialThreadCount,
5856+ context,
5857+ [](Env, ContextType*) {} /* empty finalizer */);
5858+}
5859+
5860+// static
5861+template <typename ResourceString, typename Finalizer>
5862+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5863+ const Function& callback,
5864+ const Object& resource,
5865+ ResourceString resourceName,
5866+ size_t maxQueueSize,
5867+ size_t initialThreadCount,
5868+ Finalizer finalizeCallback) {
5869+ return New(env,
5870+ callback,
5871+ resource,
5872+ resourceName,
5873+ maxQueueSize,
5874+ initialThreadCount,
5875+ static_cast<void*>(nullptr) /* context */,
5876+ finalizeCallback,
5877+ static_cast<void*>(nullptr) /* data */,
5878+ details::ThreadSafeFinalize<void, Finalizer>::Wrapper);
5879+}
5880+
5881+// static
5882+template <typename ResourceString,
5883+ typename Finalizer,
5884+ typename FinalizerDataType>
5885+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5886+ const Function& callback,
5887+ const Object& resource,
5888+ ResourceString resourceName,
5889+ size_t maxQueueSize,
5890+ size_t initialThreadCount,
5891+ Finalizer finalizeCallback,
5892+ FinalizerDataType* data) {
5893+ return New(env,
5894+ callback,
5895+ resource,
5896+ resourceName,
5897+ maxQueueSize,
5898+ initialThreadCount,
5899+ static_cast<void*>(nullptr) /* context */,
5900+ finalizeCallback,
5901+ data,
5902+ details::ThreadSafeFinalize<void, Finalizer, FinalizerDataType>::
5903+ FinalizeWrapperWithData);
5904+}
5905+
5906+// static
5907+template <typename ResourceString, typename ContextType, typename Finalizer>
5908+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5909+ const Function& callback,
5910+ const Object& resource,
5911+ ResourceString resourceName,
5912+ size_t maxQueueSize,
5913+ size_t initialThreadCount,
5914+ ContextType* context,
5915+ Finalizer finalizeCallback) {
5916+ return New(
5917+ env,
5918+ callback,
5919+ resource,
5920+ resourceName,
5921+ maxQueueSize,
5922+ initialThreadCount,
5923+ context,
5924+ finalizeCallback,
5925+ static_cast<void*>(nullptr) /* data */,
5926+ details::ThreadSafeFinalize<ContextType,
5927+ Finalizer>::FinalizeWrapperWithContext);
5928+}
5929+
5930+// static
5931+template <typename ResourceString,
5932+ typename ContextType,
5933+ typename Finalizer,
5934+ typename FinalizerDataType>
5935+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
5936+ const Function& callback,
5937+ const Object& resource,
5938+ ResourceString resourceName,
5939+ size_t maxQueueSize,
5940+ size_t initialThreadCount,
5941+ ContextType* context,
5942+ Finalizer finalizeCallback,
5943+ FinalizerDataType* data) {
5944+ return New(
5945+ env,
5946+ callback,
5947+ resource,
5948+ resourceName,
5949+ maxQueueSize,
5950+ initialThreadCount,
5951+ context,
5952+ finalizeCallback,
5953+ data,
5954+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5955+ FinalizeFinalizeWrapperWithDataAndContext);
5956+}
5957+
5958+inline ThreadSafeFunction::ThreadSafeFunction() : _tsfn() {}
5959+
5960+inline ThreadSafeFunction::ThreadSafeFunction(napi_threadsafe_function tsfn)
5961+ : _tsfn(tsfn) {}
5962+
5963+inline ThreadSafeFunction::operator napi_threadsafe_function() const {
5964+ return _tsfn;
5965+}
5966+
5967+inline napi_status ThreadSafeFunction::BlockingCall() const {
5968+ return CallInternal(nullptr, napi_tsfn_blocking);
5969+}
5970+
5971+template <>
5972+inline napi_status ThreadSafeFunction::BlockingCall(void* data) const {
5973+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking);
5974+}
5975+
5976+template <typename Callback>
5977+inline napi_status ThreadSafeFunction::BlockingCall(Callback callback) const {
5978+ return CallInternal(new CallbackWrapper(callback), napi_tsfn_blocking);
5979+}
5980+
5981+template <typename DataType, typename Callback>
5982+inline napi_status ThreadSafeFunction::BlockingCall(DataType* data,
5983+ Callback callback) const {
5984+ auto wrapper = [data, callback](Env env, Function jsCallback) {
5985+ callback(env, jsCallback, data);
5986+ };
5987+ return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_blocking);
5988+}
5989+
5990+inline napi_status ThreadSafeFunction::NonBlockingCall() const {
5991+ return CallInternal(nullptr, napi_tsfn_nonblocking);
5992+}
5993+
5994+template <>
5995+inline napi_status ThreadSafeFunction::NonBlockingCall(void* data) const {
5996+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking);
5997+}
5998+
5999+template <typename Callback>
6000+inline napi_status ThreadSafeFunction::NonBlockingCall(
6001+ Callback callback) const {
6002+ return CallInternal(new CallbackWrapper(callback), napi_tsfn_nonblocking);
6003+}
6004+
6005+template <typename DataType, typename Callback>
6006+inline napi_status ThreadSafeFunction::NonBlockingCall(
6007+ DataType* data, Callback callback) const {
6008+ auto wrapper = [data, callback](Env env, Function jsCallback) {
6009+ callback(env, jsCallback, data);
6010+ };
6011+ return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_nonblocking);
6012+}
6013+
6014+inline void ThreadSafeFunction::Ref(napi_env env) const {
6015+ if (_tsfn != nullptr) {
6016+ napi_status status = napi_ref_threadsafe_function(env, _tsfn);
6017+ NAPI_THROW_IF_FAILED_VOID(env, status);
6018+ }
6019+}
6020+
6021+inline void ThreadSafeFunction::Unref(napi_env env) const {
6022+ if (_tsfn != nullptr) {
6023+ napi_status status = napi_unref_threadsafe_function(env, _tsfn);
6024+ NAPI_THROW_IF_FAILED_VOID(env, status);
6025+ }
6026+}
6027+
6028+inline napi_status ThreadSafeFunction::Acquire() const {
6029+ return napi_acquire_threadsafe_function(_tsfn);
6030+}
6031+
6032+inline napi_status ThreadSafeFunction::Release() const {
6033+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_release);
6034+}
6035+
6036+inline napi_status ThreadSafeFunction::Abort() const {
6037+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort);
6038+}
6039+
6040+inline ThreadSafeFunction::ConvertibleContext ThreadSafeFunction::GetContext()
6041+ const {
6042+ void* context;
6043+ napi_status status = napi_get_threadsafe_function_context(_tsfn, &context);
6044+ NAPI_FATAL_IF_FAILED(status,
6045+ "ThreadSafeFunction::GetContext",
6046+ "napi_get_threadsafe_function_context");
6047+ return ConvertibleContext({context});
6048+}
6049+
6050+// static
6051+template <typename ResourceString,
6052+ typename ContextType,
6053+ typename Finalizer,
6054+ typename FinalizerDataType>
6055+inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
6056+ const Function& callback,
6057+ const Object& resource,
6058+ ResourceString resourceName,
6059+ size_t maxQueueSize,
6060+ size_t initialThreadCount,
6061+ ContextType* context,
6062+ Finalizer finalizeCallback,
6063+ FinalizerDataType* data,
6064+ napi_finalize wrapper) {
6065+ static_assert(details::can_make_string<ResourceString>::value ||
6066+ std::is_convertible<ResourceString, napi_value>::value,
6067+ "Resource name should be convertible to the string type");
6068+
6069+ ThreadSafeFunction tsfn;
6070+ auto* finalizeData = new details::
6071+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
6072+ {data, finalizeCallback});
6073+ napi_status status =
6074+ napi_create_threadsafe_function(env,
6075+ callback,
6076+ resource,
6077+ Value::From(env, resourceName),
6078+ maxQueueSize,
6079+ initialThreadCount,
6080+ finalizeData,
6081+ wrapper,
6082+ context,
6083+ CallJS,
6084+ &tsfn._tsfn);
6085+ if (status != napi_ok) {
6086+ delete finalizeData;
6087+ NAPI_THROW_IF_FAILED(env, status, ThreadSafeFunction());
6088+ }
6089+
6090+ return tsfn;
6091+}
6092+
6093+inline napi_status ThreadSafeFunction::CallInternal(
6094+ CallbackWrapper* callbackWrapper,
6095+ napi_threadsafe_function_call_mode mode) const {
6096+ napi_status status =
6097+ napi_call_threadsafe_function(_tsfn, callbackWrapper, mode);
6098+ if (status != napi_ok && callbackWrapper != nullptr) {
6099+ delete callbackWrapper;
6100+ }
6101+
6102+ return status;
6103+}
6104+
6105+// static
6106+inline void ThreadSafeFunction::CallJS(napi_env env,
6107+ napi_value jsCallback,
6108+ void* /* context */,
6109+ void* data) {
6110+ if (env == nullptr && jsCallback == nullptr) {
6111+ return;
6112+ }
6113+
6114+ details::WrapVoidCallback([&]() {
6115+ if (data != nullptr) {
6116+ auto* callbackWrapper = static_cast<CallbackWrapper*>(data);
6117+ (*callbackWrapper)(env, Function(env, jsCallback));
6118+ delete callbackWrapper;
6119+ } else if (jsCallback != nullptr) {
6120+ Function(env, jsCallback).Call({});
6121+ }
6122+ });
6123+}
6124+
6125+////////////////////////////////////////////////////////////////////////////////
6126+// Async Progress Worker Base class
6127+////////////////////////////////////////////////////////////////////////////////
6128+template <typename DataType>
6129+inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(
6130+ const Object& receiver,
6131+ const Function& callback,
6132+ const char* resource_name,
6133+ const Object& resource,
6134+ size_t queue_size)
6135+ : AsyncWorker(receiver, callback, resource_name, resource) {
6136+ // Fill all possible arguments to work around ambiguous
6137+ // ThreadSafeFunction::New signatures.
6138+ _tsfn = ThreadSafeFunction::New(callback.Env(),
6139+ callback,
6140+ resource,
6141+ resource_name,
6142+ queue_size,
6143+ /** initialThreadCount */ 1,
6144+ /** context */ this,
6145+ OnThreadSafeFunctionFinalize,
6146+ /** finalizeData */ this);
6147+}
6148+
6149+#if NAPI_VERSION > 4
6150+template <typename DataType>
6151+inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(
6152+ Napi::Env env,
6153+ const char* resource_name,
6154+ const Object& resource,
6155+ size_t queue_size)
6156+ : AsyncWorker(env, resource_name, resource) {
6157+ // TODO: Once the changes to make the callback optional for threadsafe
6158+ // functions are available on all versions we can remove the dummy Function
6159+ // here.
6160+ Function callback;
6161+ // Fill all possible arguments to work around ambiguous
6162+ // ThreadSafeFunction::New signatures.
6163+ _tsfn = ThreadSafeFunction::New(env,
6164+ callback,
6165+ resource,
6166+ resource_name,
6167+ queue_size,
6168+ /** initialThreadCount */ 1,
6169+ /** context */ this,
6170+ OnThreadSafeFunctionFinalize,
6171+ /** finalizeData */ this);
6172+}
6173+#endif
6174+
6175+template <typename DataType>
6176+inline AsyncProgressWorkerBase<DataType>::~AsyncProgressWorkerBase() {
6177+ // Abort pending tsfn call.
6178+ // Don't send progress events after we've already completed.
6179+ // It's ok to call ThreadSafeFunction::Abort and ThreadSafeFunction::Release
6180+ // duplicated.
6181+ _tsfn.Abort();
6182+}
6183+
6184+template <typename DataType>
6185+inline void AsyncProgressWorkerBase<DataType>::OnAsyncWorkProgress(
6186+ Napi::Env /* env */, Napi::Function /* jsCallback */, void* data) {
6187+ ThreadSafeData* tsd = static_cast<ThreadSafeData*>(data);
6188+ tsd->asyncprogressworker()->OnWorkProgress(tsd->data());
6189+ delete tsd;
6190+}
6191+
6192+template <typename DataType>
6193+inline napi_status AsyncProgressWorkerBase<DataType>::NonBlockingCall(
6194+ DataType* data) {
6195+ auto tsd = new AsyncProgressWorkerBase::ThreadSafeData(this, data);
6196+ auto ret = _tsfn.NonBlockingCall(tsd, OnAsyncWorkProgress);
6197+ if (ret != napi_ok) {
6198+ delete tsd;
6199+ }
6200+ return ret;
6201+}
6202+
6203+template <typename DataType>
6204+inline void AsyncProgressWorkerBase<DataType>::OnWorkComplete(
6205+ Napi::Env /* env */, napi_status status) {
6206+ _work_completed = true;
6207+ _complete_status = status;
6208+ _tsfn.Release();
6209+}
6210+
6211+template <typename DataType>
6212+inline void AsyncProgressWorkerBase<DataType>::OnThreadSafeFunctionFinalize(
6213+ Napi::Env env, void* /* data */, AsyncProgressWorkerBase* context) {
6214+ if (context->_work_completed) {
6215+ context->AsyncWorker::OnWorkComplete(env, context->_complete_status);
6216+ }
6217+}
6218+
6219+////////////////////////////////////////////////////////////////////////////////
6220+// Async Progress Worker class
6221+////////////////////////////////////////////////////////////////////////////////
6222+template <class T>
6223+inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback)
6224+ : AsyncProgressWorker(callback, "generic") {}
6225+
6226+template <class T>
6227+inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback,
6228+ const char* resource_name)
6229+ : AsyncProgressWorker(
6230+ callback, resource_name, Object::New(callback.Env())) {}
6231+
6232+template <class T>
6233+inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback,
6234+ const char* resource_name,
6235+ const Object& resource)
6236+ : AsyncProgressWorker(
6237+ Object::New(callback.Env()), callback, resource_name, resource) {}
6238+
6239+template <class T>
6240+inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
6241+ const Function& callback)
6242+ : AsyncProgressWorker(receiver, callback, "generic") {}
6243+
6244+template <class T>
6245+inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
6246+ const Function& callback,
6247+ const char* resource_name)
6248+ : AsyncProgressWorker(
6249+ receiver, callback, resource_name, Object::New(callback.Env())) {}
6250+
6251+template <class T>
6252+inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
6253+ const Function& callback,
6254+ const char* resource_name,
6255+ const Object& resource)
6256+ : AsyncProgressWorkerBase(receiver, callback, resource_name, resource),
6257+ _asyncdata(nullptr),
6258+ _asyncsize(0),
6259+ _signaled(false) {}
6260+
6261+#if NAPI_VERSION > 4
6262+template <class T>
6263+inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env)
6264+ : AsyncProgressWorker(env, "generic") {}
6265+
6266+template <class T>
6267+inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
6268+ const char* resource_name)
6269+ : AsyncProgressWorker(env, resource_name, Object::New(env)) {}
6270+
6271+template <class T>
6272+inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
6273+ const char* resource_name,
6274+ const Object& resource)
6275+ : AsyncProgressWorkerBase(env, resource_name, resource),
6276+ _asyncdata(nullptr),
6277+ _asyncsize(0) {}
6278+#endif
6279+
6280+template <class T>
6281+inline AsyncProgressWorker<T>::~AsyncProgressWorker() {
6282+ {
6283+ std::lock_guard<std::mutex> lock(this->_mutex);
6284+ _asyncdata = nullptr;
6285+ _asyncsize = 0;
6286+ }
6287+}
6288+
6289+template <class T>
6290+inline void AsyncProgressWorker<T>::Execute() {
6291+ ExecutionProgress progress(this);
6292+ Execute(progress);
6293+}
6294+
6295+template <class T>
6296+inline void AsyncProgressWorker<T>::OnWorkProgress(void*) {
6297+ T* data;
6298+ size_t size;
6299+ bool signaled;
6300+ {
6301+ std::lock_guard<std::mutex> lock(this->_mutex);
6302+ data = this->_asyncdata;
6303+ size = this->_asyncsize;
6304+ signaled = this->_signaled;
6305+ this->_asyncdata = nullptr;
6306+ this->_asyncsize = 0;
6307+ this->_signaled = false;
6308+ }
6309+
6310+ /**
6311+ * The callback of ThreadSafeFunction is not been invoked immediately on the
6312+ * callback of uv_async_t (uv io poll), rather the callback of TSFN is
6313+ * invoked on the right next uv idle callback. There are chances that during
6314+ * the deferring the signal of uv_async_t is been sent again, i.e. potential
6315+ * not coalesced two calls of the TSFN callback.
6316+ */
6317+ if (data == nullptr && !signaled) {
6318+ return;
6319+ }
6320+
6321+ this->OnProgress(data, size);
6322+ delete[] data;
6323+}
6324+
6325+template <class T>
6326+inline void AsyncProgressWorker<T>::SendProgress_(const T* data, size_t count) {
6327+ T* new_data = new T[count];
6328+ std::copy(data, data + count, new_data);
6329+
6330+ T* old_data;
6331+ {
6332+ std::lock_guard<std::mutex> lock(this->_mutex);
6333+ old_data = _asyncdata;
6334+ _asyncdata = new_data;
6335+ _asyncsize = count;
6336+ _signaled = false;
6337+ }
6338+ this->NonBlockingCall(nullptr);
6339+
6340+ delete[] old_data;
6341+}
6342+
6343+template <class T>
6344+inline void AsyncProgressWorker<T>::Signal() {
6345+ {
6346+ std::lock_guard<std::mutex> lock(this->_mutex);
6347+ _signaled = true;
6348+ }
6349+ this->NonBlockingCall(static_cast<T*>(nullptr));
6350+}
6351+
6352+template <class T>
6353+inline void AsyncProgressWorker<T>::ExecutionProgress::Signal() const {
6354+ this->_worker->Signal();
6355+}
6356+
6357+template <class T>
6358+inline void AsyncProgressWorker<T>::ExecutionProgress::Send(
6359+ const T* data, size_t count) const {
6360+ _worker->SendProgress_(data, count);
6361+}
6362+
6363+////////////////////////////////////////////////////////////////////////////////
6364+// Async Progress Queue Worker class
6365+////////////////////////////////////////////////////////////////////////////////
6366+template <class T>
6367+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6368+ const Function& callback)
6369+ : AsyncProgressQueueWorker(callback, "generic") {}
6370+
6371+template <class T>
6372+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6373+ const Function& callback, const char* resource_name)
6374+ : AsyncProgressQueueWorker(
6375+ callback, resource_name, Object::New(callback.Env())) {}
6376+
6377+template <class T>
6378+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6379+ const Function& callback, const char* resource_name, const Object& resource)
6380+ : AsyncProgressQueueWorker(
6381+ Object::New(callback.Env()), callback, resource_name, resource) {}
6382+
6383+template <class T>
6384+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6385+ const Object& receiver, const Function& callback)
6386+ : AsyncProgressQueueWorker(receiver, callback, "generic") {}
6387+
6388+template <class T>
6389+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6390+ const Object& receiver, const Function& callback, const char* resource_name)
6391+ : AsyncProgressQueueWorker(
6392+ receiver, callback, resource_name, Object::New(callback.Env())) {}
6393+
6394+template <class T>
6395+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6396+ const Object& receiver,
6397+ const Function& callback,
6398+ const char* resource_name,
6399+ const Object& resource)
6400+ : AsyncProgressWorkerBase<std::pair<T*, size_t>>(
6401+ receiver,
6402+ callback,
6403+ resource_name,
6404+ resource,
6405+ /** unlimited queue size */ 0) {}
6406+
6407+#if NAPI_VERSION > 4
6408+template <class T>
6409+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env)
6410+ : AsyncProgressQueueWorker(env, "generic") {}
6411+
6412+template <class T>
6413+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6414+ Napi::Env env, const char* resource_name)
6415+ : AsyncProgressQueueWorker(env, resource_name, Object::New(env)) {}
6416+
6417+template <class T>
6418+inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(
6419+ Napi::Env env, const char* resource_name, const Object& resource)
6420+ : AsyncProgressWorkerBase<std::pair<T*, size_t>>(
6421+ env, resource_name, resource, /** unlimited queue size */ 0) {}
6422+#endif
6423+
6424+template <class T>
6425+inline void AsyncProgressQueueWorker<T>::Execute() {
6426+ ExecutionProgress progress(this);
6427+ Execute(progress);
6428+}
6429+
6430+template <class T>
6431+inline void AsyncProgressQueueWorker<T>::OnWorkProgress(
6432+ std::pair<T*, size_t>* datapair) {
6433+ if (datapair == nullptr) {
6434+ return;
6435+ }
6436+
6437+ T* data = datapair->first;
6438+ size_t size = datapair->second;
6439+
6440+ this->OnProgress(data, size);
6441+ delete datapair;
6442+ delete[] data;
6443+}
6444+
6445+template <class T>
6446+inline void AsyncProgressQueueWorker<T>::SendProgress_(const T* data,
6447+ size_t count) {
6448+ T* new_data = new T[count];
6449+ std::copy(data, data + count, new_data);
6450+
6451+ auto pair = new std::pair<T*, size_t>(new_data, count);
6452+ this->NonBlockingCall(pair);
6453+}
6454+
6455+template <class T>
6456+inline void AsyncProgressQueueWorker<T>::Signal() const {
6457+ this->SendProgress_(static_cast<T*>(nullptr), 0);
6458+}
6459+
6460+template <class T>
6461+inline void AsyncProgressQueueWorker<T>::OnWorkComplete(Napi::Env env,
6462+ napi_status status) {
6463+ // Draining queued items in TSFN.
6464+ AsyncProgressWorkerBase<std::pair<T*, size_t>>::OnWorkComplete(env, status);
6465+}
6466+
6467+template <class T>
6468+inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Signal() const {
6469+ _worker->SendProgress_(static_cast<T*>(nullptr), 0);
6470+}
6471+
6472+template <class T>
6473+inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Send(
6474+ const T* data, size_t count) const {
6475+ _worker->SendProgress_(data, count);
6476+}
6477+#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS
6478+
6479+////////////////////////////////////////////////////////////////////////////////
6480+// Memory Management class
6481+////////////////////////////////////////////////////////////////////////////////
6482+
6483+inline int64_t MemoryManagement::AdjustExternalMemory(Env env,
6484+ int64_t change_in_bytes) {
6485+ int64_t result;
6486+ napi_status status =
6487+ napi_adjust_external_memory(env, change_in_bytes, &result);
6488+ NAPI_THROW_IF_FAILED(env, status, 0);
6489+ return result;
6490+}
6491+
6492+////////////////////////////////////////////////////////////////////////////////
6493+// Version Management class
6494+////////////////////////////////////////////////////////////////////////////////
6495+
6496+inline uint32_t VersionManagement::GetNapiVersion(Env env) {
6497+ uint32_t result;
6498+ napi_status status = napi_get_version(env, &result);
6499+ NAPI_THROW_IF_FAILED(env, status, 0);
6500+ return result;
6501+}
6502+
6503+inline const napi_node_version* VersionManagement::GetNodeVersion(Env env) {
6504+ const napi_node_version* result;
6505+ napi_status status = napi_get_node_version(env, &result);
6506+ NAPI_THROW_IF_FAILED(env, status, 0);
6507+ return result;
6508+}
6509+
6510+#if NAPI_VERSION > 5
6511+////////////////////////////////////////////////////////////////////////////////
6512+// Addon<T> class
6513+////////////////////////////////////////////////////////////////////////////////
6514+
6515+template <typename T>
6516+inline Object Addon<T>::Init(Env env, Object exports) {
6517+ T* addon = new T(env, exports);
6518+ env.SetInstanceData(addon);
6519+ return addon->entry_point_;
6520+}
6521+
6522+template <typename T>
6523+inline T* Addon<T>::Unwrap(Object wrapper) {
6524+ return wrapper.Env().GetInstanceData<T>();
6525+}
6526+
6527+template <typename T>
6528+inline void Addon<T>::DefineAddon(
6529+ Object exports, const std::initializer_list<AddonProp>& props) {
6530+ DefineProperties(exports, props);
6531+ entry_point_ = exports;
6532+}
6533+
6534+template <typename T>
6535+inline Napi::Object Addon<T>::DefineProperties(
6536+ Object object, const std::initializer_list<AddonProp>& props) {
6537+ const napi_property_descriptor* properties =
6538+ reinterpret_cast<const napi_property_descriptor*>(props.begin());
6539+ size_t size = props.size();
6540+ napi_status status =
6541+ napi_define_properties(object.Env(), object, size, properties);
6542+ NAPI_THROW_IF_FAILED(object.Env(), status, object);
6543+ for (size_t idx = 0; idx < size; idx++)
6544+ T::AttachPropData(object.Env(), object, &properties[idx]);
6545+ return object;
6546+}
6547+#endif // NAPI_VERSION > 5
6548+
6549+#if NAPI_VERSION > 2
6550+template <typename Hook, typename Arg>
6551+Env::CleanupHook<Hook, Arg> Env::AddCleanupHook(Hook hook, Arg* arg) {
6552+ return CleanupHook<Hook, Arg>(*this, hook, arg);
6553+}
6554+
6555+template <typename Hook>
6556+Env::CleanupHook<Hook> Env::AddCleanupHook(Hook hook) {
6557+ return CleanupHook<Hook>(*this, hook);
6558+}
6559+
6560+template <typename Hook, typename Arg>
6561+Env::CleanupHook<Hook, Arg>::CleanupHook() {
6562+ data = nullptr;
6563+}
6564+
6565+template <typename Hook, typename Arg>
6566+Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook)
6567+ : wrapper(Env::CleanupHook<Hook, Arg>::Wrapper) {
6568+ data = new CleanupData{std::move(hook), nullptr};
6569+ napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
6570+ if (status != napi_ok) {
6571+ delete data;
6572+ data = nullptr;
6573+ }
6574+}
6575+
6576+template <typename Hook, typename Arg>
6577+Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook, Arg* arg)
6578+ : wrapper(Env::CleanupHook<Hook, Arg>::WrapperWithArg) {
6579+ data = new CleanupData{std::move(hook), arg};
6580+ napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
6581+ if (status != napi_ok) {
6582+ delete data;
6583+ data = nullptr;
6584+ }
6585+}
6586+
6587+template <class Hook, class Arg>
6588+bool Env::CleanupHook<Hook, Arg>::Remove(Env env) {
6589+ napi_status status = napi_remove_env_cleanup_hook(env, wrapper, data);
6590+ delete data;
6591+ data = nullptr;
6592+ return status == napi_ok;
6593+}
6594+
6595+template <class Hook, class Arg>
6596+bool Env::CleanupHook<Hook, Arg>::IsEmpty() const {
6597+ return data == nullptr;
6598+}
6599+#endif // NAPI_VERSION > 2
6600+
6601+#ifdef NAPI_CPP_CUSTOM_NAMESPACE
6602+} // namespace NAPI_CPP_CUSTOM_NAMESPACE
6603+#endif
6604+
6605+} // namespace Napi
6606+
6607+#endif // SRC_NAPI_INL_H_
A node_modules/node-addon-api/napi.h +3201 -0 collapsed to keep the page light
A node_modules/node-addon-api/node_addon_api.gyp +32 -0 collapsed to keep the page light
A node_modules/node-addon-api/node_api.gyp +9 -0 collapsed to keep the page light
A node_modules/node-addon-api/noexcept.gypi +26 -0 collapsed to keep the page light
A node_modules/node-addon-api/nothing.c +0 -0

no textual change.

A node_modules/node-addon-api/package-support.json +21 -0 collapsed to keep the page light
A node_modules/node-addon-api/package.json +480 -0 collapsed to keep the page light
A node_modules/node-addon-api/tools/README.md +73 -0 collapsed to keep the page light
A node_modules/node-addon-api/tools/check-napi.js +99 -0 collapsed to keep the page light
A node_modules/node-addon-api/tools/clang-format.js +71 -0 collapsed to keep the page light
A node_modules/node-addon-api/tools/conversion.js +301 -0 collapsed to keep the page light
A node_modules/node-addon-api/tools/eslint-format.js +79 -0 collapsed to keep the page light
A node_modules/normalize-path/LICENSE +21 -0 collapsed to keep the page light
A node_modules/normalize-path/README.md +127 -0 collapsed to keep the page light
A node_modules/normalize-path/index.js +35 -0 collapsed to keep the page light
A node_modules/normalize-path/package.json +77 -0 collapsed to keep the page light
A node_modules/object-assign/index.js +90 -0 collapsed to keep the page light
A node_modules/object-assign/license +21 -0 collapsed to keep the page light
A node_modules/object-assign/package.json +42 -0 collapsed to keep the page light
A node_modules/object-assign/readme.md +61 -0 collapsed to keep the page light
A node_modules/object-hash/LICENSE +22 -0 collapsed to keep the page light
A node_modules/object-hash/index.js +453 -0 collapsed to keep the page light
A node_modules/object-hash/package.json +53 -0 collapsed to keep the page light
A node_modules/object-hash/readme.markdown +198 -0 collapsed to keep the page light
A node_modules/package-json-from-dist/LICENSE.md +63 -0 collapsed to keep the page light
A node_modules/package-json-from-dist/README.md +110 -0 collapsed to keep the page light
A node_modules/package-json-from-dist/package.json +68 -0 collapsed to keep the page light
A node_modules/path-key/index.d.ts +40 -0 collapsed to keep the page light
A node_modules/path-key/index.js +16 -0 collapsed to keep the page light
A node_modules/path-key/license +9 -0 collapsed to keep the page light
A node_modules/path-key/package.json +39 -0 collapsed to keep the page light
A node_modules/path-key/readme.md +61 -0 collapsed to keep the page light
A node_modules/path-parse/LICENSE +21 -0 collapsed to keep the page light
A node_modules/path-parse/README.md +42 -0 collapsed to keep the page light
A node_modules/path-parse/index.js +75 -0 collapsed to keep the page light
A node_modules/path-parse/package.json +33 -0 collapsed to keep the page light
A node_modules/path-scurry/LICENSE.md +55 -0 collapsed to keep the page light
A node_modules/path-scurry/README.md +636 -0 collapsed to keep the page light
A node_modules/path-scurry/package.json +89 -0 collapsed to keep the page light
A node_modules/picocolors/LICENSE +15 -0 collapsed to keep the page light
A node_modules/picocolors/README.md +21 -0 collapsed to keep the page light
A node_modules/picocolors/package.json +25 -0 collapsed to keep the page light
A node_modules/picocolors/picocolors.browser.js +4 -0 collapsed to keep the page light
A node_modules/picocolors/picocolors.d.ts +5 -0 collapsed to keep the page light
A node_modules/picocolors/picocolors.js +75 -0 collapsed to keep the page light
A node_modules/picocolors/types.d.ts +51 -0 collapsed to keep the page light
A node_modules/picomatch/CHANGELOG.md +136 -0 collapsed to keep the page light
A node_modules/picomatch/LICENSE +21 -0 collapsed to keep the page light
A node_modules/picomatch/README.md +708 -0 collapsed to keep the page light
A node_modules/picomatch/index.js +3 -0 collapsed to keep the page light
A node_modules/picomatch/lib/constants.js +179 -0 collapsed to keep the page light
A node_modules/picomatch/lib/parse.js +1091 -0 collapsed to keep the page light
A node_modules/picomatch/lib/picomatch.js +342 -0 collapsed to keep the page light
A node_modules/picomatch/lib/scan.js +391 -0 collapsed to keep the page light
A node_modules/picomatch/lib/utils.js +64 -0 collapsed to keep the page light
A node_modules/picomatch/package.json +81 -0 collapsed to keep the page light
A node_modules/pify/index.js +68 -0 collapsed to keep the page light
A node_modules/pify/license +21 -0 collapsed to keep the page light
A node_modules/pify/package.json +48 -0 collapsed to keep the page light
A node_modules/pify/readme.md +119 -0 collapsed to keep the page light
A node_modules/pirates/LICENSE +21 -0 collapsed to keep the page light
A node_modules/pirates/README.md +69 -0 collapsed to keep the page light
A node_modules/pirates/index.d.ts +82 -0 collapsed to keep the page light
A node_modules/pirates/lib/index.js +139 -0 collapsed to keep the page light
A node_modules/pirates/package.json +74 -0 collapsed to keep the page light
A node_modules/postcss-import/LICENSE +20 -0 collapsed to keep the page light
A node_modules/postcss-import/README.md +244 -0 collapsed to keep the page light
A node_modules/postcss-import/index.js +420 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/assign-layer-names.js +17 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/data-url.js +17 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/join-layer.js +9 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/join-media.js +28 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/load-content.js +12 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/parse-statements.js +172 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/process-content.js +59 -0 collapsed to keep the page light
A node_modules/postcss-import/lib/resolve-id.js +42 -0 collapsed to keep the page light
A node_modules/postcss-import/package.json +65 -0 collapsed to keep the page light
A node_modules/postcss-js/LICENSE +20 -0 collapsed to keep the page light
A node_modules/postcss-js/README.md +22 -0 collapsed to keep the page light
A node_modules/postcss-js/async.js +15 -0 collapsed to keep the page light
A node_modules/postcss-js/index.js +11 -0 collapsed to keep the page light
A node_modules/postcss-js/index.mjs +8 -0 collapsed to keep the page light
A node_modules/postcss-js/objectifier.js +85 -0 collapsed to keep the page light
A node_modules/postcss-js/package.json +42 -0 collapsed to keep the page light
A node_modules/postcss-js/parser.js +104 -0 collapsed to keep the page light
A node_modules/postcss-js/process-result.js +11 -0 collapsed to keep the page light
A node_modules/postcss-js/sync.js +12 -0 collapsed to keep the page light
A node_modules/postcss-load-config/LICENSE +20 -0 collapsed to keep the page light
A node_modules/postcss-load-config/README.md +466 -0 collapsed to keep the page light
A node_modules/postcss-load-config/node_modules/lilconfig/LICENSE +21 -0 collapsed to keep the page light
A node_modules/postcss-load-config/node_modules/lilconfig/package.json +42 -0 collapsed to keep the page light
A node_modules/postcss-load-config/node_modules/lilconfig/readme.md +98 -0 collapsed to keep the page light
A node_modules/postcss-load-config/node_modules/lilconfig/src/index.d.ts +54 -0 collapsed to keep the page light
A node_modules/postcss-load-config/node_modules/lilconfig/src/index.js +457 -0 collapsed to keep the page light
A node_modules/postcss-load-config/package.json +54 -0 collapsed to keep the page light
A node_modules/postcss-load-config/src/index.d.ts +65 -0 collapsed to keep the page light
A node_modules/postcss-load-config/src/index.js +185 -0 collapsed to keep the page light
A node_modules/postcss-load-config/src/options.js +47 -0 collapsed to keep the page light
A node_modules/postcss-load-config/src/plugins.js +85 -0 collapsed to keep the page light
A node_modules/postcss-load-config/src/req.js +10 -0 collapsed to keep the page light
A node_modules/postcss-nested/LICENSE +20 -0 collapsed to keep the page light
A node_modules/postcss-nested/README.md +85 -0 collapsed to keep the page light
A node_modules/postcss-nested/index.d.ts +41 -0 collapsed to keep the page light
A node_modules/postcss-nested/index.js +361 -0 collapsed to keep the page light
A node_modules/postcss-nested/package.json +34 -0 collapsed to keep the page light
A node_modules/postcss-selector-parser/API.md +872 -0 collapsed to keep the page light
A node_modules/postcss-selector-parser/CHANGELOG.md +549 -0 collapsed to keep the page light
A node_modules/postcss-selector-parser/LICENSE-MIT +22 -0 collapsed to keep the page light
A node_modules/postcss-selector-parser/README.md +49 -0 collapsed to keep the page light
A node_modules/postcss-selector-parser/package.json +80 -0 collapsed to keep the page light
A node_modules/postcss-selector-parser/postcss-selector-parser.d.ts +555 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/LICENSE +22 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/README.md +263 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/lib/index.d.ts +177 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/lib/index.js +28 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/lib/parse.js +321 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/lib/stringify.js +48 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/lib/unit.js +120 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/lib/walk.js +22 -0 collapsed to keep the page light
A node_modules/postcss-value-parser/package.json +58 -0 collapsed to keep the page light
A node_modules/postcss/LICENSE +20 -0 collapsed to keep the page light
A node_modules/postcss/README.md +28 -0 collapsed to keep the page light
A node_modules/postcss/lib/at-rule.d.ts +140 -0 collapsed to keep the page light
A node_modules/postcss/lib/at-rule.js +25 -0 collapsed to keep the page light
A node_modules/postcss/lib/comment.d.ts +68 -0 collapsed to keep the page light
A node_modules/postcss/lib/comment.js +13 -0 collapsed to keep the page light
A node_modules/postcss/lib/container.d.ts +480 -0 collapsed to keep the page light
A node_modules/postcss/lib/container.js +447 -0 collapsed to keep the page light
A node_modules/postcss/lib/css-syntax-error.d.ts +248 -0 collapsed to keep the page light
A node_modules/postcss/lib/css-syntax-error.js +133 -0 collapsed to keep the page light
A node_modules/postcss/lib/declaration.d.ts +151 -0 collapsed to keep the page light
A node_modules/postcss/lib/declaration.js +24 -0 collapsed to keep the page light
A node_modules/postcss/lib/document.d.ts +69 -0 collapsed to keep the page light
A node_modules/postcss/lib/document.js +33 -0 collapsed to keep the page light
A node_modules/postcss/lib/fromJSON.d.ts +9 -0 collapsed to keep the page light
A node_modules/postcss/lib/fromJSON.js +54 -0 collapsed to keep the page light
A node_modules/postcss/lib/input.d.ts +206 -0 collapsed to keep the page light
A node_modules/postcss/lib/input.js +251 -0 collapsed to keep the page light
A node_modules/postcss/lib/lazy-result.d.ts +190 -0 collapsed to keep the page light
A node_modules/postcss/lib/lazy-result.js +550 -0 collapsed to keep the page light
A node_modules/postcss/lib/list.d.ts +60 -0 collapsed to keep the page light
A node_modules/postcss/lib/list.js +58 -0 collapsed to keep the page light
A node_modules/postcss/lib/map-generator.js +368 -0 collapsed to keep the page light
A node_modules/postcss/lib/no-work-result.d.ts +46 -0 collapsed to keep the page light
A node_modules/postcss/lib/no-work-result.js +138 -0 collapsed to keep the page light
A node_modules/postcss/lib/node.d.ts +541 -0 collapsed to keep the page light
A node_modules/postcss/lib/node.js +434 -0 collapsed to keep the page light
A node_modules/postcss/lib/parse.d.ts +9 -0 collapsed to keep the page light
A node_modules/postcss/lib/parse.js +42 -0 collapsed to keep the page light
A node_modules/postcss/lib/parser.js +611 -0 collapsed to keep the page light
A node_modules/postcss/lib/postcss.d.mts +69 -0 collapsed to keep the page light
A node_modules/postcss/lib/postcss.d.ts +458 -0 collapsed to keep the page light
A node_modules/postcss/lib/postcss.js +101 -0 collapsed to keep the page light
A node_modules/postcss/lib/postcss.mjs +30 -0 collapsed to keep the page light
A node_modules/postcss/lib/previous-map.d.ts +81 -0 collapsed to keep the page light
A node_modules/postcss/lib/previous-map.js +144 -0 collapsed to keep the page light
A node_modules/postcss/lib/processor.d.ts +115 -0 collapsed to keep the page light
A node_modules/postcss/lib/processor.js +67 -0 collapsed to keep the page light
A node_modules/postcss/lib/result.d.ts +205 -0 collapsed to keep the page light
A node_modules/postcss/lib/result.js +42 -0 collapsed to keep the page light
A node_modules/postcss/lib/root.d.ts +87 -0 collapsed to keep the page light
A node_modules/postcss/lib/root.js +61 -0 collapsed to keep the page light
A node_modules/postcss/lib/rule.d.ts +126 -0 collapsed to keep the page light
A node_modules/postcss/lib/rule.js +27 -0 collapsed to keep the page light
A node_modules/postcss/lib/stringifier.d.ts +46 -0 collapsed to keep the page light
A node_modules/postcss/lib/stringifier.js +353 -0 collapsed to keep the page light
A node_modules/postcss/lib/stringify.d.ts +9 -0 collapsed to keep the page light
A node_modules/postcss/lib/stringify.js +11 -0 collapsed to keep the page light
A node_modules/postcss/lib/symbols.js +5 -0 collapsed to keep the page light
A node_modules/postcss/lib/terminal-highlight.js +70 -0 collapsed to keep the page light
A node_modules/postcss/lib/tokenize.js +266 -0 collapsed to keep the page light
A node_modules/postcss/lib/warn-once.js +13 -0 collapsed to keep the page light
A node_modules/postcss/lib/warning.d.ts +147 -0 collapsed to keep the page light
A node_modules/postcss/lib/warning.js +37 -0 collapsed to keep the page light
A node_modules/postcss/package.json +88 -0 collapsed to keep the page light
A node_modules/prettier-plugin-tailwindcss/LICENSE +21 -0 collapsed to keep the page light
A node_modules/prettier-plugin-tailwindcss/README.md +174 -0 collapsed to keep the page light
A node_modules/prettier-plugin-tailwindcss/package.json +144 -0 collapsed to keep the page light
A node_modules/prettier/LICENSE +7 -0 collapsed to keep the page light
A node_modules/prettier/README.md +108 -0 collapsed to keep the page light
A node_modules/prettier/THIRD-PARTY-NOTICES.md +4416 -0 collapsed to keep the page light
A node_modules/prettier/bin/prettier.cjs +68 -0 collapsed to keep the page light
A node_modules/prettier/doc.d.ts +254 -0 collapsed to keep the page light
A node_modules/prettier/doc.js +1261 -0 collapsed to keep the page light
A node_modules/prettier/doc.mjs +1233 -0 collapsed to keep the page light
A node_modules/prettier/index.cjs +682 -0 collapsed to keep the page light
A node_modules/prettier/index.d.ts +956 -0 collapsed to keep the page light
A node_modules/prettier/index.mjs +22242 -0 collapsed to keep the page light
A node_modules/prettier/internal/cli.mjs +4873 -0 collapsed to keep the page light
A node_modules/prettier/package.json +200 -0 collapsed to keep the page light
A node_modules/prettier/plugins/acorn.d.ts +6 -0 collapsed to keep the page light
A node_modules/prettier/plugins/acorn.js +15 -0 collapsed to keep the page light
A node_modules/prettier/plugins/acorn.mjs +15 -0 collapsed to keep the page light
A node_modules/prettier/plugins/angular.d.ts +8 -0 collapsed to keep the page light
A node_modules/prettier/plugins/angular.js +2 -0 collapsed to keep the page light
A node_modules/prettier/plugins/angular.mjs +2 -0 collapsed to keep the page light
A node_modules/prettier/plugins/babel.d.ts +18 -0 collapsed to keep the page light
A node_modules/prettier/plugins/babel.js +15 -0 collapsed to keep the page light
A node_modules/prettier/plugins/babel.mjs +15 -0 collapsed to keep the page light
A node_modules/prettier/plugins/estree.d.ts +1 -0 collapsed to keep the page light
A node_modules/prettier/plugins/estree.js +36 -0 collapsed to keep the page light
A node_modules/prettier/plugins/estree.mjs +36 -0 collapsed to keep the page light
A node_modules/prettier/plugins/flow.d.ts +5 -0 collapsed to keep the page light
A node_modules/prettier/plugins/flow.js +19 -0 collapsed to keep the page light
A node_modules/prettier/plugins/flow.mjs +19 -0 collapsed to keep the page light
A node_modules/prettier/plugins/glimmer.d.ts +5 -0 collapsed to keep the page light
A node_modules/prettier/plugins/glimmer.js +30 -0 collapsed to keep the page light
A node_modules/prettier/plugins/glimmer.mjs +30 -0 collapsed to keep the page light
A node_modules/prettier/plugins/graphql.d.ts +5 -0 collapsed to keep the page light
A node_modules/prettier/plugins/graphql.js +29 -0 collapsed to keep the page light
A node_modules/prettier/plugins/graphql.mjs +29 -0 collapsed to keep the page light
A node_modules/prettier/plugins/html.d.ts +8 -0 collapsed to keep the page light
A node_modules/prettier/plugins/html.js +22 -0 collapsed to keep the page light
A node_modules/prettier/plugins/html.mjs +22 -0 collapsed to keep the page light
A node_modules/prettier/plugins/markdown.d.ts +7 -0 collapsed to keep the page light
A node_modules/prettier/plugins/markdown.js +63 -0 collapsed to keep the page light
A node_modules/prettier/plugins/markdown.mjs +63 -0 collapsed to keep the page light
A node_modules/prettier/plugins/meriyah.d.ts +5 -0 collapsed to keep the page light
A node_modules/prettier/plugins/meriyah.js +4 -0 collapsed to keep the page light
A node_modules/prettier/plugins/meriyah.mjs +4 -0 collapsed to keep the page light
A node_modules/prettier/plugins/postcss.d.ts +7 -0 collapsed to keep the page light
A node_modules/prettier/plugins/postcss.js +54 -0 collapsed to keep the page light
A node_modules/prettier/plugins/postcss.mjs +54 -0 collapsed to keep the page light
A node_modules/prettier/plugins/typescript.d.ts +5 -0 collapsed to keep the page light
A node_modules/prettier/plugins/typescript.js +20 -0 collapsed to keep the page light
A node_modules/prettier/plugins/typescript.mjs +20 -0 collapsed to keep the page light
A node_modules/prettier/plugins/yaml.d.ts +5 -0 collapsed to keep the page light
A node_modules/prettier/plugins/yaml.js +161 -0 collapsed to keep the page light
A node_modules/prettier/plugins/yaml.mjs +161 -0 collapsed to keep the page light
A node_modules/prettier/standalone.d.ts +33 -0 collapsed to keep the page light
A node_modules/prettier/standalone.js +39 -0 collapsed to keep the page light
A node_modules/prettier/standalone.mjs +39 -0 collapsed to keep the page light
A node_modules/queue-microtask/LICENSE +20 -0 collapsed to keep the page light
A node_modules/queue-microtask/README.md +90 -0 collapsed to keep the page light
A node_modules/queue-microtask/index.d.ts +2 -0 collapsed to keep the page light
A node_modules/queue-microtask/index.js +9 -0 collapsed to keep the page light
A node_modules/queue-microtask/package.json +55 -0 collapsed to keep the page light
A node_modules/read-cache/LICENSE +20 -0 collapsed to keep the page light
A node_modules/read-cache/README.md +46 -0 collapsed to keep the page light
A node_modules/read-cache/index.js +78 -0 collapsed to keep the page light
A node_modules/read-cache/package.json +34 -0 collapsed to keep the page light
A node_modules/readdirp/LICENSE +21 -0 collapsed to keep the page light
A node_modules/readdirp/README.md +122 -0 collapsed to keep the page light
A node_modules/readdirp/index.d.ts +43 -0 collapsed to keep the page light
A node_modules/readdirp/index.js +287 -0 collapsed to keep the page light
A node_modules/readdirp/package.json +122 -0 collapsed to keep the page light
A node_modules/resolve/.editorconfig +37 -0 collapsed to keep the page light
A node_modules/resolve/.eslintrc +65 -0 collapsed to keep the page light
A node_modules/resolve/.github/FUNDING.yml +12 -0 collapsed to keep the page light
A node_modules/resolve/LICENSE +21 -0 collapsed to keep the page light
A node_modules/resolve/SECURITY.md +3 -0 collapsed to keep the page light
A node_modules/resolve/async.js +3 -0 collapsed to keep the page light
A node_modules/resolve/bin/resolve +50 -0 collapsed to keep the page light
A node_modules/resolve/example/async.js +5 -0 collapsed to keep the page light
A node_modules/resolve/example/sync.js +3 -0 collapsed to keep the page light
A node_modules/resolve/index.js +6 -0 collapsed to keep the page light
A node_modules/resolve/lib/async.js +329 -0 collapsed to keep the page light
A node_modules/resolve/lib/caller.js +8 -0 collapsed to keep the page light
A node_modules/resolve/lib/core.js +12 -0 collapsed to keep the page light
A node_modules/resolve/lib/core.json +158 -0 collapsed to keep the page light
A node_modules/resolve/lib/homedir.js +24 -0 collapsed to keep the page light
A node_modules/resolve/lib/is-core.js +5 -0 collapsed to keep the page light
A node_modules/resolve/lib/node-modules-paths.js +42 -0 collapsed to keep the page light
A node_modules/resolve/lib/normalize-options.js +10 -0 collapsed to keep the page light
A node_modules/resolve/lib/sync.js +208 -0 collapsed to keep the page light
A node_modules/resolve/package.json +72 -0 collapsed to keep the page light
A node_modules/resolve/readme.markdown +301 -0 collapsed to keep the page light
A node_modules/resolve/sync.js +3 -0 collapsed to keep the page light
A node_modules/resolve/test/core.js +88 -0 collapsed to keep the page light
A node_modules/resolve/test/dotdot.js +29 -0 collapsed to keep the page light
A node_modules/resolve/test/dotdot/abc/index.js +2 -0 collapsed to keep the page light
A node_modules/resolve/test/dotdot/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/faulty_basedir.js +29 -0 collapsed to keep the page light
A node_modules/resolve/test/filter.js +34 -0 collapsed to keep the page light
A node_modules/resolve/test/filter_sync.js +33 -0 collapsed to keep the page light
A node_modules/resolve/test/home_paths.js +127 -0 collapsed to keep the page light
A node_modules/resolve/test/home_paths_sync.js +114 -0 collapsed to keep the page light
A node_modules/resolve/test/mock.js +315 -0 collapsed to keep the page light
A node_modules/resolve/test/mock_sync.js +214 -0 collapsed to keep the page light
A node_modules/resolve/test/module_dir.js +56 -0 collapsed to keep the page light
A node_modules/resolve/test/module_dir/xmodules/aaa/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/module_dir/ymodules/aaa/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/module_dir/zmodules/bbb/main.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/module_dir/zmodules/bbb/package.json +3 -0 collapsed to keep the page light
A node_modules/resolve/test/node-modules-paths.js +143 -0 collapsed to keep the page light
A node_modules/resolve/test/node_path.js +70 -0 collapsed to keep the page light
A node_modules/resolve/test/node_path/x/aaa/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/node_path/x/ccc/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/node_path/y/bbb/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/node_path/y/ccc/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/nonstring.js +9 -0 collapsed to keep the page light
A node_modules/resolve/test/pathfilter.js +75 -0 collapsed to keep the page light
A node_modules/resolve/test/pathfilter/deep_ref/main.js +0 -0

no textual change.

A node_modules/resolve/test/precedence.js +23 -0 collapsed to keep the page light
A node_modules/resolve/test/precedence/aaa.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/precedence/aaa/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/precedence/aaa/main.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/precedence/bbb.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/precedence/bbb/main.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver.js +597 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/baz/doom.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/baz/package.json +4 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/baz/quux.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/browser_field/a.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/browser_field/b.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/browser_field/package.json +5 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/cup.coffee +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/dot_main/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/dot_main/package.json +3 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/dot_slash_main/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/dot_slash_main/package.json +3 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/false_main/index.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/false_main/package.json +4 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/foo.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/incorrect_main/index.js +2 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/incorrect_main/package.json +3 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/invalid_main/package.json +7 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/mug.coffee +0 -0

no textual change.

A node_modules/resolve/test/resolver/mug.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/multirepo/lerna.json +6 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/multirepo/package.json +20 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/multirepo/packages/package-a/index.js +35 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/multirepo/packages/package-a/package.json +14 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/multirepo/packages/package-b/index.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/multirepo/packages/package-b/package.json +14 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/nested_symlinks/mylib/async.js +26 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/nested_symlinks/mylib/package.json +15 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/nested_symlinks/mylib/sync.js +12 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/other_path/lib/other-lib.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/other_path/root.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/quux/foo/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/same_names/foo.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/same_names/foo/index.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/symlinked/_/node_modules/foo.js +0 -0

no textual change.

A node_modules/resolve/test/resolver/symlinked/_/symlink_target/.gitkeep +0 -0

no textual change.

A node_modules/resolve/test/resolver/symlinked/package/bar.js +1 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/symlinked/package/package.json +3 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver/without_basedir/main.js +5 -0 collapsed to keep the page light
A node_modules/resolve/test/resolver_sync.js +730 -0 collapsed to keep the page light
A node_modules/resolve/test/shadowed_core.js +54 -0 collapsed to keep the page light
A node_modules/resolve/test/shadowed_core/node_modules/util/index.js +0 -0

no textual change.

A node_modules/resolve/test/subdirs.js +13 -0 collapsed to keep the page light
A node_modules/resolve/test/symlinks.js +176 -0 collapsed to keep the page light
A node_modules/reusify/.coveralls.yml +1 -0 collapsed to keep the page light
A node_modules/reusify/.travis.yml +28 -0 collapsed to keep the page light
A node_modules/reusify/LICENSE +22 -0 collapsed to keep the page light
A node_modules/reusify/README.md +145 -0 collapsed to keep the page light
A node_modules/reusify/benchmarks/createNoCodeFunction.js +30 -0 collapsed to keep the page light
A node_modules/reusify/benchmarks/fib.js +13 -0 collapsed to keep the page light
A node_modules/reusify/benchmarks/reuseNoCodeFunction.js +38 -0 collapsed to keep the page light
A node_modules/reusify/package.json +45 -0 collapsed to keep the page light
A node_modules/reusify/reusify.js +33 -0 collapsed to keep the page light
A node_modules/reusify/test.js +66 -0 collapsed to keep the page light
A node_modules/run-parallel/LICENSE +20 -0 collapsed to keep the page light
A node_modules/run-parallel/README.md +85 -0 collapsed to keep the page light
A node_modules/run-parallel/index.js +51 -0 collapsed to keep the page light
A node_modules/run-parallel/package.json +58 -0 collapsed to keep the page light
A node_modules/shebang-command/index.js +19 -0 collapsed to keep the page light
A node_modules/shebang-command/license +9 -0 collapsed to keep the page light
A node_modules/shebang-command/package.json +34 -0 collapsed to keep the page light
A node_modules/shebang-command/readme.md +34 -0 collapsed to keep the page light
A node_modules/shebang-regex/index.d.ts +22 -0 collapsed to keep the page light
A node_modules/shebang-regex/index.js +2 -0 collapsed to keep the page light
A node_modules/shebang-regex/license +9 -0 collapsed to keep the page light
A node_modules/shebang-regex/package.json +35 -0 collapsed to keep the page light
A node_modules/shebang-regex/readme.md +33 -0 collapsed to keep the page light
A node_modules/signal-exit/README.md +74 -0 collapsed to keep the page light
A node_modules/signal-exit/package.json +106 -0 collapsed to keep the page light
A node_modules/source-map-js/LICENSE +28 -0 collapsed to keep the page light
A node_modules/source-map-js/README.md +765 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/array-set.js +121 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/base64-vlq.js +140 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/base64.js +67 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/binary-search.js +111 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/mapping-list.js +79 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/quick-sort.js +132 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/source-map-consumer.d.ts +1 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/source-map-consumer.js +1188 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/source-map-generator.d.ts +1 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/source-map-generator.js +444 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/source-node.d.ts +1 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/source-node.js +413 -0 collapsed to keep the page light
A node_modules/source-map-js/lib/util.js +594 -0 collapsed to keep the page light
A node_modules/source-map-js/package.json +71 -0 collapsed to keep the page light
A node_modules/source-map-js/source-map.d.ts +104 -0 collapsed to keep the page light
A node_modules/source-map-js/source-map.js +8 -0 collapsed to keep the page light
A node_modules/string-width-cjs/index.d.ts +29 -0 collapsed to keep the page light
A node_modules/string-width-cjs/index.js +47 -0 collapsed to keep the page light
A node_modules/string-width-cjs/license +9 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/README.md +73 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/es2015/index.js +6 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/es2015/text.js +6 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/index.d.ts +23 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/index.js +6 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/package.json +50 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/emoji-regex/text.js +6 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/index.d.ts +17 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/index.js +4 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/license +9 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex/index.d.ts +37 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex/index.js +10 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex/license +9 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex/package.json +55 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex/readme.md +78 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/package.json +54 -0 collapsed to keep the page light
A node_modules/string-width-cjs/node_modules/strip-ansi/readme.md +46 -0 collapsed to keep the page light
A node_modules/string-width-cjs/package.json +56 -0 collapsed to keep the page light
A node_modules/string-width-cjs/readme.md +50 -0 collapsed to keep the page light
A node_modules/string-width/index.d.ts +29 -0 collapsed to keep the page light
A node_modules/string-width/index.js +54 -0 collapsed to keep the page light
A node_modules/string-width/license +9 -0 collapsed to keep the page light
A node_modules/string-width/package.json +59 -0 collapsed to keep the page light
A node_modules/string-width/readme.md +67 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/index.d.ts +17 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/index.js +4 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/license +9 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/node_modules/ansi-regex/index.d.ts +37 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/node_modules/ansi-regex/index.js +10 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/node_modules/ansi-regex/license +9 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/node_modules/ansi-regex/package.json +55 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/node_modules/ansi-regex/readme.md +78 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/package.json +54 -0 collapsed to keep the page light
A node_modules/strip-ansi-cjs/readme.md +46 -0 collapsed to keep the page light
A node_modules/strip-ansi/index.d.ts +15 -0 collapsed to keep the page light
A node_modules/strip-ansi/index.js +14 -0 collapsed to keep the page light
A node_modules/strip-ansi/license +9 -0 collapsed to keep the page light
A node_modules/strip-ansi/package.json +57 -0 collapsed to keep the page light
A node_modules/strip-ansi/readme.md +41 -0 collapsed to keep the page light
A node_modules/sucrase/LICENSE +21 -0 collapsed to keep the page light
A node_modules/sucrase/README.md +295 -0 collapsed to keep the page light
A node_modules/sucrase/bin/sucrase +3 -0 collapsed to keep the page light
A node_modules/sucrase/bin/sucrase-node +18 -0 collapsed to keep the page light
A node_modules/sucrase/package.json +88 -0 collapsed to keep the page light
A node_modules/sucrase/register/index.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/register/js.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/register/jsx.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/register/ts-legacy-module-interop.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/register/ts.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/register/tsx-legacy-module-interop.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/register/tsx.js +1 -0 collapsed to keep the page light
A node_modules/sucrase/ts-node-plugin/index.js +83 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/.eslintrc +14 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/.github/FUNDING.yml +12 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/.nycrc +9 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/CHANGELOG.md +22 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/LICENSE +21 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/README.md +42 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/browser.js +3 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/index.js +9 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/package.json +70 -0 collapsed to keep the page light
A node_modules/supports-preserve-symlinks-flag/test/index.js +29 -0 collapsed to keep the page light
A node_modules/tapable/LICENSE +21 -0 collapsed to keep the page light
A node_modules/tapable/README.md +296 -0 collapsed to keep the page light
A node_modules/tapable/lib/AsyncParallelBailHook.js +85 -0 collapsed to keep the page light
A node_modules/tapable/lib/AsyncParallelHook.js +37 -0 collapsed to keep the page light
A node_modules/tapable/lib/AsyncSeriesBailHook.js +42 -0 collapsed to keep the page light
A node_modules/tapable/lib/AsyncSeriesHook.js +37 -0 collapsed to keep the page light
A node_modules/tapable/lib/AsyncSeriesLoopHook.js +37 -0 collapsed to keep the page light
A node_modules/tapable/lib/AsyncSeriesWaterfallHook.js +47 -0 collapsed to keep the page light
A node_modules/tapable/lib/Hook.js +175 -0 collapsed to keep the page light
A node_modules/tapable/lib/HookCodeFactory.js +468 -0 collapsed to keep the page light
A node_modules/tapable/lib/HookMap.js +61 -0 collapsed to keep the page light
A node_modules/tapable/lib/MultiHook.js +54 -0 collapsed to keep the page light
A node_modules/tapable/lib/SyncBailHook.js +51 -0 collapsed to keep the page light
A node_modules/tapable/lib/SyncHook.js +46 -0 collapsed to keep the page light
A node_modules/tapable/lib/SyncLoopHook.js +46 -0 collapsed to keep the page light
A node_modules/tapable/lib/SyncWaterfallHook.js +57 -0 collapsed to keep the page light
A node_modules/tapable/lib/index.js +19 -0 collapsed to keep the page light
A node_modules/tapable/lib/util-browser.js +16 -0 collapsed to keep the page light
A node_modules/tapable/package.json +44 -0 collapsed to keep the page light
A node_modules/tapable/tapable.d.ts +116 -0 collapsed to keep the page light
A node_modules/thenify-all/History.md +11 -0 collapsed to keep the page light
A node_modules/thenify-all/LICENSE +22 -0 collapsed to keep the page light
A node_modules/thenify-all/README.md +66 -0 collapsed to keep the page light
A node_modules/thenify-all/index.js +73 -0 collapsed to keep the page light
A node_modules/thenify-all/package.json +34 -0 collapsed to keep the page light
A node_modules/thenify/History.md +11 -0 collapsed to keep the page light
A node_modules/thenify/LICENSE +22 -0 collapsed to keep the page light
A node_modules/thenify/README.md +120 -0 collapsed to keep the page light
A node_modules/thenify/index.js +77 -0 collapsed to keep the page light
A node_modules/thenify/package.json +31 -0 collapsed to keep the page light
A node_modules/to-regex-range/LICENSE +21 -0 collapsed to keep the page light
A node_modules/to-regex-range/README.md +305 -0 collapsed to keep the page light
A node_modules/to-regex-range/index.js +288 -0 collapsed to keep the page light
A node_modules/to-regex-range/package.json +88 -0 collapsed to keep the page light
A node_modules/ts-interface-checker/LICENSE +201 -0 collapsed to keep the page light
A node_modules/ts-interface-checker/README.md +185 -0 collapsed to keep the page light
A node_modules/ts-interface-checker/package.json +60 -0 collapsed to keep the page light
A node_modules/util-deprecate/History.md +16 -0 collapsed to keep the page light
A node_modules/util-deprecate/LICENSE +24 -0 collapsed to keep the page light
A node_modules/util-deprecate/README.md +53 -0 collapsed to keep the page light
A node_modules/util-deprecate/browser.js +67 -0 collapsed to keep the page light
A node_modules/util-deprecate/node.js +6 -0 collapsed to keep the page light
A node_modules/util-deprecate/package.json +27 -0 collapsed to keep the page light
A node_modules/which/CHANGELOG.md +166 -0 collapsed to keep the page light
A node_modules/which/LICENSE +15 -0 collapsed to keep the page light
A node_modules/which/README.md +54 -0 collapsed to keep the page light
A node_modules/which/bin/node-which +52 -0 collapsed to keep the page light
A node_modules/which/package.json +43 -0 collapsed to keep the page light
A node_modules/which/which.js +125 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/index.js +216 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/license +9 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/ansi-styles/index.d.ts +345 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/ansi-styles/index.js +163 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/ansi-styles/license +9 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/ansi-styles/package.json +56 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/ansi-styles/readme.md +152 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/index.d.ts +29 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/index.js +47 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/license +9 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/README.md +73 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/es2015/index.js +6 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/es2015/text.js +6 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/index.d.ts +23 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/index.js +6 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/package.json +50 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex/text.js +6 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/package.json +56 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/string-width/readme.md +50 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/index.d.ts +17 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/index.js +4 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/license +9 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex/index.d.ts +37 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex/index.js +10 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex/license +9 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex/package.json +55 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex/readme.md +78 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/package.json +54 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/node_modules/strip-ansi/readme.md +46 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/package.json +62 -0 collapsed to keep the page light
A node_modules/wrap-ansi-cjs/readme.md +91 -0 collapsed to keep the page light
A node_modules/wrap-ansi/index.d.ts +41 -0 collapsed to keep the page light
A node_modules/wrap-ansi/index.js +214 -0 collapsed to keep the page light
A node_modules/wrap-ansi/license +9 -0 collapsed to keep the page light
A node_modules/wrap-ansi/package.json +69 -0 collapsed to keep the page light
A node_modules/wrap-ansi/readme.md +91 -0 collapsed to keep the page light
A node_modules/yaml/LICENSE +13 -0 collapsed to keep the page light
A node_modules/yaml/README.md +169 -0 collapsed to keep the page light
A node_modules/yaml/bin.mjs +11 -0 collapsed to keep the page light
A node_modules/yaml/browser/index.js +5 -0 collapsed to keep the page light
A node_modules/yaml/browser/package.json +3 -0 collapsed to keep the page light
A node_modules/yaml/package.json +96 -0 collapsed to keep the page light
A node_modules/yaml/util.js +2 -0 collapsed to keep the page light
D package.json +0 -17 collapsed to keep the page light
M tailwind.config.js +9 -56 collapsed to keep the page light

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close