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
@@ -1,9 +1,10 @@
1 .env1 .env
2-node_modules/2+# Node.js/Bun specific (removed)
3+# node_modules/
3 *tmp/4 *tmp/
4 tmp/*5 tmp/*
5 config.yml6 config.yml
6-bun.lockb7+# bun.lockb
7 *.log8 *.log
8 *.txt9 *.txt
9 *sync-conflict*10 *sync-conflict*
@@ -16,3 +17,7 @@ setup.sh
16 sqlite.db17 sqlite.db
17 .vscode/18 .vscode/
18 admin-ui/19 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
@@ -4,7 +4,7 @@ before:
4 hooks:4 hooks:
5 - go mod tidy5 - go mod tidy
6 - templ generate6 - templ generate
7- - bun run build:css7+ - tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css
8 8
9 release:9 release:
10 draft: true10 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
@@ -38,7 +38,7 @@ build: build-css build-templ
38 # Build CSS with tailwindcss38 # Build CSS with tailwindcss
39 build-css:39 build-css:
40 @echo "Building CSS with tailwindcss..."40 @echo "Building CSS with tailwindcss..."
41- @bun run build:css41+ @tailwindcss -i internal/webui/public/assets/css/custom.css -o internal/webui/public/assets/css/tailwind.css
42 @echo "CSS built successfully"42 @echo "CSS built successfully"
43 43
44 # Generate Go code from templ templates44 # 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 }
@@ -1,8 +1,8 @@
1 package handlers1 package handlers
2 2
3 import (3 import (
4+ "encoding/json"
4 "fmt"5 "fmt"
5- "net/http"
6 "strings"6 "strings"
7 7
8 "github.com/bnema/gordon/internal/server"8 "github.com/bnema/gordon/internal/server"
@@ -126,25 +126,6 @@ func CreateContainerFullGET(c echo.Context, a *server.App) error {
126 func CreateContainerPOST(c echo.Context, a *server.App) error {126 func CreateContainerPOST(c echo.Context, a *server.App) error {
127 log.Debug("CreateContainerPOST handler called")127 log.Debug("CreateContainerPOST handler called")
128 128
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-
148 // Retrieve all form parameters129 // Retrieve all form parameters
149 formParams, err := c.FormParams()130 formParams, err := c.FormParams()
150 if err != nil {131 if err != nil {
@@ -165,6 +146,22 @@ func CreateContainerPOST(c echo.Context, a *server.App) error {
165 }146 }
166 }147 }
167 148
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+
168 cmdParams, err := cmdparams.FromInputsToCmdParams(sanitizedInputs, a)165 cmdParams, err := cmdparams.FromInputsToCmdParams(sanitizedInputs, a)
169 if err != nil {166 if err != nil {
170 return sendError(c, err)167 return sendError(c, err)
@@ -229,6 +226,21 @@ func CreateContainerPOST(c echo.Context, a *server.App) error {
229 log.Info("Skipping proxy setup as requested", "container_id", containerID, "container_name", containerName)226 log.Info("Skipping proxy setup as requested", "container_id", containerID, "container_name", containerName)
230 }227 }
231 228
232- // Redirect to the container list page229+ // Prepare success message payload
233- return c.Redirect(http.StatusSeeOther, fmt.Sprintf("%s/containers", a.Config.Admin.Path))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
234 }246 }
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
@@ -224,12 +224,108 @@ func ImageManagerPrune(c echo.Context, a *server.App) error {
224 lastPruneResult.mutex.Unlock()224 lastPruneResult.mutex.Unlock()
225 }()225 }()
226 226
227- // Immediately return 202 Accepted to the client227+ // Immediately return a placeholder that initiates polling
228- c.Response().Header().Set(echo.HeaderContentType, echo.MIMETextHTML) // Set appropriate content type if needed for HTMX228+ // 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.
229 c.Response().WriteHeader(http.StatusAccepted)231 c.Response().WriteHeader(http.StatusAccepted)
230- // Optionally, return a message or updated component indicating the process has started232+ // We'll return a small snippet that the template swap can use
231- // For now, just return a simple message in the response body233+ // This snippet should include the polling mechanism itself.
232- return c.String(http.StatusAccepted, "Image pruning started in the background.")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)
233 }329 }
234 330
235 // ContainerManagerComponent handles the /container-manager route331 // 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
@@ -24,6 +24,15 @@ func generateOrderedYAML(infoMap map[string]interface{}) (string, error) {
24 continue24 continue
25 }25 }
26 26
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
27 yamlBytes, err := yaml.Marshal(map[string]interface{}{key: value})36 yamlBytes, err := yaml.Marshal(map[string]interface{}{key: value})
28 if err != nil {37 if err != nil {
29 return "", err38 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")
@@ -81,12 +81,12 @@ func StartOAuthGithub(c echo.Context, a *server.App) error {
81 return fmt.Errorf("could not extend session expiration: %w", err)81 return fmt.Errorf("could not extend session expiration: %w", err)
82 }82 }
83 83
84- // Explicitly mark the session as online since we've validated it84+ // Explicitly mark the session as active since we've validated it
85- logger.Info("Marking existing session as online", "sessionID", sessionID)85+ logger.Info("Marking existing session as active", "sessionID", sessionID)
86 err = queries.MarkSessionActive(a.DB, sessionID)86 err = queries.MarkSessionActive(a.DB, sessionID)
87 if err != nil {87 if err != nil {
88- logger.Error("Failed to mark session as online", "error", err, "sessionID", sessionID)88+ logger.Error("Failed to mark session as active", "error", err, "sessionID", sessionID)
89- return fmt.Errorf("failed to mark session online: %w", err)89+ return fmt.Errorf("failed to mark session active: %w", err)
90 }90 }
91 91
92 logger.Info("Session is valid and extended. Redirecting to admin panel")92 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
@@ -218,6 +218,12 @@ func (p *Proxy) Close() {
218 218
219 // requestDomainCertificate requests a certificate for a domain219 // requestDomainCertificate requests a certificate for a domain
220 func (p *Proxy) requestDomainCertificate(domainName string) error {220 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+
221 logger.Debug("Requesting certificate for domain", "domain", domainName)227 logger.Debug("Requesting certificate for domain", "domain", domainName)
222 228
223 // Check if we're already processing this domain229 // 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+// }
@@ -1,7 +1,6 @@
1 package proxy1 package proxy
2 2
3 import (3 import (
4- "fmt"
5 "net"4 "net"
6 "net/http"5 "net/http"
7 "strings"6 "strings"
@@ -114,7 +113,7 @@ func (p *Proxy) setupMiddleware() {
114 }113 }
115 114
116 // Add middleware to log incoming headers (for debugging Cloudflare detection)115 // Add middleware to log incoming headers (for debugging Cloudflare detection)
117- p.httpsServer.Use(logHeadersMiddleware())116+ // p.httpsServer.Use(logHeadersMiddleware())
118 117
119 // --- Rate Limiting Setup (Domain Only Now) ---118 // --- Rate Limiting Setup (Domain Only Now) ---
120 if p.config.EnableRateLimit {119 if p.config.EnableRateLimit {
@@ -250,17 +249,17 @@ func (p *Proxy) createRequestIDMiddleware() echo.MiddlewareFunc {
250 }249 }
251 250
252 // logHeadersMiddleware creates a middleware function to log request headers251 // logHeadersMiddleware creates a middleware function to log request headers
253-func logHeadersMiddleware() echo.MiddlewareFunc {252+// func logHeadersMiddleware() echo.MiddlewareFunc {
254- return func(next echo.HandlerFunc) echo.HandlerFunc {253+// return func(next echo.HandlerFunc) echo.HandlerFunc {
255- return func(c echo.Context) error {254+// return func(c echo.Context) error {
256- // Log all headers at DEBUG level255+// // Log all headers at DEBUG level
257- headerStrings := []string{}256+// headerStrings := []string{}
258- for k, v := range c.Request().Header {257+// for k, v := range c.Request().Header {
259- headerStrings = append(headerStrings, fmt.Sprintf("%s: %s", k, strings.Join(v, ",")))258+// headerStrings = append(headerStrings, fmt.Sprintf("%s: %s", k, strings.Join(v, ",")))
260- }259+// }
261- logger.Debug("Incoming Request Headers", "request_id", c.Get(RequestIDKey), "headers", strings.Join(headerStrings, " | "))260+// logger.Debug("Incoming Request Headers", "request_id", c.Get(RequestIDKey), "headers", strings.Join(headerStrings, " | "))
262-261+
263- return next(c)262+// return next(c)
264- }263+// }
265- }264+// }
266-}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 }
@@ -1196,19 +1196,53 @@ func (p *Proxy) StartContainerEventListener() error {
1196 } else {1196 } else {
1197 // Even if IP is the same, make sure the route is active1197 // Even if IP is the same, make sure the route is active
1198 if !route.Active {1198 if !route.Active {
1199- logger.Info("Reactivating route for restarted container",1199+ logger.Info("Attempting to reactivate route for restarted container",
1200 "container_id", containerID,1200 "container_id", containerID,
1201 "container_name", containerName,1201 "container_name", containerName,
1202 "domain", domain)1202 "domain", domain)
1203 1203
1204- // Just reuse ForceUpdateRouteIP with the same IP to activate the route1204+ // --- Add Health Check Before Activation ---
1205- p.ForceUpdateRouteIP(domain, containerIP)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+ }
1206 }1240 }
1207 }1241 }
1208 }1242 }
1209 }1243 }
1210 1244
1211- // Call the standard recreation handler for additional checks1245+ // Call the standard recreation handler for additional checks (might add the route if missing)
1212 p.HandleContainerRecreation(containerID, containerName, containerIP)1246 p.HandleContainerRecreation(containerID, containerName, containerIP)
1213 }()1247 }()
1214 }1248 }
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 }
@@ -23,6 +23,9 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
23 }23 }
24 }24 }
25 25
26+ // Retrieve proxy port from the correct input key
27+ proxyPortValue := inputs["container_port"] // Changed from proxy_port
28+
26 params := docker.ContainerCommandParams{29 params := docker.ContainerCommandParams{
27 IsSSL: inputs["container_protocol"] == "https",30 IsSSL: inputs["container_protocol"] == "https",
28 ContainerName: inputs["container_name"],31 ContainerName: inputs["container_name"],
@@ -31,14 +34,30 @@ func FromInputsToCmdParams(inputs map[string]string, a *server.App) (docker.Cont
31 ImageName: inputs["image_name"],34 ImageName: inputs["image_name"],
32 ImageID: inputs["image_id"],35 ImageID: inputs["image_id"],
33 Restart: inputs["restart"],36 Restart: inputs["restart"],
34- ProxyPort: inputs["proxy_port"],37+ ProxyPort: proxyPortValue, // Assign the retrieved value
35 Volumes: volumeSlice,38 Volumes: volumeSlice,
36 Environment: environmentSlice,39 Environment: environmentSlice,
37 Network: a.Config.ContainerEngine.Network,40 Network: a.Config.ContainerEngine.Network,
38 PortMappings: portMappings,41 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{}
39 }48 }
40 49
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
42 if err != nil {61 if err != nil {
43 return docker.ContainerCommandParams{}, fmt.Errorf("error setting up proxy route: %w", err)62 return docker.ContainerCommandParams{}, fmt.Errorf("error setting up proxy route: %w", err)
44 }63 }
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 -->
@@ -1,14 +1,14 @@
1 package components1 package components
2 2
3 import (3 import (
4- "github.com/docker/docker/api/types"4+ "github.com/docker/docker/api/types/container"
5 "strconv"5 "strconv"
6 )6 )
7 7
8 // ContainerList displays a list of containers8 // ContainerList displays a list of containers
9-templ ContainerList(containers []types.Container, noContainer bool) {9+templ ContainerList(containers []container.Summary, noContainer bool) {
10 <!-- Container list using daisyUI components -->10 <!-- Container list using daisyUI components -->
11- <div class="card w-full bg-base-300">11+ <div class="card w-full bg-base-100">
12 <div class="card-body p-4">12 <div class="card-body p-4">
13 13
14 <!-- Action buttons -->14 <!-- 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">
@@ -21,7 +21,7 @@ type ContainerFormData struct {
21 templ CreateContainerForm(data ContainerFormData) {21 templ CreateContainerForm(data ContainerFormData) {
22 <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">22 <div class="flex flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-4 flex-grow">
23 <!-- Left Side: Docker Run Options -->23 <!-- Left Side: Docker Run Options -->
24- <div class="flex-grow card p-6">24+ <div class="flex-grow card p-6 bg-base-100">
25 <h2 class="card-title pb-4">Deploy a container based on { data.ImageName }</h2>25 <h2 class="card-title pb-4">Deploy a container based on { data.ImageName }</h2>
26 if data.ErrorMessage != "" {26 if data.ErrorMessage != "" {
27 <div class="alert alert-error">27 <div class="alert alert-error">
@@ -36,6 +36,7 @@ templ CreateContainerForm(data ContainerFormData) {
36 hx-swap="innerHTML" 36 hx-swap="innerHTML"
37 hx-target={ "#create-form-target-" + data.ShortID }>37 hx-target={ "#create-form-target-" + data.ShortID }>
38 <!-- Image Name -->38 <!-- Image Name -->
39+ <input type="hidden" name="image_id" value={ data.ImageID } />
39 <div class="grid grid-cols-1 md:grid-cols-3 gap-4 pb-4">40 <div class="grid grid-cols-1 md:grid-cols-3 gap-4 pb-4">
40 <div class="md:col-span-1">41 <div class="md:col-span-1">
41 <label class="label">42 <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 -->
@@ -21,7 +21,7 @@ type HumanReadableImage struct {
21 // ImageList displays a list of images21 // ImageList displays a list of images
22 templ ImageList(images []HumanReadableImage) {22 templ ImageList(images []HumanReadableImage) {
23 <!-- Image list using daisyUI components -->23 <!-- Image list using daisyUI components -->
24- <div class="card w-full bg-base-300">24+ <div class="card w-full bg-base-100">
25 <div class="card-body p-4">25 <div class="card-body p-4">
26 26
27 <!-- Action buttons -->27 <!-- 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">
@@ -3,7 +3,7 @@ package components
3 // Navbar is a menu component for navigation3 // Navbar is a menu component for navigation
4 templ Navbar(buildVersion string, adminPath string, userSettingsURL string, logoutURL string) {4 templ Navbar(buildVersion string, adminPath string, userSettingsURL string, logoutURL string) {
5 <!-- DaisyUI Navbar -->5 <!-- 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">
7 <div class="navbar-start">7 <div class="navbar-start">
8 <div class="flex items-center">8 <div class="flex items-center">
9 <h1 class="gordon-title text-2xl md:text-3xl text-primary tracking-tighter px-4">9 <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 }
@@ -4,7 +4,7 @@ package components
4 templ Success(message string) {4 templ Success(message string) {
5 <div5 <div
6 id="success"6 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">
8 <p class="text-2xl text-center">8 <p class="text-2xl text-center">
9 if message != "" {9 if message != "" {
10 { message }10 { 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 -->
@@ -7,7 +7,7 @@ templ AdminLayout(title string, buildVersion string, adminPath string, userSetti
7 <!DOCTYPE html>7 <!DOCTYPE html>
8 <html lang="en" data-theme="gordon-dark">8 <html lang="en" data-theme="gordon-dark">
9 @components.Header(title)9 @components.Header(title)
10- <body class="min-h-screen bg-base-100">10+ <body class="min-h-screen bg-base-250">
11 @components.Navbar(buildVersion, adminPath, userSettingsURL, logoutURL)11 @components.Navbar(buildVersion, adminPath, userSettingsURL, logoutURL)
12 12
13 <!-- Main content starts after navbar height -->13 <!-- 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>
@@ -8,7 +8,7 @@ templ Base(title string) {
8 <!DOCTYPE html>8 <!DOCTYPE html>
9 <html lang="en">9 <html lang="en">
10 @components.Header(title)10 @components.Header(title)
11- <body class="min-h-screen bg-base-100">11+ <body class="min-h-screen bg-base-200">
12 { children... }12 { children... }
13 @components.Footer()13 @components.Footer()
14 </body>14 </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 />
@@ -13,7 +13,7 @@ templ InstallPage(title string, version string) {
13 >13 >
14 <div class="circle-shadow flex justify-center w-100">14 <div class="circle-shadow flex justify-center w-100">
15 <img15 <img
16- src="/assets/imgs/gordon-mascot-hq-trsp.png"16+ src="/assets/imgs/gordon-mascot-mq-trsp.png"
17 alt="logo"17 alt="logo"
18 class="sm:h-24 h-32 xl:h-48"18 class="sm:h-24 h-32 xl:h-48"
19 />19 />
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 -->
@@ -17,7 +17,7 @@ templ ManagerPage(title string, buildVersion string, adminPath string, userSetti
17 </div>17 </div>
18 18
19 <!-- Stats overview -->19 <!-- 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">
21 <div class="stat">21 <div class="stat">
22 <div class="stat-figure text-primary">22 <div class="stat-figure text-primary">
23 <span class="iconf text-3xl">󰡨</span>23 <span class="iconf text-3xl">󰡨</span>
@@ -38,7 +38,7 @@ templ ManagerPage(title string, buildVersion string, adminPath string, userSetti
38 </div>38 </div>
39 39
40 <!-- Tabs for containers and images -->40 <!-- 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">
42 <input type="radio" name="my_tabs" role="tab" class="tab" aria-label="Containers" id="containers-tab" checked />42 <input type="radio" name="my_tabs" role="tab" class="tab" aria-label="Containers" id="containers-tab" checked />
43 <div role="tabpanel" class="tab-content p-0 bg-base-300">43 <div role="tabpanel" class="tab-content p-0 bg-base-300">
44 <!-- Container manager section -->44 <!-- 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>
@@ -16,13 +16,10 @@ templ NotFoundPage(data ErrorPageData) {
16 @layouts.Base(data.Title) {16 @layouts.Base(data.Title) {
17 <div class="flex flex-col items-center justify-center min-h-screen p-4">17 <div class="flex flex-col items-center justify-center min-h-screen p-4">
18 <div class="flex flex-col items-center mb-8">18 <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" />
20 <h1 class="text-4xl font-bold text-error">404</h1>20 <h1 class="text-4xl font-bold text-error">404</h1>
21 <h2 class="text-2xl mb-2">Page Not Found</h2>21 <h2 class="text-2xl mb-2">Page Not Found</h2>
22 <p class="text-center text-base-content opacity-70 max-w-md mb-8">{ data.Message }</p>22 <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>
26 </div>23 </div>
27 </div>24 </div>
28 }25 }
@@ -33,7 +30,7 @@ templ ForbiddenPage(data ErrorPageData) {
33 @layouts.Base(data.Title) {30 @layouts.Base(data.Title) {
34 <div class="flex flex-col items-center justify-center min-h-screen p-4">31 <div class="flex flex-col items-center justify-center min-h-screen p-4">
35 <div class="flex flex-col items-center mb-8">32 <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" />
37 <h1 class="text-4xl font-bold text-error">403</h1>34 <h1 class="text-4xl font-bold text-error">403</h1>
38 <h2 class="text-2xl mb-2">Access Forbidden</h2>35 <h2 class="text-2xl mb-2">Access Forbidden</h2>
39 <p class="text-center text-base-content opacity-70 max-w-md mb-8">{ data.Message }</p>36 <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";
@@ -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-
9 @import "tailwindcss";1 @import "tailwindcss";
10-@plugin "daisyui";2+/* Custom DaisyUI theme - Defined in tailwind.config.js */
11-
12-/* Custom DaisyUI theme */
13 @plugin "daisyui/theme" {3 @plugin "daisyui/theme" {
14 name: "gordon-dark";4 name: "gordon-dark";
15 default: true;5 default: true;
16 prefersdark: true;6 prefersdark: true;
17 color-scheme: "dark";7 color-scheme: "dark";
18- --color-base-100: oklch(28% 0.091 267.935);8+ --color-base-100: oklch(14% 0 0);
19- --color-base-200: oklch(20% 0.042 265.755);9+ --color-base-200: oklch(21% 0.006 285.885);
20- --color-base-300: oklch(13% 0.028 261.692);10+ --color-base-250: oklch(21% 0.006 285.885);
21- --color-base-content: oklch(93% 0.034 272.788);11+ --color-base-300: oklch(26% 0 0);
22- --color-primary: oklch(87% 0 0);12+ --color-base-content: oklch(97% 0.001 106.424);
23- --color-primary-content: oklch(14% 0 0);13+ --color-primary: oklch(44% 0.043 257.281);
24- --color-secondary: oklch(80% 0.105 251.813);14+ --color-primary-content: oklch(98% 0.003 247.858);
25- --color-secondary-content: oklch(28% 0.091 267.935);15+ --color-secondary: oklch(66% 0.179 58.318);
26- --color-accent: oklch(80% 0.105 251.813);16+ --color-secondary-content: oklch(98% 0.022 95.277);
27- --color-accent-content: oklch(28% 0.091 267.935);17+ --color-accent: oklch(60% 0.118 184.704);
28- --color-neutral: oklch(37% 0.034 259.733);18+ --color-accent-content: oklch(98% 0.014 180.72);
29- --color-neutral-content: oklch(98% 0.002 247.839);19+ --color-neutral: oklch(42% 0.199 265.638);
20+ --color-neutral-content: oklch(98% 0.001 106.423);
30 --color-info: oklch(68% 0.169 237.323);21 --color-info: oklch(68% 0.169 237.323);
31 --color-info-content: oklch(97% 0.013 236.62);22 --color-info-content: oklch(97% 0.013 236.62);
32- --color-success: oklch(70% 0.14 182.503);23+ --color-success: oklch(69% 0.17 162.48);
33- --color-success-content: oklch(98% 0.014 180.72);24+ --color-success-content: oklch(97% 0.021 166.113);
34- --color-warning: oklch(76% 0.188 70.08);25+ --color-warning: oklch(70% 0.213 47.604);
35- --color-warning-content: oklch(98% 0.022 95.277);26+ --color-warning-content: oklch(98% 0.016 73.684);
36 --color-error: oklch(64% 0.246 16.439);27 --color-error: oklch(64% 0.246 16.439);
37 --color-error-content: oklch(96% 0.015 12.422);28 --color-error-content: oklch(96% 0.015 12.422);
38- --radius-selector: 0rem;29+ --radius-selector: 1rem;
39- --radius-field: 0rem;30+ --radius-field: 0.5rem;
40- --radius-box: 0rem;31+ --radius-box: 1rem;
41 --size-selector: 0.25rem;32 --size-selector: 0.25rem;
42- --size-field: 0.25rem;33+ --size-field: 0.21875rem;
43 --border: 1px;34 --border: 1px;
44 --depth: 0;35 --depth: 0;
45 --noise: 0;36 --noise: 0;
46 }37 }
47 38
48 39
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-
121 /* Import IBM Plex Fonts */40 /* Import IBM Plex Fonts */
122 @font-face {41 @font-face {
123 font-family: "IBMPlexSans-Bold";42 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 collapsed to keep the page light
A node_modules/node-addon-api/napi.h +3201 -0
@@ -0,0 +1,3201 @@
1+#ifndef SRC_NAPI_H_
2+#define SRC_NAPI_H_
3+
4+#ifndef NAPI_HAS_THREADS
5+#if !defined(__wasm__) || (defined(__EMSCRIPTEN_PTHREADS__) || \
6+ (defined(__wasi__) && defined(_REENTRANT)))
7+#define NAPI_HAS_THREADS 1
8+#else
9+#define NAPI_HAS_THREADS 0
10+#endif
11+#endif
12+
13+#include <node_api.h>
14+#include <functional>
15+#include <initializer_list>
16+#include <memory>
17+#if NAPI_HAS_THREADS
18+#include <mutex>
19+#endif // NAPI_HAS_THREADS
20+#include <string>
21+#include <vector>
22+
23+// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known
24+// good version)
25+#if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210
26+#define NAPI_HAS_CONSTEXPR 1
27+#endif
28+
29+// VS2013 does not support char16_t literal strings, so we'll work around it
30+// using wchar_t strings and casting them. This is safe as long as the character
31+// sizes are the same.
32+#if defined(_MSC_VER) && _MSC_VER <= 1800
33+static_assert(sizeof(char16_t) == sizeof(wchar_t),
34+ "Size mismatch between char16_t and wchar_t");
35+#define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L##x)
36+#else
37+#define NAPI_WIDE_TEXT(x) u##x
38+#endif
39+
40+// If C++ exceptions are not explicitly enabled or disabled, enable them
41+// if exceptions were enabled in the compiler settings.
42+#if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
43+#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
44+#define NAPI_CPP_EXCEPTIONS
45+#else
46+#error Exception support not detected. \
47+ Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS.
48+#endif
49+#endif
50+
51+// If C++ NAPI_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE should
52+// not be set
53+#if defined(NAPI_CPP_EXCEPTIONS) && defined(NODE_ADDON_API_ENABLE_MAYBE)
54+#error NODE_ADDON_API_ENABLE_MAYBE should not be set when \
55+ NAPI_CPP_EXCEPTIONS is defined.
56+#endif
57+
58+#ifdef _NOEXCEPT
59+#define NAPI_NOEXCEPT _NOEXCEPT
60+#else
61+#define NAPI_NOEXCEPT noexcept
62+#endif
63+
64+#ifdef NAPI_CPP_EXCEPTIONS
65+
66+// When C++ exceptions are enabled, Errors are thrown directly. There is no need
67+// to return anything after the throw statements. The variadic parameter is an
68+// optional return value that is ignored.
69+// We need _VOID versions of the macros to avoid warnings resulting from
70+// leaving the NAPI_THROW_* `...` argument empty.
71+
72+#define NAPI_THROW(e, ...) throw e
73+#define NAPI_THROW_VOID(e) throw e
74+
75+#define NAPI_THROW_IF_FAILED(env, status, ...) \
76+ if ((status) != napi_ok) throw Napi::Error::New(env);
77+
78+#define NAPI_THROW_IF_FAILED_VOID(env, status) \
79+ if ((status) != napi_ok) throw Napi::Error::New(env);
80+
81+#else // NAPI_CPP_EXCEPTIONS
82+
83+// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
84+// which are pending until the callback returns to JS. The variadic parameter
85+// is an optional return value; usually it is an empty result.
86+// We need _VOID versions of the macros to avoid warnings resulting from
87+// leaving the NAPI_THROW_* `...` argument empty.
88+
89+#define NAPI_THROW(e, ...) \
90+ do { \
91+ (e).ThrowAsJavaScriptException(); \
92+ return __VA_ARGS__; \
93+ } while (0)
94+
95+#define NAPI_THROW_VOID(e) \
96+ do { \
97+ (e).ThrowAsJavaScriptException(); \
98+ return; \
99+ } while (0)
100+
101+#define NAPI_THROW_IF_FAILED(env, status, ...) \
102+ if ((status) != napi_ok) { \
103+ Napi::Error::New(env).ThrowAsJavaScriptException(); \
104+ return __VA_ARGS__; \
105+ }
106+
107+#define NAPI_THROW_IF_FAILED_VOID(env, status) \
108+ if ((status) != napi_ok) { \
109+ Napi::Error::New(env).ThrowAsJavaScriptException(); \
110+ return; \
111+ }
112+
113+#endif // NAPI_CPP_EXCEPTIONS
114+
115+#ifdef NODE_ADDON_API_ENABLE_MAYBE
116+#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
117+ NAPI_THROW_IF_FAILED(env, status, Napi::Nothing<type>())
118+
119+#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \
120+ NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \
121+ return Napi::Just<type>(result);
122+#else
123+#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
124+ NAPI_THROW_IF_FAILED(env, status, type())
125+
126+#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \
127+ NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \
128+ return result;
129+#endif
130+
131+#define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
132+#define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
133+
134+#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \
135+ NAPI_DISALLOW_ASSIGN(CLASS) \
136+ NAPI_DISALLOW_COPY(CLASS)
137+
138+#define NAPI_CHECK(condition, location, message) \
139+ do { \
140+ if (!(condition)) { \
141+ Napi::Error::Fatal((location), (message)); \
142+ } \
143+ } while (0)
144+
145+#define NAPI_FATAL_IF_FAILED(status, location, message) \
146+ NAPI_CHECK((status) == napi_ok, location, message)
147+
148+////////////////////////////////////////////////////////////////////////////////
149+/// Node-API C++ Wrapper Classes
150+///
151+/// These classes wrap the "Node-API" ABI-stable C APIs for Node.js, providing a
152+/// C++ object model and C++ exception-handling semantics with low overhead.
153+/// The wrappers are all header-only so that they do not affect the ABI.
154+////////////////////////////////////////////////////////////////////////////////
155+namespace Napi {
156+
157+#ifdef NAPI_CPP_CUSTOM_NAMESPACE
158+// NAPI_CPP_CUSTOM_NAMESPACE can be #define'd per-addon to avoid symbol
159+// conflicts between different instances of node-addon-api
160+
161+// First dummy definition of the namespace to make sure that Napi::(name) still
162+// refers to the right things inside this file.
163+namespace NAPI_CPP_CUSTOM_NAMESPACE {}
164+using namespace NAPI_CPP_CUSTOM_NAMESPACE;
165+
166+namespace NAPI_CPP_CUSTOM_NAMESPACE {
167+#endif
168+
169+// Forward declarations
170+class Env;
171+class Value;
172+class Boolean;
173+class Number;
174+#if NAPI_VERSION > 5
175+class BigInt;
176+#endif // NAPI_VERSION > 5
177+#if (NAPI_VERSION > 4)
178+class Date;
179+#endif
180+class String;
181+class Object;
182+class Array;
183+class ArrayBuffer;
184+class Function;
185+class Error;
186+class PropertyDescriptor;
187+class CallbackInfo;
188+class TypedArray;
189+template <typename T>
190+class TypedArrayOf;
191+
192+using Int8Array =
193+ TypedArrayOf<int8_t>; ///< Typed-array of signed 8-bit integers
194+using Uint8Array =
195+ TypedArrayOf<uint8_t>; ///< Typed-array of unsigned 8-bit integers
196+using Int16Array =
197+ TypedArrayOf<int16_t>; ///< Typed-array of signed 16-bit integers
198+using Uint16Array =
199+ TypedArrayOf<uint16_t>; ///< Typed-array of unsigned 16-bit integers
200+using Int32Array =
201+ TypedArrayOf<int32_t>; ///< Typed-array of signed 32-bit integers
202+using Uint32Array =
203+ TypedArrayOf<uint32_t>; ///< Typed-array of unsigned 32-bit integers
204+using Float32Array =
205+ TypedArrayOf<float>; ///< Typed-array of 32-bit floating-point values
206+using Float64Array =
207+ TypedArrayOf<double>; ///< Typed-array of 64-bit floating-point values
208+#if NAPI_VERSION > 5
209+using BigInt64Array =
210+ TypedArrayOf<int64_t>; ///< Typed array of signed 64-bit integers
211+using BigUint64Array =
212+ TypedArrayOf<uint64_t>; ///< Typed array of unsigned 64-bit integers
213+#endif // NAPI_VERSION > 5
214+
215+/// Defines the signature of a Node-API C++ module's registration callback
216+/// (init) function.
217+using ModuleRegisterCallback = Object (*)(Env env, Object exports);
218+
219+class MemoryManagement;
220+
221+/// A simple Maybe type, representing an object which may or may not have a
222+/// value.
223+///
224+/// If an API method returns a Maybe<>, the API method can potentially fail
225+/// either because an exception is thrown, or because an exception is pending,
226+/// e.g. because a previous API call threw an exception that hasn't been
227+/// caught yet. In that case, a "Nothing" value is returned.
228+template <class T>
229+class Maybe {
230+ public:
231+ bool IsNothing() const;
232+ bool IsJust() const;
233+
234+ /// Short-hand for Unwrap(), which doesn't return a value. Could be used
235+ /// where the actual value of the Maybe is not needed like Object::Set.
236+ /// If this Maybe is nothing (empty), node-addon-api will crash the
237+ /// process.
238+ void Check() const;
239+
240+ /// Return the value of type T contained in the Maybe. If this Maybe is
241+ /// nothing (empty), node-addon-api will crash the process.
242+ T Unwrap() const;
243+
244+ /// Return the value of type T contained in the Maybe, or using a default
245+ /// value if this Maybe is nothing (empty).
246+ T UnwrapOr(const T& default_value) const;
247+
248+ /// Converts this Maybe to a value of type T in the out. If this Maybe is
249+ /// nothing (empty), `false` is returned and `out` is left untouched.
250+ bool UnwrapTo(T* out) const;
251+
252+ bool operator==(const Maybe& other) const;
253+ bool operator!=(const Maybe& other) const;
254+
255+ private:
256+ Maybe();
257+ explicit Maybe(const T& t);
258+
259+ bool _has_value;
260+ T _value;
261+
262+ template <class U>
263+ friend Maybe<U> Nothing();
264+ template <class U>
265+ friend Maybe<U> Just(const U& u);
266+};
267+
268+template <class T>
269+inline Maybe<T> Nothing();
270+
271+template <class T>
272+inline Maybe<T> Just(const T& t);
273+
274+#if defined(NODE_ADDON_API_ENABLE_MAYBE)
275+template <typename T>
276+using MaybeOrValue = Maybe<T>;
277+#else
278+template <typename T>
279+using MaybeOrValue = T;
280+#endif
281+
282+/// Environment for Node-API values and operations.
283+///
284+/// All Node-API values and operations must be associated with an environment.
285+/// An environment instance is always provided to callback functions; that
286+/// environment must then be used for any creation of Node-API values or other
287+/// Node-API operations within the callback. (Many methods infer the
288+/// environment from the `this` instance that the method is called on.)
289+///
290+/// In the future, multiple environments per process may be supported,
291+/// although current implementations only support one environment per process.
292+///
293+/// In the V8 JavaScript engine, a Node-API environment approximately
294+/// corresponds to an Isolate.
295+class Env {
296+ private:
297+ napi_env _env;
298+#if NAPI_VERSION > 5
299+ template <typename T>
300+ static void DefaultFini(Env, T* data);
301+ template <typename DataType, typename HintType>
302+ static void DefaultFiniWithHint(Env, DataType* data, HintType* hint);
303+#endif // NAPI_VERSION > 5
304+ public:
305+ Env(napi_env env);
306+
307+ operator napi_env() const;
308+
309+ Object Global() const;
310+ Value Undefined() const;
311+ Value Null() const;
312+
313+ bool IsExceptionPending() const;
314+ Error GetAndClearPendingException() const;
315+
316+ MaybeOrValue<Value> RunScript(const char* utf8script) const;
317+ MaybeOrValue<Value> RunScript(const std::string& utf8script) const;
318+ MaybeOrValue<Value> RunScript(String script) const;
319+
320+#if NAPI_VERSION > 2
321+ template <typename Hook, typename Arg = void>
322+ class CleanupHook;
323+
324+ template <typename Hook>
325+ CleanupHook<Hook> AddCleanupHook(Hook hook);
326+
327+ template <typename Hook, typename Arg>
328+ CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg);
329+#endif // NAPI_VERSION > 2
330+
331+#if NAPI_VERSION > 5
332+ template <typename T>
333+ T* GetInstanceData() const;
334+
335+ template <typename T>
336+ using Finalizer = void (*)(Env, T*);
337+ template <typename T, Finalizer<T> fini = Env::DefaultFini<T>>
338+ void SetInstanceData(T* data) const;
339+
340+ template <typename DataType, typename HintType>
341+ using FinalizerWithHint = void (*)(Env, DataType*, HintType*);
342+ template <typename DataType,
343+ typename HintType,
344+ FinalizerWithHint<DataType, HintType> fini =
345+ Env::DefaultFiniWithHint<DataType, HintType>>
346+ void SetInstanceData(DataType* data, HintType* hint) const;
347+#endif // NAPI_VERSION > 5
348+
349+#if NAPI_VERSION > 2
350+ template <typename Hook, typename Arg>
351+ class CleanupHook {
352+ public:
353+ CleanupHook();
354+ CleanupHook(Env env, Hook hook, Arg* arg);
355+ CleanupHook(Env env, Hook hook);
356+ bool Remove(Env env);
357+ bool IsEmpty() const;
358+
359+ private:
360+ static inline void Wrapper(void* data) NAPI_NOEXCEPT;
361+ static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT;
362+
363+ void (*wrapper)(void* arg);
364+ struct CleanupData {
365+ Hook hook;
366+ Arg* arg;
367+ } * data;
368+ };
369+#endif // NAPI_VERSION > 2
370+
371+#if NAPI_VERSION > 8
372+ const char* GetModuleFileName() const;
373+#endif // NAPI_VERSION > 8
374+};
375+
376+/// A JavaScript value of unknown type.
377+///
378+/// For type-specific operations, convert to one of the Value subclasses using a
379+/// `To*` or `As()` method. The `To*` methods do type coercion; the `As()`
380+/// method does not.
381+///
382+/// Napi::Value value = ...
383+/// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid
384+/// arg..."); Napi::String str = value.As<Napi::String>(); // Cast to a
385+/// string value
386+///
387+/// Napi::Value anotherValue = ...
388+/// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value
389+class Value {
390+ public:
391+ Value(); ///< Creates a new _empty_ Value instance.
392+ Value(napi_env env,
393+ napi_value value); ///< Wraps a Node-API value primitive.
394+
395+ /// Creates a JS value from a C++ primitive.
396+ ///
397+ /// `value` may be any of:
398+ /// - bool
399+ /// - Any integer type
400+ /// - Any floating point type
401+ /// - const char* (encoded using UTF-8, null-terminated)
402+ /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
403+ /// - std::string (encoded using UTF-8)
404+ /// - std::u16string
405+ /// - napi::Value
406+ /// - napi_value
407+ template <typename T>
408+ static Value From(napi_env env, const T& value);
409+
410+ /// Converts to a Node-API value primitive.
411+ ///
412+ /// If the instance is _empty_, this returns `nullptr`.
413+ operator napi_value() const;
414+
415+ /// Tests if this value strictly equals another value.
416+ bool operator==(const Value& other) const;
417+
418+ /// Tests if this value does not strictly equal another value.
419+ bool operator!=(const Value& other) const;
420+
421+ /// Tests if this value strictly equals another value.
422+ bool StrictEquals(const Value& other) const;
423+
424+ /// Gets the environment the value is associated with.
425+ Napi::Env Env() const;
426+
427+ /// Checks if the value is empty (uninitialized).
428+ ///
429+ /// An empty value is invalid, and most attempts to perform an operation on an
430+ /// empty value will result in an exception. Note an empty value is distinct
431+ /// from JavaScript `null` or `undefined`, which are valid values.
432+ ///
433+ /// When C++ exceptions are disabled at compile time, a method with a `Value`
434+ /// return type may return an empty value to indicate a pending exception. So
435+ /// when not using C++ exceptions, callers should check whether the value is
436+ /// empty before attempting to use it.
437+ bool IsEmpty() const;
438+
439+ napi_valuetype Type() const; ///< Gets the type of the value.
440+
441+ bool IsUndefined()
442+ const; ///< Tests if a value is an undefined JavaScript value.
443+ bool IsNull() const; ///< Tests if a value is a null JavaScript value.
444+ bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean.
445+ bool IsNumber() const; ///< Tests if a value is a JavaScript number.
446+#if NAPI_VERSION > 5
447+ bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint.
448+#endif // NAPI_VERSION > 5
449+#if (NAPI_VERSION > 4)
450+ bool IsDate() const; ///< Tests if a value is a JavaScript date.
451+#endif
452+ bool IsString() const; ///< Tests if a value is a JavaScript string.
453+ bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol.
454+ bool IsArray() const; ///< Tests if a value is a JavaScript array.
455+ bool IsArrayBuffer()
456+ const; ///< Tests if a value is a JavaScript array buffer.
457+ bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array.
458+ bool IsObject() const; ///< Tests if a value is a JavaScript object.
459+ bool IsFunction() const; ///< Tests if a value is a JavaScript function.
460+ bool IsPromise() const; ///< Tests if a value is a JavaScript promise.
461+ bool IsDataView() const; ///< Tests if a value is a JavaScript data view.
462+ bool IsBuffer() const; ///< Tests if a value is a Node buffer.
463+ bool IsExternal() const; ///< Tests if a value is a pointer to external data.
464+
465+ /// Casts to another type of `Napi::Value`, when the actual type is known or
466+ /// assumed.
467+ ///
468+ /// This conversion does NOT coerce the type. Calling any methods
469+ /// inappropriate for the actual value type will throw `Napi::Error`.
470+ ///
471+ /// If `NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS` is defined, this method
472+ /// asserts that the actual type is the expected type.
473+ template <typename T>
474+ T As() const;
475+
476+ MaybeOrValue<Boolean> ToBoolean()
477+ const; ///< Coerces a value to a JavaScript boolean.
478+ MaybeOrValue<Number> ToNumber()
479+ const; ///< Coerces a value to a JavaScript number.
480+ MaybeOrValue<String> ToString()
481+ const; ///< Coerces a value to a JavaScript string.
482+ MaybeOrValue<Object> ToObject()
483+ const; ///< Coerces a value to a JavaScript object.
484+
485+ protected:
486+ /// !cond INTERNAL
487+ napi_env _env;
488+ napi_value _value;
489+ /// !endcond
490+};
491+
492+/// A JavaScript boolean value.
493+class Boolean : public Value {
494+ public:
495+ static Boolean New(napi_env env, ///< Node-API environment
496+ bool value ///< Boolean value
497+ );
498+
499+ static void CheckCast(napi_env env, napi_value value);
500+
501+ Boolean(); ///< Creates a new _empty_ Boolean instance.
502+ Boolean(napi_env env,
503+ napi_value value); ///< Wraps a Node-API value primitive.
504+
505+ operator bool() const; ///< Converts a Boolean value to a boolean primitive.
506+ bool Value() const; ///< Converts a Boolean value to a boolean primitive.
507+};
508+
509+/// A JavaScript number value.
510+class Number : public Value {
511+ public:
512+ static Number New(napi_env env, ///< Node-API environment
513+ double value ///< Number value
514+ );
515+
516+ static void CheckCast(napi_env env, napi_value value);
517+
518+ Number(); ///< Creates a new _empty_ Number instance.
519+ Number(napi_env env,
520+ napi_value value); ///< Wraps a Node-API value primitive.
521+
522+ operator int32_t()
523+ const; ///< Converts a Number value to a 32-bit signed integer value.
524+ operator uint32_t()
525+ const; ///< Converts a Number value to a 32-bit unsigned integer value.
526+ operator int64_t()
527+ const; ///< Converts a Number value to a 64-bit signed integer value.
528+ operator float()
529+ const; ///< Converts a Number value to a 32-bit floating-point value.
530+ operator double()
531+ const; ///< Converts a Number value to a 64-bit floating-point value.
532+
533+ int32_t Int32Value()
534+ const; ///< Converts a Number value to a 32-bit signed integer value.
535+ uint32_t Uint32Value()
536+ const; ///< Converts a Number value to a 32-bit unsigned integer value.
537+ int64_t Int64Value()
538+ const; ///< Converts a Number value to a 64-bit signed integer value.
539+ float FloatValue()
540+ const; ///< Converts a Number value to a 32-bit floating-point value.
541+ double DoubleValue()
542+ const; ///< Converts a Number value to a 64-bit floating-point value.
543+};
544+
545+#if NAPI_VERSION > 5
546+/// A JavaScript bigint value.
547+class BigInt : public Value {
548+ public:
549+ static BigInt New(napi_env env, ///< Node-API environment
550+ int64_t value ///< Number value
551+ );
552+ static BigInt New(napi_env env, ///< Node-API environment
553+ uint64_t value ///< Number value
554+ );
555+
556+ /// Creates a new BigInt object using a specified sign bit and a
557+ /// specified list of digits/words.
558+ /// The resulting number is calculated as:
559+ /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
560+ static BigInt New(napi_env env, ///< Node-API environment
561+ int sign_bit, ///< Sign bit. 1 if negative.
562+ size_t word_count, ///< Number of words in array
563+ const uint64_t* words ///< Array of words
564+ );
565+
566+ static void CheckCast(napi_env env, napi_value value);
567+
568+ BigInt(); ///< Creates a new _empty_ BigInt instance.
569+ BigInt(napi_env env,
570+ napi_value value); ///< Wraps a Node-API value primitive.
571+
572+ int64_t Int64Value(bool* lossless)
573+ const; ///< Converts a BigInt value to a 64-bit signed integer value.
574+ uint64_t Uint64Value(bool* lossless)
575+ const; ///< Converts a BigInt value to a 64-bit unsigned integer value.
576+
577+ size_t WordCount() const; ///< The number of 64-bit words needed to store
578+ ///< the result of ToWords().
579+
580+ /// Writes the contents of this BigInt to a specified memory location.
581+ /// `sign_bit` must be provided and will be set to 1 if this BigInt is
582+ /// negative.
583+ /// `*word_count` has to be initialized to the length of the `words` array.
584+ /// Upon return, it will be set to the actual number of words that would
585+ /// be needed to store this BigInt (i.e. the return value of `WordCount()`).
586+ void ToWords(int* sign_bit, size_t* word_count, uint64_t* words);
587+};
588+#endif // NAPI_VERSION > 5
589+
590+#if (NAPI_VERSION > 4)
591+/// A JavaScript date value.
592+class Date : public Value {
593+ public:
594+ /// Creates a new Date value from a double primitive.
595+ static Date New(napi_env env, ///< Node-API environment
596+ double value ///< Number value
597+ );
598+
599+ static void CheckCast(napi_env env, napi_value value);
600+
601+ Date(); ///< Creates a new _empty_ Date instance.
602+ Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive.
603+ operator double() const; ///< Converts a Date value to double primitive
604+
605+ double ValueOf() const; ///< Converts a Date value to a double primitive.
606+};
607+#endif
608+
609+/// A JavaScript string or symbol value (that can be used as a property name).
610+class Name : public Value {
611+ public:
612+ static void CheckCast(napi_env env, napi_value value);
613+
614+ Name(); ///< Creates a new _empty_ Name instance.
615+ Name(napi_env env,
616+ napi_value value); ///< Wraps a Node-API value primitive.
617+};
618+
619+/// A JavaScript string value.
620+class String : public Name {
621+ public:
622+ /// Creates a new String value from a UTF-8 encoded C++ string.
623+ static String New(napi_env env, ///< Node-API environment
624+ const std::string& value ///< UTF-8 encoded C++ string
625+ );
626+
627+ /// Creates a new String value from a UTF-16 encoded C++ string.
628+ static String New(napi_env env, ///< Node-API environment
629+ const std::u16string& value ///< UTF-16 encoded C++ string
630+ );
631+
632+ /// Creates a new String value from a UTF-8 encoded C string.
633+ static String New(
634+ napi_env env, ///< Node-API environment
635+ const char* value ///< UTF-8 encoded null-terminated C string
636+ );
637+
638+ /// Creates a new String value from a UTF-16 encoded C string.
639+ static String New(
640+ napi_env env, ///< Node-API environment
641+ const char16_t* value ///< UTF-16 encoded null-terminated C string
642+ );
643+
644+ /// Creates a new String value from a UTF-8 encoded C string with specified
645+ /// length.
646+ static String New(napi_env env, ///< Node-API environment
647+ const char* value, ///< UTF-8 encoded C string (not
648+ ///< necessarily null-terminated)
649+ size_t length ///< length of the string in bytes
650+ );
651+
652+ /// Creates a new String value from a UTF-16 encoded C string with specified
653+ /// length.
654+ static String New(
655+ napi_env env, ///< Node-API environment
656+ const char16_t* value, ///< UTF-16 encoded C string (not necessarily
657+ ///< null-terminated)
658+ size_t length ///< Length of the string in 2-byte code units
659+ );
660+
661+ /// Creates a new String based on the original object's type.
662+ ///
663+ /// `value` may be any of:
664+ /// - const char* (encoded using UTF-8, null-terminated)
665+ /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
666+ /// - std::string (encoded using UTF-8)
667+ /// - std::u16string
668+ template <typename T>
669+ static String From(napi_env env, const T& value);
670+
671+ static void CheckCast(napi_env env, napi_value value);
672+
673+ String(); ///< Creates a new _empty_ String instance.
674+ String(napi_env env,
675+ napi_value value); ///< Wraps a Node-API value primitive.
676+
677+ operator std::string()
678+ const; ///< Converts a String value to a UTF-8 encoded C++ string.
679+ operator std::u16string()
680+ const; ///< Converts a String value to a UTF-16 encoded C++ string.
681+ std::string Utf8Value()
682+ const; ///< Converts a String value to a UTF-8 encoded C++ string.
683+ std::u16string Utf16Value()
684+ const; ///< Converts a String value to a UTF-16 encoded C++ string.
685+};
686+
687+/// A JavaScript symbol value.
688+class Symbol : public Name {
689+ public:
690+ /// Creates a new Symbol value with an optional description.
691+ static Symbol New(
692+ napi_env env, ///< Node-API environment
693+ const char* description =
694+ nullptr ///< Optional UTF-8 encoded null-terminated C string
695+ /// describing the symbol
696+ );
697+
698+ /// Creates a new Symbol value with a description.
699+ static Symbol New(
700+ napi_env env, ///< Node-API environment
701+ const std::string&
702+ description ///< UTF-8 encoded C++ string describing the symbol
703+ );
704+
705+ /// Creates a new Symbol value with a description.
706+ static Symbol New(napi_env env, ///< Node-API environment
707+ String description ///< String value describing the symbol
708+ );
709+
710+ /// Creates a new Symbol value with a description.
711+ static Symbol New(
712+ napi_env env, ///< Node-API environment
713+ napi_value description ///< String value describing the symbol
714+ );
715+
716+ /// Get a public Symbol (e.g. Symbol.iterator).
717+ static MaybeOrValue<Symbol> WellKnown(napi_env, const std::string& name);
718+
719+ // Create a symbol in the global registry, UTF-8 Encoded cpp string
720+ static MaybeOrValue<Symbol> For(napi_env env, const std::string& description);
721+
722+ // Create a symbol in the global registry, C style string (null terminated)
723+ static MaybeOrValue<Symbol> For(napi_env env, const char* description);
724+
725+ // Create a symbol in the global registry, String value describing the symbol
726+ static MaybeOrValue<Symbol> For(napi_env env, String description);
727+
728+ // Create a symbol in the global registry, napi_value describing the symbol
729+ static MaybeOrValue<Symbol> For(napi_env env, napi_value description);
730+
731+ static void CheckCast(napi_env env, napi_value value);
732+
733+ Symbol(); ///< Creates a new _empty_ Symbol instance.
734+ Symbol(napi_env env,
735+ napi_value value); ///< Wraps a Node-API value primitive.
736+};
737+
738+class TypeTaggable : public Value {
739+ public:
740+#if NAPI_VERSION >= 8
741+ void TypeTag(const napi_type_tag* type_tag) const;
742+ bool CheckTypeTag(const napi_type_tag* type_tag) const;
743+#endif // NAPI_VERSION >= 8
744+ protected:
745+ TypeTaggable();
746+ TypeTaggable(napi_env env, napi_value value);
747+};
748+
749+/// A JavaScript object value.
750+class Object : public TypeTaggable {
751+ public:
752+ /// Enables property and element assignments using indexing syntax.
753+ ///
754+ /// This is a convenient helper to get and set object properties. As
755+ /// getting and setting object properties may throw with JavaScript
756+ /// exceptions, it is notable that these operations may fail.
757+ /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort
758+ /// on JavaScript exceptions.
759+ ///
760+ /// Example:
761+ ///
762+ /// Napi::Value propertyValue = object1['A'];
763+ /// object2['A'] = propertyValue;
764+ /// Napi::Value elementValue = array[0];
765+ /// array[1] = elementValue;
766+ template <typename Key>
767+ class PropertyLValue {
768+ public:
769+ /// Converts an L-value to a value.
770+ operator Value() const;
771+
772+ /// Assigns a value to the property. The type of value can be
773+ /// anything supported by `Object::Set`.
774+ template <typename ValueType>
775+ PropertyLValue& operator=(ValueType value);
776+
777+ private:
778+ PropertyLValue() = delete;
779+ PropertyLValue(Object object, Key key);
780+ napi_env _env;
781+ napi_value _object;
782+ Key _key;
783+
784+ friend class Napi::Object;
785+ };
786+
787+ /// Creates a new Object value.
788+ static Object New(napi_env env ///< Node-API environment
789+ );
790+
791+ static void CheckCast(napi_env env, napi_value value);
792+
793+ Object(); ///< Creates a new _empty_ Object instance.
794+ Object(napi_env env,
795+ napi_value value); ///< Wraps a Node-API value primitive.
796+
797+ /// Gets or sets a named property.
798+ PropertyLValue<std::string> operator[](
799+ const char* utf8name ///< UTF-8 encoded null-terminated property name
800+ );
801+
802+ /// Gets or sets a named property.
803+ PropertyLValue<std::string> operator[](
804+ const std::string& utf8name ///< UTF-8 encoded property name
805+ );
806+
807+ /// Gets or sets an indexed property or array element.
808+ PropertyLValue<uint32_t> operator[](
809+ uint32_t index /// Property / element index
810+ );
811+
812+ /// Gets or sets an indexed property or array element.
813+ PropertyLValue<Value> operator[](Value index /// Property / element index
814+ ) const;
815+
816+ /// Gets a named property.
817+ MaybeOrValue<Value> operator[](
818+ const char* utf8name ///< UTF-8 encoded null-terminated property name
819+ ) const;
820+
821+ /// Gets a named property.
822+ MaybeOrValue<Value> operator[](
823+ const std::string& utf8name ///< UTF-8 encoded property name
824+ ) const;
825+
826+ /// Gets an indexed property or array element.
827+ MaybeOrValue<Value> operator[](uint32_t index ///< Property / element index
828+ ) const;
829+
830+ /// Checks whether a property is present.
831+ MaybeOrValue<bool> Has(napi_value key ///< Property key primitive
832+ ) const;
833+
834+ /// Checks whether a property is present.
835+ MaybeOrValue<bool> Has(Value key ///< Property key
836+ ) const;
837+
838+ /// Checks whether a named property is present.
839+ MaybeOrValue<bool> Has(
840+ const char* utf8name ///< UTF-8 encoded null-terminated property name
841+ ) const;
842+
843+ /// Checks whether a named property is present.
844+ MaybeOrValue<bool> Has(
845+ const std::string& utf8name ///< UTF-8 encoded property name
846+ ) const;
847+
848+ /// Checks whether a own property is present.
849+ MaybeOrValue<bool> HasOwnProperty(napi_value key ///< Property key primitive
850+ ) const;
851+
852+ /// Checks whether a own property is present.
853+ MaybeOrValue<bool> HasOwnProperty(Value key ///< Property key
854+ ) const;
855+
856+ /// Checks whether a own property is present.
857+ MaybeOrValue<bool> HasOwnProperty(
858+ const char* utf8name ///< UTF-8 encoded null-terminated property name
859+ ) const;
860+
861+ /// Checks whether a own property is present.
862+ MaybeOrValue<bool> HasOwnProperty(
863+ const std::string& utf8name ///< UTF-8 encoded property name
864+ ) const;
865+
866+ /// Gets a property.
867+ MaybeOrValue<Value> Get(napi_value key ///< Property key primitive
868+ ) const;
869+
870+ /// Gets a property.
871+ MaybeOrValue<Value> Get(Value key ///< Property key
872+ ) const;
873+
874+ /// Gets a named property.
875+ MaybeOrValue<Value> Get(
876+ const char* utf8name ///< UTF-8 encoded null-terminated property name
877+ ) const;
878+
879+ /// Gets a named property.
880+ MaybeOrValue<Value> Get(
881+ const std::string& utf8name ///< UTF-8 encoded property name
882+ ) const;
883+
884+ /// Sets a property.
885+ template <typename ValueType>
886+ MaybeOrValue<bool> Set(napi_value key, ///< Property key primitive
887+ const ValueType& value ///< Property value primitive
888+ ) const;
889+
890+ /// Sets a property.
891+ template <typename ValueType>
892+ MaybeOrValue<bool> Set(Value key, ///< Property key
893+ const ValueType& value ///< Property value
894+ ) const;
895+
896+ /// Sets a named property.
897+ template <typename ValueType>
898+ MaybeOrValue<bool> Set(
899+ const char* utf8name, ///< UTF-8 encoded null-terminated property name
900+ const ValueType& value) const;
901+
902+ /// Sets a named property.
903+ template <typename ValueType>
904+ MaybeOrValue<bool> Set(
905+ const std::string& utf8name, ///< UTF-8 encoded property name
906+ const ValueType& value ///< Property value primitive
907+ ) const;
908+
909+ /// Delete property.
910+ MaybeOrValue<bool> Delete(napi_value key ///< Property key primitive
911+ ) const;
912+
913+ /// Delete property.
914+ MaybeOrValue<bool> Delete(Value key ///< Property key
915+ ) const;
916+
917+ /// Delete property.
918+ MaybeOrValue<bool> Delete(
919+ const char* utf8name ///< UTF-8 encoded null-terminated property name
920+ ) const;
921+
922+ /// Delete property.
923+ MaybeOrValue<bool> Delete(
924+ const std::string& utf8name ///< UTF-8 encoded property name
925+ ) const;
926+
927+ /// Checks whether an indexed property is present.
928+ MaybeOrValue<bool> Has(uint32_t index ///< Property / element index
929+ ) const;
930+
931+ /// Gets an indexed property or array element.
932+ MaybeOrValue<Value> Get(uint32_t index ///< Property / element index
933+ ) const;
934+
935+ /// Sets an indexed property or array element.
936+ template <typename ValueType>
937+ MaybeOrValue<bool> Set(uint32_t index, ///< Property / element index
938+ const ValueType& value ///< Property value primitive
939+ ) const;
940+
941+ /// Deletes an indexed property or array element.
942+ MaybeOrValue<bool> Delete(uint32_t index ///< Property / element index
943+ ) const;
944+
945+ /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and
946+ /// Proxy.[[GetOwnProperty]] calling into JavaScript. See:
947+ /// -
948+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys
949+ /// -
950+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
951+ MaybeOrValue<Array> GetPropertyNames() const; ///< Get all property names
952+
953+ /// Defines a property on the object.
954+ ///
955+ /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
956+ /// into JavaScript. See
957+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
958+ MaybeOrValue<bool> DefineProperty(
959+ const PropertyDescriptor&
960+ property ///< Descriptor for the property to be defined
961+ ) const;
962+
963+ /// Defines properties on the object.
964+ ///
965+ /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
966+ /// into JavaScript. See
967+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
968+ MaybeOrValue<bool> DefineProperties(
969+ const std::initializer_list<PropertyDescriptor>& properties
970+ ///< List of descriptors for the properties to be defined
971+ ) const;
972+
973+ /// Defines properties on the object.
974+ ///
975+ /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
976+ /// into JavaScript. See
977+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
978+ MaybeOrValue<bool> DefineProperties(
979+ const std::vector<PropertyDescriptor>& properties
980+ ///< Vector of descriptors for the properties to be defined
981+ ) const;
982+
983+ /// Checks if an object is an instance created by a constructor function.
984+ ///
985+ /// This is equivalent to the JavaScript `instanceof` operator.
986+ ///
987+ /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
988+ /// JavaScript.
989+ /// See
990+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
991+ MaybeOrValue<bool> InstanceOf(
992+ const Function& constructor ///< Constructor function
993+ ) const;
994+
995+ template <typename Finalizer, typename T>
996+ inline void AddFinalizer(Finalizer finalizeCallback, T* data) const;
997+
998+ template <typename Finalizer, typename T, typename Hint>
999+ inline void AddFinalizer(Finalizer finalizeCallback,
1000+ T* data,
1001+ Hint* finalizeHint) const;
1002+
1003+#ifdef NAPI_CPP_EXCEPTIONS
1004+ class const_iterator;
1005+
1006+ inline const_iterator begin() const;
1007+
1008+ inline const_iterator end() const;
1009+
1010+ class iterator;
1011+
1012+ inline iterator begin();
1013+
1014+ inline iterator end();
1015+#endif // NAPI_CPP_EXCEPTIONS
1016+
1017+#if NAPI_VERSION >= 8
1018+ /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
1019+ /// JavaScript.
1020+ /// See
1021+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1022+ MaybeOrValue<bool> Freeze() const;
1023+ /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
1024+ /// JavaScript.
1025+ /// See
1026+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1027+ MaybeOrValue<bool> Seal() const;
1028+#endif // NAPI_VERSION >= 8
1029+};
1030+
1031+template <typename T>
1032+class External : public TypeTaggable {
1033+ public:
1034+ static External New(napi_env env, T* data);
1035+
1036+ // Finalizer must implement `void operator()(Env env, T* data)`.
1037+ template <typename Finalizer>
1038+ static External New(napi_env env, T* data, Finalizer finalizeCallback);
1039+ // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1040+ template <typename Finalizer, typename Hint>
1041+ static External New(napi_env env,
1042+ T* data,
1043+ Finalizer finalizeCallback,
1044+ Hint* finalizeHint);
1045+
1046+ static void CheckCast(napi_env env, napi_value value);
1047+
1048+ External();
1049+ External(napi_env env, napi_value value);
1050+
1051+ T* Data() const;
1052+};
1053+
1054+class Array : public Object {
1055+ public:
1056+ static Array New(napi_env env);
1057+ static Array New(napi_env env, size_t length);
1058+
1059+ static void CheckCast(napi_env env, napi_value value);
1060+
1061+ Array();
1062+ Array(napi_env env, napi_value value);
1063+
1064+ uint32_t Length() const;
1065+};
1066+
1067+#ifdef NAPI_CPP_EXCEPTIONS
1068+class Object::const_iterator {
1069+ private:
1070+ enum class Type { BEGIN, END };
1071+
1072+ inline const_iterator(const Object* object, const Type type);
1073+
1074+ public:
1075+ inline const_iterator& operator++();
1076+
1077+ inline bool operator==(const const_iterator& other) const;
1078+
1079+ inline bool operator!=(const const_iterator& other) const;
1080+
1081+ inline const std::pair<Value, Object::PropertyLValue<Value>> operator*()
1082+ const;
1083+
1084+ private:
1085+ const Napi::Object* _object;
1086+ Array _keys;
1087+ uint32_t _index;
1088+
1089+ friend class Object;
1090+};
1091+
1092+class Object::iterator {
1093+ private:
1094+ enum class Type { BEGIN, END };
1095+
1096+ inline iterator(Object* object, const Type type);
1097+
1098+ public:
1099+ inline iterator& operator++();
1100+
1101+ inline bool operator==(const iterator& other) const;
1102+
1103+ inline bool operator!=(const iterator& other) const;
1104+
1105+ inline std::pair<Value, Object::PropertyLValue<Value>> operator*();
1106+
1107+ private:
1108+ Napi::Object* _object;
1109+ Array _keys;
1110+ uint32_t _index;
1111+
1112+ friend class Object;
1113+};
1114+#endif // NAPI_CPP_EXCEPTIONS
1115+
1116+/// A JavaScript array buffer value.
1117+class ArrayBuffer : public Object {
1118+ public:
1119+ /// Creates a new ArrayBuffer instance over a new automatically-allocated
1120+ /// buffer.
1121+ static ArrayBuffer New(
1122+ napi_env env, ///< Node-API environment
1123+ size_t byteLength ///< Length of the buffer to be allocated, in bytes
1124+ );
1125+
1126+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1127+ /// Creates a new ArrayBuffer instance, using an external buffer with
1128+ /// specified byte length.
1129+ static ArrayBuffer New(
1130+ napi_env env, ///< Node-API environment
1131+ void* externalData, ///< Pointer to the external buffer to be used by
1132+ ///< the array
1133+ size_t byteLength ///< Length of the external buffer to be used by the
1134+ ///< array, in bytes
1135+ );
1136+
1137+ /// Creates a new ArrayBuffer instance, using an external buffer with
1138+ /// specified byte length.
1139+ template <typename Finalizer>
1140+ static ArrayBuffer New(
1141+ napi_env env, ///< Node-API environment
1142+ void* externalData, ///< Pointer to the external buffer to be used by
1143+ ///< the array
1144+ size_t byteLength, ///< Length of the external buffer to be used by the
1145+ ///< array,
1146+ /// in bytes
1147+ Finalizer finalizeCallback ///< Function to be called when the array
1148+ ///< buffer is destroyed;
1149+ /// must implement `void operator()(Env env,
1150+ /// void* externalData)`
1151+ );
1152+
1153+ /// Creates a new ArrayBuffer instance, using an external buffer with
1154+ /// specified byte length.
1155+ template <typename Finalizer, typename Hint>
1156+ static ArrayBuffer New(
1157+ napi_env env, ///< Node-API environment
1158+ void* externalData, ///< Pointer to the external buffer to be used by
1159+ ///< the array
1160+ size_t byteLength, ///< Length of the external buffer to be used by the
1161+ ///< array,
1162+ /// in bytes
1163+ Finalizer finalizeCallback, ///< Function to be called when the array
1164+ ///< buffer is destroyed;
1165+ /// must implement `void operator()(Env
1166+ /// env, void* externalData, Hint* hint)`
1167+ Hint* finalizeHint ///< Hint (second parameter) to be passed to the
1168+ ///< finalize callback
1169+ );
1170+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1171+
1172+ static void CheckCast(napi_env env, napi_value value);
1173+
1174+ ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance.
1175+ ArrayBuffer(napi_env env,
1176+ napi_value value); ///< Wraps a Node-API value primitive.
1177+
1178+ void* Data(); ///< Gets a pointer to the data buffer.
1179+ size_t ByteLength(); ///< Gets the length of the array buffer in bytes.
1180+
1181+#if NAPI_VERSION >= 7
1182+ bool IsDetached() const;
1183+ void Detach();
1184+#endif // NAPI_VERSION >= 7
1185+};
1186+
1187+/// A JavaScript typed-array value with unknown array type.
1188+///
1189+/// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the
1190+/// `As()` method:
1191+///
1192+/// Napi::TypedArray array = ...
1193+/// if (t.TypedArrayType() == napi_int32_array) {
1194+/// Napi::Int32Array int32Array = t.As<Napi::Int32Array>();
1195+/// }
1196+class TypedArray : public Object {
1197+ public:
1198+ static void CheckCast(napi_env env, napi_value value);
1199+
1200+ TypedArray(); ///< Creates a new _empty_ TypedArray instance.
1201+ TypedArray(napi_env env,
1202+ napi_value value); ///< Wraps a Node-API value primitive.
1203+
1204+ napi_typedarray_type TypedArrayType()
1205+ const; ///< Gets the type of this typed-array.
1206+ Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1207+
1208+ uint8_t ElementSize()
1209+ const; ///< Gets the size in bytes of one element in the array.
1210+ size_t ElementLength() const; ///< Gets the number of elements in the array.
1211+ size_t ByteOffset()
1212+ const; ///< Gets the offset into the buffer where the array starts.
1213+ size_t ByteLength() const; ///< Gets the length of the array in bytes.
1214+
1215+ protected:
1216+ /// !cond INTERNAL
1217+ napi_typedarray_type _type;
1218+ size_t _length;
1219+
1220+ TypedArray(napi_env env,
1221+ napi_value value,
1222+ napi_typedarray_type type,
1223+ size_t length);
1224+
1225+ template <typename T>
1226+ static
1227+#if defined(NAPI_HAS_CONSTEXPR)
1228+ constexpr
1229+#endif
1230+ napi_typedarray_type
1231+ TypedArrayTypeForPrimitiveType() {
1232+ return std::is_same<T, int8_t>::value ? napi_int8_array
1233+ : std::is_same<T, uint8_t>::value ? napi_uint8_array
1234+ : std::is_same<T, int16_t>::value ? napi_int16_array
1235+ : std::is_same<T, uint16_t>::value ? napi_uint16_array
1236+ : std::is_same<T, int32_t>::value ? napi_int32_array
1237+ : std::is_same<T, uint32_t>::value ? napi_uint32_array
1238+ : std::is_same<T, float>::value ? napi_float32_array
1239+ : std::is_same<T, double>::value ? napi_float64_array
1240+#if NAPI_VERSION > 5
1241+ : std::is_same<T, int64_t>::value ? napi_bigint64_array
1242+ : std::is_same<T, uint64_t>::value ? napi_biguint64_array
1243+#endif // NAPI_VERSION > 5
1244+ : napi_int8_array;
1245+ }
1246+ /// !endcond
1247+};
1248+
1249+/// A JavaScript typed-array value with known array type.
1250+///
1251+/// Note while it is possible to create and access Uint8 "clamped" arrays using
1252+/// this class, the _clamping_ behavior is only applied in JavaScript.
1253+template <typename T>
1254+class TypedArrayOf : public TypedArray {
1255+ public:
1256+ /// Creates a new TypedArray instance over a new automatically-allocated array
1257+ /// buffer.
1258+ ///
1259+ /// The array type parameter can normally be omitted (because it is inferred
1260+ /// from the template parameter T), except when creating a "clamped" array:
1261+ ///
1262+ /// Uint8Array::New(env, length, napi_uint8_clamped_array)
1263+ static TypedArrayOf New(
1264+ napi_env env, ///< Node-API environment
1265+ size_t elementLength, ///< Length of the created array, as a number of
1266+ ///< elements
1267+#if defined(NAPI_HAS_CONSTEXPR)
1268+ napi_typedarray_type type =
1269+ TypedArray::TypedArrayTypeForPrimitiveType<T>()
1270+#else
1271+ napi_typedarray_type type
1272+#endif
1273+ ///< Type of array, if different from the default array type for the
1274+ ///< template parameter T.
1275+ );
1276+
1277+ /// Creates a new TypedArray instance over a provided array buffer.
1278+ ///
1279+ /// The array type parameter can normally be omitted (because it is inferred
1280+ /// from the template parameter T), except when creating a "clamped" array:
1281+ ///
1282+ /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array)
1283+ static TypedArrayOf New(
1284+ napi_env env, ///< Node-API environment
1285+ size_t elementLength, ///< Length of the created array, as a number of
1286+ ///< elements
1287+ Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use
1288+ size_t bufferOffset, ///< Offset into the array buffer where the
1289+ ///< typed-array starts
1290+#if defined(NAPI_HAS_CONSTEXPR)
1291+ napi_typedarray_type type =
1292+ TypedArray::TypedArrayTypeForPrimitiveType<T>()
1293+#else
1294+ napi_typedarray_type type
1295+#endif
1296+ ///< Type of array, if different from the default array type for the
1297+ ///< template parameter T.
1298+ );
1299+
1300+ static void CheckCast(napi_env env, napi_value value);
1301+
1302+ TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance.
1303+ TypedArrayOf(napi_env env,
1304+ napi_value value); ///< Wraps a Node-API value primitive.
1305+
1306+ T& operator[](size_t index); ///< Gets or sets an element in the array.
1307+ const T& operator[](size_t index) const; ///< Gets an element in the array.
1308+
1309+ /// Gets a pointer to the array's backing buffer.
1310+ ///
1311+ /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer,
1312+ /// because the typed-array may have a non-zero `ByteOffset()` into the
1313+ /// `ArrayBuffer`.
1314+ T* Data();
1315+
1316+ /// Gets a pointer to the array's backing buffer.
1317+ ///
1318+ /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer,
1319+ /// because the typed-array may have a non-zero `ByteOffset()` into the
1320+ /// `ArrayBuffer`.
1321+ const T* Data() const;
1322+
1323+ private:
1324+ T* _data;
1325+
1326+ TypedArrayOf(napi_env env,
1327+ napi_value value,
1328+ napi_typedarray_type type,
1329+ size_t length,
1330+ T* data);
1331+};
1332+
1333+/// The DataView provides a low-level interface for reading/writing multiple
1334+/// number types in an ArrayBuffer irrespective of the platform's endianness.
1335+class DataView : public Object {
1336+ public:
1337+ static DataView New(napi_env env, Napi::ArrayBuffer arrayBuffer);
1338+ static DataView New(napi_env env,
1339+ Napi::ArrayBuffer arrayBuffer,
1340+ size_t byteOffset);
1341+ static DataView New(napi_env env,
1342+ Napi::ArrayBuffer arrayBuffer,
1343+ size_t byteOffset,
1344+ size_t byteLength);
1345+
1346+ static void CheckCast(napi_env env, napi_value value);
1347+
1348+ DataView(); ///< Creates a new _empty_ DataView instance.
1349+ DataView(napi_env env,
1350+ napi_value value); ///< Wraps a Node-API value primitive.
1351+
1352+ Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1353+ size_t ByteOffset()
1354+ const; ///< Gets the offset into the buffer where the array starts.
1355+ size_t ByteLength() const; ///< Gets the length of the array in bytes.
1356+
1357+ void* Data() const;
1358+
1359+ float GetFloat32(size_t byteOffset) const;
1360+ double GetFloat64(size_t byteOffset) const;
1361+ int8_t GetInt8(size_t byteOffset) const;
1362+ int16_t GetInt16(size_t byteOffset) const;
1363+ int32_t GetInt32(size_t byteOffset) const;
1364+ uint8_t GetUint8(size_t byteOffset) const;
1365+ uint16_t GetUint16(size_t byteOffset) const;
1366+ uint32_t GetUint32(size_t byteOffset) const;
1367+
1368+ void SetFloat32(size_t byteOffset, float value) const;
1369+ void SetFloat64(size_t byteOffset, double value) const;
1370+ void SetInt8(size_t byteOffset, int8_t value) const;
1371+ void SetInt16(size_t byteOffset, int16_t value) const;
1372+ void SetInt32(size_t byteOffset, int32_t value) const;
1373+ void SetUint8(size_t byteOffset, uint8_t value) const;
1374+ void SetUint16(size_t byteOffset, uint16_t value) const;
1375+ void SetUint32(size_t byteOffset, uint32_t value) const;
1376+
1377+ private:
1378+ template <typename T>
1379+ T ReadData(size_t byteOffset) const;
1380+
1381+ template <typename T>
1382+ void WriteData(size_t byteOffset, T value) const;
1383+
1384+ void* _data;
1385+ size_t _length;
1386+};
1387+
1388+class Function : public Object {
1389+ public:
1390+ using VoidCallback = void (*)(const CallbackInfo& info);
1391+ using Callback = Value (*)(const CallbackInfo& info);
1392+
1393+ template <VoidCallback cb>
1394+ static Function New(napi_env env,
1395+ const char* utf8name = nullptr,
1396+ void* data = nullptr);
1397+
1398+ template <Callback cb>
1399+ static Function New(napi_env env,
1400+ const char* utf8name = nullptr,
1401+ void* data = nullptr);
1402+
1403+ template <VoidCallback cb>
1404+ static Function New(napi_env env,
1405+ const std::string& utf8name,
1406+ void* data = nullptr);
1407+
1408+ template <Callback cb>
1409+ static Function New(napi_env env,
1410+ const std::string& utf8name,
1411+ void* data = nullptr);
1412+
1413+ /// Callable must implement operator() accepting a const CallbackInfo&
1414+ /// and return either void or Value.
1415+ template <typename Callable>
1416+ static Function New(napi_env env,
1417+ Callable cb,
1418+ const char* utf8name = nullptr,
1419+ void* data = nullptr);
1420+ /// Callable must implement operator() accepting a const CallbackInfo&
1421+ /// and return either void or Value.
1422+ template <typename Callable>
1423+ static Function New(napi_env env,
1424+ Callable cb,
1425+ const std::string& utf8name,
1426+ void* data = nullptr);
1427+
1428+ static void CheckCast(napi_env env, napi_value value);
1429+
1430+ Function();
1431+ Function(napi_env env, napi_value value);
1432+
1433+ MaybeOrValue<Value> operator()(
1434+ const std::initializer_list<napi_value>& args) const;
1435+
1436+ MaybeOrValue<Value> Call(const std::initializer_list<napi_value>& args) const;
1437+ MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const;
1438+ MaybeOrValue<Value> Call(const std::vector<Value>& args) const;
1439+ MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const;
1440+ MaybeOrValue<Value> Call(napi_value recv,
1441+ const std::initializer_list<napi_value>& args) const;
1442+ MaybeOrValue<Value> Call(napi_value recv,
1443+ const std::vector<napi_value>& args) const;
1444+ MaybeOrValue<Value> Call(napi_value recv,
1445+ const std::vector<Value>& args) const;
1446+ MaybeOrValue<Value> Call(napi_value recv,
1447+ size_t argc,
1448+ const napi_value* args) const;
1449+
1450+ MaybeOrValue<Value> MakeCallback(
1451+ napi_value recv,
1452+ const std::initializer_list<napi_value>& args,
1453+ napi_async_context context = nullptr) const;
1454+ MaybeOrValue<Value> MakeCallback(napi_value recv,
1455+ const std::vector<napi_value>& args,
1456+ napi_async_context context = nullptr) const;
1457+ MaybeOrValue<Value> MakeCallback(napi_value recv,
1458+ size_t argc,
1459+ const napi_value* args,
1460+ napi_async_context context = nullptr) const;
1461+
1462+ MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const;
1463+ MaybeOrValue<Object> New(const std::vector<napi_value>& args) const;
1464+ MaybeOrValue<Object> New(size_t argc, const napi_value* args) const;
1465+};
1466+
1467+class Promise : public Object {
1468+ public:
1469+ class Deferred {
1470+ public:
1471+ static Deferred New(napi_env env);
1472+ Deferred(napi_env env);
1473+
1474+ Napi::Promise Promise() const;
1475+ Napi::Env Env() const;
1476+
1477+ void Resolve(napi_value value) const;
1478+ void Reject(napi_value value) const;
1479+
1480+ private:
1481+ napi_env _env;
1482+ napi_deferred _deferred;
1483+ napi_value _promise;
1484+ };
1485+
1486+ static void CheckCast(napi_env env, napi_value value);
1487+
1488+ Promise(napi_env env, napi_value value);
1489+};
1490+
1491+template <typename T>
1492+class Buffer : public Uint8Array {
1493+ public:
1494+ static Buffer<T> New(napi_env env, size_t length);
1495+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1496+ static Buffer<T> New(napi_env env, T* data, size_t length);
1497+
1498+ // Finalizer must implement `void operator()(Env env, T* data)`.
1499+ template <typename Finalizer>
1500+ static Buffer<T> New(napi_env env,
1501+ T* data,
1502+ size_t length,
1503+ Finalizer finalizeCallback);
1504+ // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1505+ template <typename Finalizer, typename Hint>
1506+ static Buffer<T> New(napi_env env,
1507+ T* data,
1508+ size_t length,
1509+ Finalizer finalizeCallback,
1510+ Hint* finalizeHint);
1511+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1512+
1513+ static Buffer<T> NewOrCopy(napi_env env, T* data, size_t length);
1514+ // Finalizer must implement `void operator()(Env env, T* data)`.
1515+ template <typename Finalizer>
1516+ static Buffer<T> NewOrCopy(napi_env env,
1517+ T* data,
1518+ size_t length,
1519+ Finalizer finalizeCallback);
1520+ // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1521+ template <typename Finalizer, typename Hint>
1522+ static Buffer<T> NewOrCopy(napi_env env,
1523+ T* data,
1524+ size_t length,
1525+ Finalizer finalizeCallback,
1526+ Hint* finalizeHint);
1527+
1528+ static Buffer<T> Copy(napi_env env, const T* data, size_t length);
1529+
1530+ static void CheckCast(napi_env env, napi_value value);
1531+
1532+ Buffer();
1533+ Buffer(napi_env env, napi_value value);
1534+ size_t Length() const;
1535+ T* Data() const;
1536+
1537+ private:
1538+};
1539+
1540+/// Holds a counted reference to a value; initially a weak reference unless
1541+/// otherwise specified, may be changed to/from a strong reference by adjusting
1542+/// the refcount.
1543+///
1544+/// The referenced value is not immediately destroyed when the reference count
1545+/// is zero; it is merely then eligible for garbage-collection if there are no
1546+/// other references to the value.
1547+template <typename T>
1548+class Reference {
1549+ public:
1550+ static Reference<T> New(const T& value, uint32_t initialRefcount = 0);
1551+
1552+ Reference();
1553+ Reference(napi_env env, napi_ref ref);
1554+ ~Reference();
1555+
1556+ // A reference can be moved but cannot be copied.
1557+ Reference(Reference<T>&& other);
1558+ Reference<T>& operator=(Reference<T>&& other);
1559+ NAPI_DISALLOW_ASSIGN(Reference<T>)
1560+
1561+ operator napi_ref() const;
1562+ bool operator==(const Reference<T>& other) const;
1563+ bool operator!=(const Reference<T>& other) const;
1564+
1565+ Napi::Env Env() const;
1566+ bool IsEmpty() const;
1567+
1568+ // Note when getting the value of a Reference it is usually correct to do so
1569+ // within a HandleScope so that the value handle gets cleaned up efficiently.
1570+ T Value() const;
1571+
1572+ uint32_t Ref() const;
1573+ uint32_t Unref() const;
1574+ void Reset();
1575+ void Reset(const T& value, uint32_t refcount = 0);
1576+
1577+ // Call this on a reference that is declared as static data, to prevent its
1578+ // destructor from running at program shutdown time, which would attempt to
1579+ // reset the reference when the environment is no longer valid. Avoid using
1580+ // this if at all possible. If you do need to use static data, MAKE SURE to
1581+ // warn your users that your addon is NOT threadsafe.
1582+ void SuppressDestruct();
1583+
1584+ protected:
1585+ Reference(const Reference<T>&);
1586+
1587+ /// !cond INTERNAL
1588+ napi_env _env;
1589+ napi_ref _ref;
1590+ /// !endcond
1591+
1592+ private:
1593+ bool _suppressDestruct;
1594+};
1595+
1596+class ObjectReference : public Reference<Object> {
1597+ public:
1598+ ObjectReference();
1599+ ObjectReference(napi_env env, napi_ref ref);
1600+
1601+ // A reference can be moved but cannot be copied.
1602+ ObjectReference(Reference<Object>&& other);
1603+ ObjectReference& operator=(Reference<Object>&& other);
1604+ ObjectReference(ObjectReference&& other);
1605+ ObjectReference& operator=(ObjectReference&& other);
1606+ NAPI_DISALLOW_ASSIGN(ObjectReference)
1607+
1608+ MaybeOrValue<Napi::Value> Get(const char* utf8name) const;
1609+ MaybeOrValue<Napi::Value> Get(const std::string& utf8name) const;
1610+ MaybeOrValue<bool> Set(const char* utf8name, napi_value value) const;
1611+ MaybeOrValue<bool> Set(const char* utf8name, Napi::Value value) const;
1612+ MaybeOrValue<bool> Set(const char* utf8name, const char* utf8value) const;
1613+ MaybeOrValue<bool> Set(const char* utf8name, bool boolValue) const;
1614+ MaybeOrValue<bool> Set(const char* utf8name, double numberValue) const;
1615+ MaybeOrValue<bool> Set(const std::string& utf8name, napi_value value) const;
1616+ MaybeOrValue<bool> Set(const std::string& utf8name, Napi::Value value) const;
1617+ MaybeOrValue<bool> Set(const std::string& utf8name,
1618+ std::string& utf8value) const;
1619+ MaybeOrValue<bool> Set(const std::string& utf8name, bool boolValue) const;
1620+ MaybeOrValue<bool> Set(const std::string& utf8name, double numberValue) const;
1621+
1622+ MaybeOrValue<Napi::Value> Get(uint32_t index) const;
1623+ MaybeOrValue<bool> Set(uint32_t index, const napi_value value) const;
1624+ MaybeOrValue<bool> Set(uint32_t index, const Napi::Value value) const;
1625+ MaybeOrValue<bool> Set(uint32_t index, const char* utf8value) const;
1626+ MaybeOrValue<bool> Set(uint32_t index, const std::string& utf8value) const;
1627+ MaybeOrValue<bool> Set(uint32_t index, bool boolValue) const;
1628+ MaybeOrValue<bool> Set(uint32_t index, double numberValue) const;
1629+
1630+ protected:
1631+ ObjectReference(const ObjectReference&);
1632+};
1633+
1634+class FunctionReference : public Reference<Function> {
1635+ public:
1636+ FunctionReference();
1637+ FunctionReference(napi_env env, napi_ref ref);
1638+
1639+ // A reference can be moved but cannot be copied.
1640+ FunctionReference(Reference<Function>&& other);
1641+ FunctionReference& operator=(Reference<Function>&& other);
1642+ FunctionReference(FunctionReference&& other);
1643+ FunctionReference& operator=(FunctionReference&& other);
1644+ NAPI_DISALLOW_ASSIGN_COPY(FunctionReference)
1645+
1646+ MaybeOrValue<Napi::Value> operator()(
1647+ const std::initializer_list<napi_value>& args) const;
1648+
1649+ MaybeOrValue<Napi::Value> Call(
1650+ const std::initializer_list<napi_value>& args) const;
1651+ MaybeOrValue<Napi::Value> Call(const std::vector<napi_value>& args) const;
1652+ MaybeOrValue<Napi::Value> Call(
1653+ napi_value recv, const std::initializer_list<napi_value>& args) const;
1654+ MaybeOrValue<Napi::Value> Call(napi_value recv,
1655+ const std::vector<napi_value>& args) const;
1656+ MaybeOrValue<Napi::Value> Call(napi_value recv,
1657+ size_t argc,
1658+ const napi_value* args) const;
1659+
1660+ MaybeOrValue<Napi::Value> MakeCallback(
1661+ napi_value recv,
1662+ const std::initializer_list<napi_value>& args,
1663+ napi_async_context context = nullptr) const;
1664+ MaybeOrValue<Napi::Value> MakeCallback(
1665+ napi_value recv,
1666+ const std::vector<napi_value>& args,
1667+ napi_async_context context = nullptr) const;
1668+ MaybeOrValue<Napi::Value> MakeCallback(
1669+ napi_value recv,
1670+ size_t argc,
1671+ const napi_value* args,
1672+ napi_async_context context = nullptr) const;
1673+
1674+ MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const;
1675+ MaybeOrValue<Object> New(const std::vector<napi_value>& args) const;
1676+};
1677+
1678+// Shortcuts to creating a new reference with inferred type and refcount = 0.
1679+template <typename T>
1680+Reference<T> Weak(T value);
1681+ObjectReference Weak(Object value);
1682+FunctionReference Weak(Function value);
1683+
1684+// Shortcuts to creating a new reference with inferred type and refcount = 1.
1685+template <typename T>
1686+Reference<T> Persistent(T value);
1687+ObjectReference Persistent(Object value);
1688+FunctionReference Persistent(Function value);
1689+
1690+/// A persistent reference to a JavaScript error object. Use of this class
1691+/// depends somewhat on whether C++ exceptions are enabled at compile time.
1692+///
1693+/// ### Handling Errors With C++ Exceptions
1694+///
1695+/// If C++ exceptions are enabled, then the `Error` class extends
1696+/// `std::exception` and enables integrated error-handling for C++ exceptions
1697+/// and JavaScript exceptions.
1698+///
1699+/// If a Node-API call fails without executing any JavaScript code (for
1700+/// example due to an invalid argument), then the Node-API wrapper
1701+/// automatically converts and throws the error as a C++ exception of type
1702+/// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API
1703+/// throws a JavaScript exception, then the Node-API wrapper automatically
1704+/// converts and throws it as a C++ exception of type `Napi::Error`.
1705+///
1706+/// If a C++ exception of type `Napi::Error` escapes from a Node-API C++
1707+/// callback, then the Node-API wrapper automatically converts and throws it
1708+/// as a JavaScript exception. Therefore, catching a C++ exception of type
1709+/// `Napi::Error` prevents a JavaScript exception from being thrown.
1710+///
1711+/// #### Example 1A - Throwing a C++ exception:
1712+///
1713+/// Napi::Env env = ...
1714+/// throw Napi::Error::New(env, "Example exception");
1715+///
1716+/// Following C++ statements will not be executed. The exception will bubble
1717+/// up as a C++ exception of type `Napi::Error`, until it is either caught
1718+/// while still in C++, or else automatically propataged as a JavaScript
1719+/// exception when the callback returns to JavaScript.
1720+///
1721+/// #### Example 2A - Propagating a Node-API C++ exception:
1722+///
1723+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1724+/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1725+///
1726+/// Following C++ statements will not be executed. The exception will bubble
1727+/// up as a C++ exception of type `Napi::Error`, until it is either caught
1728+/// while still in C++, or else automatically propagated as a JavaScript
1729+/// exception when the callback returns to JavaScript.
1730+///
1731+/// #### Example 3A - Handling a Node-API C++ exception:
1732+///
1733+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1734+/// Napi::Value result;
1735+/// try {
1736+/// result = jsFunctionThatThrows({ arg1, arg2 });
1737+/// } catch (const Napi::Error& e) {
1738+/// cerr << "Caught JavaScript exception: " + e.what();
1739+/// }
1740+///
1741+/// Since the exception was caught here, it will not be propagated as a
1742+/// JavaScript exception.
1743+///
1744+/// ### Handling Errors Without C++ Exceptions
1745+///
1746+/// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`)
1747+/// then this class does not extend `std::exception`, and APIs in the `Napi`
1748+/// namespace do not throw C++ exceptions when they fail. Instead, they raise
1749+/// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code
1750+/// should check `Value::IsEmpty()` before attempting to use a returned value,
1751+/// and may use methods on the `Env` class to check for, get, and clear a
1752+/// pending JavaScript exception. If the pending exception is not cleared, it
1753+/// will be thrown when the native callback returns to JavaScript.
1754+///
1755+/// #### Example 1B - Throwing a JS exception
1756+///
1757+/// Napi::Env env = ...
1758+/// Napi::Error::New(env, "Example
1759+/// exception").ThrowAsJavaScriptException(); return;
1760+///
1761+/// After throwing a JS exception, the code should generally return
1762+/// immediately from the native callback, after performing any necessary
1763+/// cleanup.
1764+///
1765+/// #### Example 2B - Propagating a Node-API JS exception:
1766+///
1767+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1768+/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1769+/// if (result.IsEmpty()) return;
1770+///
1771+/// An empty value result from a Node-API call indicates an error occurred,
1772+/// and a JavaScript exception is pending. To let the exception propagate, the
1773+/// code should generally return immediately from the native callback, after
1774+/// performing any necessary cleanup.
1775+///
1776+/// #### Example 3B - Handling a Node-API JS exception:
1777+///
1778+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1779+/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1780+/// if (result.IsEmpty()) {
1781+/// Napi::Error e = env.GetAndClearPendingException();
1782+/// cerr << "Caught JavaScript exception: " + e.Message();
1783+/// }
1784+///
1785+/// Since the exception was cleared here, it will not be propagated as a
1786+/// JavaScript exception after the native callback returns.
1787+class Error : public ObjectReference
1788+#ifdef NAPI_CPP_EXCEPTIONS
1789+ ,
1790+ public std::exception
1791+#endif // NAPI_CPP_EXCEPTIONS
1792+{
1793+ public:
1794+ static Error New(napi_env env);
1795+ static Error New(napi_env env, const char* message);
1796+ static Error New(napi_env env, const std::string& message);
1797+
1798+ static NAPI_NO_RETURN void Fatal(const char* location, const char* message);
1799+
1800+ Error();
1801+ Error(napi_env env, napi_value value);
1802+
1803+ // An error can be moved or copied.
1804+ Error(Error&& other);
1805+ Error& operator=(Error&& other);
1806+ Error(const Error&);
1807+ Error& operator=(const Error&);
1808+
1809+ const std::string& Message() const NAPI_NOEXCEPT;
1810+ void ThrowAsJavaScriptException() const;
1811+
1812+ Object Value() const;
1813+
1814+#ifdef NAPI_CPP_EXCEPTIONS
1815+ const char* what() const NAPI_NOEXCEPT override;
1816+#endif // NAPI_CPP_EXCEPTIONS
1817+
1818+ protected:
1819+ /// !cond INTERNAL
1820+ using create_error_fn = napi_status (*)(napi_env envb,
1821+ napi_value code,
1822+ napi_value msg,
1823+ napi_value* result);
1824+
1825+ template <typename TError>
1826+ static TError New(napi_env env,
1827+ const char* message,
1828+ size_t length,
1829+ create_error_fn create_error);
1830+ /// !endcond
1831+
1832+ private:
1833+ static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT;
1834+ mutable std::string _message;
1835+};
1836+
1837+class TypeError : public Error {
1838+ public:
1839+ static TypeError New(napi_env env, const char* message);
1840+ static TypeError New(napi_env env, const std::string& message);
1841+
1842+ TypeError();
1843+ TypeError(napi_env env, napi_value value);
1844+};
1845+
1846+class RangeError : public Error {
1847+ public:
1848+ static RangeError New(napi_env env, const char* message);
1849+ static RangeError New(napi_env env, const std::string& message);
1850+
1851+ RangeError();
1852+ RangeError(napi_env env, napi_value value);
1853+};
1854+
1855+#if NAPI_VERSION > 8
1856+class SyntaxError : public Error {
1857+ public:
1858+ static SyntaxError New(napi_env env, const char* message);
1859+ static SyntaxError New(napi_env env, const std::string& message);
1860+
1861+ SyntaxError();
1862+ SyntaxError(napi_env env, napi_value value);
1863+};
1864+#endif // NAPI_VERSION > 8
1865+
1866+class CallbackInfo {
1867+ public:
1868+ CallbackInfo(napi_env env, napi_callback_info info);
1869+ ~CallbackInfo();
1870+
1871+ // Disallow copying to prevent multiple free of _dynamicArgs
1872+ NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo)
1873+
1874+ Napi::Env Env() const;
1875+ Value NewTarget() const;
1876+ bool IsConstructCall() const;
1877+ size_t Length() const;
1878+ const Value operator[](size_t index) const;
1879+ Value This() const;
1880+ void* Data() const;
1881+ void SetData(void* data);
1882+ explicit operator napi_callback_info() const;
1883+
1884+ private:
1885+ const size_t _staticArgCount = 6;
1886+ napi_env _env;
1887+ napi_callback_info _info;
1888+ napi_value _this;
1889+ size_t _argc;
1890+ napi_value* _argv;
1891+ napi_value _staticArgs[6];
1892+ napi_value* _dynamicArgs;
1893+ void* _data;
1894+};
1895+
1896+class PropertyDescriptor {
1897+ public:
1898+ using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info);
1899+ using SetterCallback = void (*)(const Napi::CallbackInfo& info);
1900+
1901+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
1902+ template <typename Getter>
1903+ static PropertyDescriptor Accessor(
1904+ const char* utf8name,
1905+ Getter getter,
1906+ napi_property_attributes attributes = napi_default,
1907+ void* data = nullptr);
1908+ template <typename Getter>
1909+ static PropertyDescriptor Accessor(
1910+ const std::string& utf8name,
1911+ Getter getter,
1912+ napi_property_attributes attributes = napi_default,
1913+ void* data = nullptr);
1914+ template <typename Getter>
1915+ static PropertyDescriptor Accessor(
1916+ napi_value name,
1917+ Getter getter,
1918+ napi_property_attributes attributes = napi_default,
1919+ void* data = nullptr);
1920+ template <typename Getter>
1921+ static PropertyDescriptor Accessor(
1922+ Name name,
1923+ Getter getter,
1924+ napi_property_attributes attributes = napi_default,
1925+ void* data = nullptr);
1926+ template <typename Getter, typename Setter>
1927+ static PropertyDescriptor Accessor(
1928+ const char* utf8name,
1929+ Getter getter,
1930+ Setter setter,
1931+ napi_property_attributes attributes = napi_default,
1932+ void* data = nullptr);
1933+ template <typename Getter, typename Setter>
1934+ static PropertyDescriptor Accessor(
1935+ const std::string& utf8name,
1936+ Getter getter,
1937+ Setter setter,
1938+ napi_property_attributes attributes = napi_default,
1939+ void* data = nullptr);
1940+ template <typename Getter, typename Setter>
1941+ static PropertyDescriptor Accessor(
1942+ napi_value name,
1943+ Getter getter,
1944+ Setter setter,
1945+ napi_property_attributes attributes = napi_default,
1946+ void* data = nullptr);
1947+ template <typename Getter, typename Setter>
1948+ static PropertyDescriptor Accessor(
1949+ Name name,
1950+ Getter getter,
1951+ Setter setter,
1952+ napi_property_attributes attributes = napi_default,
1953+ void* data = nullptr);
1954+ template <typename Callable>
1955+ static PropertyDescriptor Function(
1956+ const char* utf8name,
1957+ Callable cb,
1958+ napi_property_attributes attributes = napi_default,
1959+ void* data = nullptr);
1960+ template <typename Callable>
1961+ static PropertyDescriptor Function(
1962+ const std::string& utf8name,
1963+ Callable cb,
1964+ napi_property_attributes attributes = napi_default,
1965+ void* data = nullptr);
1966+ template <typename Callable>
1967+ static PropertyDescriptor Function(
1968+ napi_value name,
1969+ Callable cb,
1970+ napi_property_attributes attributes = napi_default,
1971+ void* data = nullptr);
1972+ template <typename Callable>
1973+ static PropertyDescriptor Function(
1974+ Name name,
1975+ Callable cb,
1976+ napi_property_attributes attributes = napi_default,
1977+ void* data = nullptr);
1978+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
1979+
1980+ template <GetterCallback Getter>
1981+ static PropertyDescriptor Accessor(
1982+ const char* utf8name,
1983+ napi_property_attributes attributes = napi_default,
1984+ void* data = nullptr);
1985+
1986+ template <GetterCallback Getter>
1987+ static PropertyDescriptor Accessor(
1988+ const std::string& utf8name,
1989+ napi_property_attributes attributes = napi_default,
1990+ void* data = nullptr);
1991+
1992+ template <GetterCallback Getter>
1993+ static PropertyDescriptor Accessor(
1994+ Name name,
1995+ napi_property_attributes attributes = napi_default,
1996+ void* data = nullptr);
1997+
1998+ template <GetterCallback Getter, SetterCallback Setter>
1999+ static PropertyDescriptor Accessor(
2000+ const char* utf8name,
2001+ napi_property_attributes attributes = napi_default,
2002+ void* data = nullptr);
2003+
2004+ template <GetterCallback Getter, SetterCallback Setter>
2005+ static PropertyDescriptor Accessor(
2006+ const std::string& utf8name,
2007+ napi_property_attributes attributes = napi_default,
2008+ void* data = nullptr);
2009+
2010+ template <GetterCallback Getter, SetterCallback Setter>
2011+ static PropertyDescriptor Accessor(
2012+ Name name,
2013+ napi_property_attributes attributes = napi_default,
2014+ void* data = nullptr);
2015+
2016+ template <typename Getter>
2017+ static PropertyDescriptor Accessor(
2018+ Napi::Env env,
2019+ Napi::Object object,
2020+ const char* utf8name,
2021+ Getter getter,
2022+ napi_property_attributes attributes = napi_default,
2023+ void* data = nullptr);
2024+ template <typename Getter>
2025+ static PropertyDescriptor Accessor(
2026+ Napi::Env env,
2027+ Napi::Object object,
2028+ const std::string& utf8name,
2029+ Getter getter,
2030+ napi_property_attributes attributes = napi_default,
2031+ void* data = nullptr);
2032+ template <typename Getter>
2033+ static PropertyDescriptor Accessor(
2034+ Napi::Env env,
2035+ Napi::Object object,
2036+ Name name,
2037+ Getter getter,
2038+ napi_property_attributes attributes = napi_default,
2039+ void* data = nullptr);
2040+ template <typename Getter, typename Setter>
2041+ static PropertyDescriptor Accessor(
2042+ Napi::Env env,
2043+ Napi::Object object,
2044+ const char* utf8name,
2045+ Getter getter,
2046+ Setter setter,
2047+ napi_property_attributes attributes = napi_default,
2048+ void* data = nullptr);
2049+ template <typename Getter, typename Setter>
2050+ static PropertyDescriptor Accessor(
2051+ Napi::Env env,
2052+ Napi::Object object,
2053+ const std::string& utf8name,
2054+ Getter getter,
2055+ Setter setter,
2056+ napi_property_attributes attributes = napi_default,
2057+ void* data = nullptr);
2058+ template <typename Getter, typename Setter>
2059+ static PropertyDescriptor Accessor(
2060+ Napi::Env env,
2061+ Napi::Object object,
2062+ Name name,
2063+ Getter getter,
2064+ Setter setter,
2065+ napi_property_attributes attributes = napi_default,
2066+ void* data = nullptr);
2067+ template <typename Callable>
2068+ static PropertyDescriptor Function(
2069+ Napi::Env env,
2070+ Napi::Object object,
2071+ const char* utf8name,
2072+ Callable cb,
2073+ napi_property_attributes attributes = napi_default,
2074+ void* data = nullptr);
2075+ template <typename Callable>
2076+ static PropertyDescriptor Function(
2077+ Napi::Env env,
2078+ Napi::Object object,
2079+ const std::string& utf8name,
2080+ Callable cb,
2081+ napi_property_attributes attributes = napi_default,
2082+ void* data = nullptr);
2083+ template <typename Callable>
2084+ static PropertyDescriptor Function(
2085+ Napi::Env env,
2086+ Napi::Object object,
2087+ Name name,
2088+ Callable cb,
2089+ napi_property_attributes attributes = napi_default,
2090+ void* data = nullptr);
2091+ static PropertyDescriptor Value(
2092+ const char* utf8name,
2093+ napi_value value,
2094+ napi_property_attributes attributes = napi_default);
2095+ static PropertyDescriptor Value(
2096+ const std::string& utf8name,
2097+ napi_value value,
2098+ napi_property_attributes attributes = napi_default);
2099+ static PropertyDescriptor Value(
2100+ napi_value name,
2101+ napi_value value,
2102+ napi_property_attributes attributes = napi_default);
2103+ static PropertyDescriptor Value(
2104+ Name name,
2105+ Napi::Value value,
2106+ napi_property_attributes attributes = napi_default);
2107+
2108+ PropertyDescriptor(napi_property_descriptor desc);
2109+
2110+ operator napi_property_descriptor&();
2111+ operator const napi_property_descriptor&() const;
2112+
2113+ private:
2114+ napi_property_descriptor _desc;
2115+};
2116+
2117+/// Property descriptor for use with `ObjectWrap::DefineClass()`.
2118+///
2119+/// This is different from the standalone `PropertyDescriptor` because it is
2120+/// specific to each `ObjectWrap<T>` subclass. This prevents using descriptors
2121+/// from a different class when defining a new class (preventing the callbacks
2122+/// from having incorrect `this` pointers).
2123+template <typename T>
2124+class ClassPropertyDescriptor {
2125+ public:
2126+ ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {}
2127+
2128+ operator napi_property_descriptor&() { return _desc; }
2129+ operator const napi_property_descriptor&() const { return _desc; }
2130+
2131+ private:
2132+ napi_property_descriptor _desc;
2133+};
2134+
2135+template <typename T, typename TCallback>
2136+struct MethodCallbackData {
2137+ TCallback callback;
2138+ void* data;
2139+};
2140+
2141+template <typename T, typename TGetterCallback, typename TSetterCallback>
2142+struct AccessorCallbackData {
2143+ TGetterCallback getterCallback;
2144+ TSetterCallback setterCallback;
2145+ void* data;
2146+};
2147+
2148+template <typename T>
2149+class InstanceWrap {
2150+ public:
2151+ using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info);
2152+ using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info);
2153+ using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info);
2154+ using InstanceSetterCallback = void (T::*)(const CallbackInfo& info,
2155+ const Napi::Value& value);
2156+
2157+ using PropertyDescriptor = ClassPropertyDescriptor<T>;
2158+
2159+ static PropertyDescriptor InstanceMethod(
2160+ const char* utf8name,
2161+ InstanceVoidMethodCallback method,
2162+ napi_property_attributes attributes = napi_default,
2163+ void* data = nullptr);
2164+ static PropertyDescriptor InstanceMethod(
2165+ const char* utf8name,
2166+ InstanceMethodCallback method,
2167+ napi_property_attributes attributes = napi_default,
2168+ void* data = nullptr);
2169+ static PropertyDescriptor InstanceMethod(
2170+ Symbol name,
2171+ InstanceVoidMethodCallback method,
2172+ napi_property_attributes attributes = napi_default,
2173+ void* data = nullptr);
2174+ static PropertyDescriptor InstanceMethod(
2175+ Symbol name,
2176+ InstanceMethodCallback method,
2177+ napi_property_attributes attributes = napi_default,
2178+ void* data = nullptr);
2179+ template <InstanceVoidMethodCallback method>
2180+ static PropertyDescriptor InstanceMethod(
2181+ const char* utf8name,
2182+ napi_property_attributes attributes = napi_default,
2183+ void* data = nullptr);
2184+ template <InstanceMethodCallback method>
2185+ static PropertyDescriptor InstanceMethod(
2186+ const char* utf8name,
2187+ napi_property_attributes attributes = napi_default,
2188+ void* data = nullptr);
2189+ template <InstanceVoidMethodCallback method>
2190+ static PropertyDescriptor InstanceMethod(
2191+ Symbol name,
2192+ napi_property_attributes attributes = napi_default,
2193+ void* data = nullptr);
2194+ template <InstanceMethodCallback method>
2195+ static PropertyDescriptor InstanceMethod(
2196+ Symbol name,
2197+ napi_property_attributes attributes = napi_default,
2198+ void* data = nullptr);
2199+ static PropertyDescriptor InstanceAccessor(
2200+ const char* utf8name,
2201+ InstanceGetterCallback getter,
2202+ InstanceSetterCallback setter,
2203+ napi_property_attributes attributes = napi_default,
2204+ void* data = nullptr);
2205+ static PropertyDescriptor InstanceAccessor(
2206+ Symbol name,
2207+ InstanceGetterCallback getter,
2208+ InstanceSetterCallback setter,
2209+ napi_property_attributes attributes = napi_default,
2210+ void* data = nullptr);
2211+ template <InstanceGetterCallback getter,
2212+ InstanceSetterCallback setter = nullptr>
2213+ static PropertyDescriptor InstanceAccessor(
2214+ const char* utf8name,
2215+ napi_property_attributes attributes = napi_default,
2216+ void* data = nullptr);
2217+ template <InstanceGetterCallback getter,
2218+ InstanceSetterCallback setter = nullptr>
2219+ static PropertyDescriptor InstanceAccessor(
2220+ Symbol name,
2221+ napi_property_attributes attributes = napi_default,
2222+ void* data = nullptr);
2223+ static PropertyDescriptor InstanceValue(
2224+ const char* utf8name,
2225+ Napi::Value value,
2226+ napi_property_attributes attributes = napi_default);
2227+ static PropertyDescriptor InstanceValue(
2228+ Symbol name,
2229+ Napi::Value value,
2230+ napi_property_attributes attributes = napi_default);
2231+
2232+ protected:
2233+ static void AttachPropData(napi_env env,
2234+ napi_value value,
2235+ const napi_property_descriptor* prop);
2236+
2237+ private:
2238+ using This = InstanceWrap<T>;
2239+
2240+ using InstanceVoidMethodCallbackData =
2241+ MethodCallbackData<T, InstanceVoidMethodCallback>;
2242+ using InstanceMethodCallbackData =
2243+ MethodCallbackData<T, InstanceMethodCallback>;
2244+ using InstanceAccessorCallbackData =
2245+ AccessorCallbackData<T, InstanceGetterCallback, InstanceSetterCallback>;
2246+
2247+ static napi_value InstanceVoidMethodCallbackWrapper(napi_env env,
2248+ napi_callback_info info);
2249+ static napi_value InstanceMethodCallbackWrapper(napi_env env,
2250+ napi_callback_info info);
2251+ static napi_value InstanceGetterCallbackWrapper(napi_env env,
2252+ napi_callback_info info);
2253+ static napi_value InstanceSetterCallbackWrapper(napi_env env,
2254+ napi_callback_info info);
2255+
2256+ template <InstanceSetterCallback method>
2257+ static napi_value WrappedMethod(napi_env env,
2258+ napi_callback_info info) NAPI_NOEXCEPT;
2259+
2260+ template <InstanceSetterCallback setter>
2261+ struct SetterTag {};
2262+
2263+ template <InstanceSetterCallback setter>
2264+ static napi_callback WrapSetter(SetterTag<setter>) NAPI_NOEXCEPT {
2265+ return &This::WrappedMethod<setter>;
2266+ }
2267+ static napi_callback WrapSetter(SetterTag<nullptr>) NAPI_NOEXCEPT {
2268+ return nullptr;
2269+ }
2270+};
2271+
2272+/// Base class to be extended by C++ classes exposed to JavaScript; each C++
2273+/// class instance gets "wrapped" by a JavaScript object that is managed by this
2274+/// class.
2275+///
2276+/// At initialization time, the `DefineClass()` method must be used to
2277+/// hook up the accessor and method callbacks. It takes a list of
2278+/// property descriptors, which can be constructed via the various
2279+/// static methods on the base class.
2280+///
2281+/// #### Example:
2282+///
2283+/// class Example: public Napi::ObjectWrap<Example> {
2284+/// public:
2285+/// static void Initialize(Napi::Env& env, Napi::Object& target) {
2286+/// Napi::Function constructor = DefineClass(env, "Example", {
2287+/// InstanceAccessor<&Example::GetSomething,
2288+/// &Example::SetSomething>("value"),
2289+/// InstanceMethod<&Example::DoSomething>("doSomething"),
2290+/// });
2291+/// target.Set("Example", constructor);
2292+/// }
2293+///
2294+/// Example(const Napi::CallbackInfo& info); // Constructor
2295+/// Napi::Value GetSomething(const Napi::CallbackInfo& info);
2296+/// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value&
2297+/// value); Napi::Value DoSomething(const Napi::CallbackInfo& info);
2298+/// }
2299+template <typename T>
2300+class ObjectWrap : public InstanceWrap<T>, public Reference<Object> {
2301+ public:
2302+ ObjectWrap(const CallbackInfo& callbackInfo);
2303+ virtual ~ObjectWrap();
2304+
2305+ static T* Unwrap(Object wrapper);
2306+
2307+ // Methods exposed to JavaScript must conform to one of these callback
2308+ // signatures.
2309+ using StaticVoidMethodCallback = void (*)(const CallbackInfo& info);
2310+ using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info);
2311+ using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info);
2312+ using StaticSetterCallback = void (*)(const CallbackInfo& info,
2313+ const Napi::Value& value);
2314+
2315+ using PropertyDescriptor = ClassPropertyDescriptor<T>;
2316+
2317+ static Function DefineClass(
2318+ Napi::Env env,
2319+ const char* utf8name,
2320+ const std::initializer_list<PropertyDescriptor>& properties,
2321+ void* data = nullptr);
2322+ static Function DefineClass(Napi::Env env,
2323+ const char* utf8name,
2324+ const std::vector<PropertyDescriptor>& properties,
2325+ void* data = nullptr);
2326+ static PropertyDescriptor StaticMethod(
2327+ const char* utf8name,
2328+ StaticVoidMethodCallback method,
2329+ napi_property_attributes attributes = napi_default,
2330+ void* data = nullptr);
2331+ static PropertyDescriptor StaticMethod(
2332+ const char* utf8name,
2333+ StaticMethodCallback method,
2334+ napi_property_attributes attributes = napi_default,
2335+ void* data = nullptr);
2336+ static PropertyDescriptor StaticMethod(
2337+ Symbol name,
2338+ StaticVoidMethodCallback method,
2339+ napi_property_attributes attributes = napi_default,
2340+ void* data = nullptr);
2341+ static PropertyDescriptor StaticMethod(
2342+ Symbol name,
2343+ StaticMethodCallback method,
2344+ napi_property_attributes attributes = napi_default,
2345+ void* data = nullptr);
2346+ template <StaticVoidMethodCallback method>
2347+ static PropertyDescriptor StaticMethod(
2348+ const char* utf8name,
2349+ napi_property_attributes attributes = napi_default,
2350+ void* data = nullptr);
2351+ template <StaticVoidMethodCallback method>
2352+ static PropertyDescriptor StaticMethod(
2353+ Symbol name,
2354+ napi_property_attributes attributes = napi_default,
2355+ void* data = nullptr);
2356+ template <StaticMethodCallback method>
2357+ static PropertyDescriptor StaticMethod(
2358+ const char* utf8name,
2359+ napi_property_attributes attributes = napi_default,
2360+ void* data = nullptr);
2361+ template <StaticMethodCallback method>
2362+ static PropertyDescriptor StaticMethod(
2363+ Symbol name,
2364+ napi_property_attributes attributes = napi_default,
2365+ void* data = nullptr);
2366+ static PropertyDescriptor StaticAccessor(
2367+ const char* utf8name,
2368+ StaticGetterCallback getter,
2369+ StaticSetterCallback setter,
2370+ napi_property_attributes attributes = napi_default,
2371+ void* data = nullptr);
2372+ static PropertyDescriptor StaticAccessor(
2373+ Symbol name,
2374+ StaticGetterCallback getter,
2375+ StaticSetterCallback setter,
2376+ napi_property_attributes attributes = napi_default,
2377+ void* data = nullptr);
2378+ template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr>
2379+ static PropertyDescriptor StaticAccessor(
2380+ const char* utf8name,
2381+ napi_property_attributes attributes = napi_default,
2382+ void* data = nullptr);
2383+ template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr>
2384+ static PropertyDescriptor StaticAccessor(
2385+ Symbol name,
2386+ napi_property_attributes attributes = napi_default,
2387+ void* data = nullptr);
2388+ static PropertyDescriptor StaticValue(
2389+ const char* utf8name,
2390+ Napi::Value value,
2391+ napi_property_attributes attributes = napi_default);
2392+ static PropertyDescriptor StaticValue(
2393+ Symbol name,
2394+ Napi::Value value,
2395+ napi_property_attributes attributes = napi_default);
2396+ static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
2397+ virtual void Finalize(Napi::Env env);
2398+
2399+ private:
2400+ using This = ObjectWrap<T>;
2401+
2402+ static napi_value ConstructorCallbackWrapper(napi_env env,
2403+ napi_callback_info info);
2404+ static napi_value StaticVoidMethodCallbackWrapper(napi_env env,
2405+ napi_callback_info info);
2406+ static napi_value StaticMethodCallbackWrapper(napi_env env,
2407+ napi_callback_info info);
2408+ static napi_value StaticGetterCallbackWrapper(napi_env env,
2409+ napi_callback_info info);
2410+ static napi_value StaticSetterCallbackWrapper(napi_env env,
2411+ napi_callback_info info);
2412+ static void FinalizeCallback(napi_env env, void* data, void* hint);
2413+ static Function DefineClass(Napi::Env env,
2414+ const char* utf8name,
2415+ const size_t props_count,
2416+ const napi_property_descriptor* props,
2417+ void* data = nullptr);
2418+
2419+ using StaticVoidMethodCallbackData =
2420+ MethodCallbackData<T, StaticVoidMethodCallback>;
2421+ using StaticMethodCallbackData = MethodCallbackData<T, StaticMethodCallback>;
2422+
2423+ using StaticAccessorCallbackData =
2424+ AccessorCallbackData<T, StaticGetterCallback, StaticSetterCallback>;
2425+
2426+ template <StaticSetterCallback method>
2427+ static napi_value WrappedMethod(napi_env env,
2428+ napi_callback_info info) NAPI_NOEXCEPT;
2429+
2430+ template <StaticSetterCallback setter>
2431+ struct StaticSetterTag {};
2432+
2433+ template <StaticSetterCallback setter>
2434+ static napi_callback WrapStaticSetter(StaticSetterTag<setter>) NAPI_NOEXCEPT {
2435+ return &This::WrappedMethod<setter>;
2436+ }
2437+ static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>)
2438+ NAPI_NOEXCEPT {
2439+ return nullptr;
2440+ }
2441+
2442+ bool _construction_failed = true;
2443+};
2444+
2445+class HandleScope {
2446+ public:
2447+ HandleScope(napi_env env, napi_handle_scope scope);
2448+ explicit HandleScope(Napi::Env env);
2449+ ~HandleScope();
2450+
2451+ // Disallow copying to prevent double close of napi_handle_scope
2452+ NAPI_DISALLOW_ASSIGN_COPY(HandleScope)
2453+
2454+ operator napi_handle_scope() const;
2455+
2456+ Napi::Env Env() const;
2457+
2458+ private:
2459+ napi_env _env;
2460+ napi_handle_scope _scope;
2461+};
2462+
2463+class EscapableHandleScope {
2464+ public:
2465+ EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope);
2466+ explicit EscapableHandleScope(Napi::Env env);
2467+ ~EscapableHandleScope();
2468+
2469+ // Disallow copying to prevent double close of napi_escapable_handle_scope
2470+ NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope)
2471+
2472+ operator napi_escapable_handle_scope() const;
2473+
2474+ Napi::Env Env() const;
2475+ Value Escape(napi_value escapee);
2476+
2477+ private:
2478+ napi_env _env;
2479+ napi_escapable_handle_scope _scope;
2480+};
2481+
2482+#if (NAPI_VERSION > 2)
2483+class CallbackScope {
2484+ public:
2485+ CallbackScope(napi_env env, napi_callback_scope scope);
2486+ CallbackScope(napi_env env, napi_async_context context);
2487+ virtual ~CallbackScope();
2488+
2489+ // Disallow copying to prevent double close of napi_callback_scope
2490+ NAPI_DISALLOW_ASSIGN_COPY(CallbackScope)
2491+
2492+ operator napi_callback_scope() const;
2493+
2494+ Napi::Env Env() const;
2495+
2496+ private:
2497+ napi_env _env;
2498+ napi_callback_scope _scope;
2499+};
2500+#endif
2501+
2502+class AsyncContext {
2503+ public:
2504+ explicit AsyncContext(napi_env env, const char* resource_name);
2505+ explicit AsyncContext(napi_env env,
2506+ const char* resource_name,
2507+ const Object& resource);
2508+ virtual ~AsyncContext();
2509+
2510+ AsyncContext(AsyncContext&& other);
2511+ AsyncContext& operator=(AsyncContext&& other);
2512+ NAPI_DISALLOW_ASSIGN_COPY(AsyncContext)
2513+
2514+ operator napi_async_context() const;
2515+
2516+ Napi::Env Env() const;
2517+
2518+ private:
2519+ napi_env _env;
2520+ napi_async_context _context;
2521+};
2522+
2523+#if NAPI_HAS_THREADS
2524+class AsyncWorker {
2525+ public:
2526+ virtual ~AsyncWorker();
2527+
2528+ NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker)
2529+
2530+ operator napi_async_work() const;
2531+
2532+ Napi::Env Env() const;
2533+
2534+ void Queue();
2535+ void Cancel();
2536+ void SuppressDestruct();
2537+
2538+ ObjectReference& Receiver();
2539+ FunctionReference& Callback();
2540+
2541+ virtual void OnExecute(Napi::Env env);
2542+ virtual void OnWorkComplete(Napi::Env env, napi_status status);
2543+
2544+ protected:
2545+ explicit AsyncWorker(const Function& callback);
2546+ explicit AsyncWorker(const Function& callback, const char* resource_name);
2547+ explicit AsyncWorker(const Function& callback,
2548+ const char* resource_name,
2549+ const Object& resource);
2550+ explicit AsyncWorker(const Object& receiver, const Function& callback);
2551+ explicit AsyncWorker(const Object& receiver,
2552+ const Function& callback,
2553+ const char* resource_name);
2554+ explicit AsyncWorker(const Object& receiver,
2555+ const Function& callback,
2556+ const char* resource_name,
2557+ const Object& resource);
2558+
2559+ explicit AsyncWorker(Napi::Env env);
2560+ explicit AsyncWorker(Napi::Env env, const char* resource_name);
2561+ explicit AsyncWorker(Napi::Env env,
2562+ const char* resource_name,
2563+ const Object& resource);
2564+
2565+ virtual void Execute() = 0;
2566+ virtual void OnOK();
2567+ virtual void OnError(const Error& e);
2568+ virtual void Destroy();
2569+ virtual std::vector<napi_value> GetResult(Napi::Env env);
2570+
2571+ void SetError(const std::string& error);
2572+
2573+ private:
2574+ static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker);
2575+ static inline void OnAsyncWorkComplete(napi_env env,
2576+ napi_status status,
2577+ void* asyncworker);
2578+
2579+ napi_env _env;
2580+ napi_async_work _work;
2581+ ObjectReference _receiver;
2582+ FunctionReference _callback;
2583+ std::string _error;
2584+ bool _suppress_destruct;
2585+};
2586+#endif // NAPI_HAS_THREADS
2587+
2588+#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS)
2589+class ThreadSafeFunction {
2590+ public:
2591+ // This API may only be called from the main thread.
2592+ template <typename ResourceString>
2593+ static ThreadSafeFunction New(napi_env env,
2594+ const Function& callback,
2595+ ResourceString resourceName,
2596+ size_t maxQueueSize,
2597+ size_t initialThreadCount);
2598+
2599+ // This API may only be called from the main thread.
2600+ template <typename ResourceString, typename ContextType>
2601+ static ThreadSafeFunction New(napi_env env,
2602+ const Function& callback,
2603+ ResourceString resourceName,
2604+ size_t maxQueueSize,
2605+ size_t initialThreadCount,
2606+ ContextType* context);
2607+
2608+ // This API may only be called from the main thread.
2609+ template <typename ResourceString, typename Finalizer>
2610+ static ThreadSafeFunction New(napi_env env,
2611+ const Function& callback,
2612+ ResourceString resourceName,
2613+ size_t maxQueueSize,
2614+ size_t initialThreadCount,
2615+ Finalizer finalizeCallback);
2616+
2617+ // This API may only be called from the main thread.
2618+ template <typename ResourceString,
2619+ typename Finalizer,
2620+ typename FinalizerDataType>
2621+ static ThreadSafeFunction New(napi_env env,
2622+ const Function& callback,
2623+ ResourceString resourceName,
2624+ size_t maxQueueSize,
2625+ size_t initialThreadCount,
2626+ Finalizer finalizeCallback,
2627+ FinalizerDataType* data);
2628+
2629+ // This API may only be called from the main thread.
2630+ template <typename ResourceString, typename ContextType, typename Finalizer>
2631+ static ThreadSafeFunction New(napi_env env,
2632+ const Function& callback,
2633+ ResourceString resourceName,
2634+ size_t maxQueueSize,
2635+ size_t initialThreadCount,
2636+ ContextType* context,
2637+ Finalizer finalizeCallback);
2638+
2639+ // This API may only be called from the main thread.
2640+ template <typename ResourceString,
2641+ typename ContextType,
2642+ typename Finalizer,
2643+ typename FinalizerDataType>
2644+ static ThreadSafeFunction New(napi_env env,
2645+ const Function& callback,
2646+ ResourceString resourceName,
2647+ size_t maxQueueSize,
2648+ size_t initialThreadCount,
2649+ ContextType* context,
2650+ Finalizer finalizeCallback,
2651+ FinalizerDataType* data);
2652+
2653+ // This API may only be called from the main thread.
2654+ template <typename ResourceString>
2655+ static ThreadSafeFunction New(napi_env env,
2656+ const Function& callback,
2657+ const Object& resource,
2658+ ResourceString resourceName,
2659+ size_t maxQueueSize,
2660+ size_t initialThreadCount);
2661+
2662+ // This API may only be called from the main thread.
2663+ template <typename ResourceString, typename ContextType>
2664+ static ThreadSafeFunction New(napi_env env,
2665+ const Function& callback,
2666+ const Object& resource,
2667+ ResourceString resourceName,
2668+ size_t maxQueueSize,
2669+ size_t initialThreadCount,
2670+ ContextType* context);
2671+
2672+ // This API may only be called from the main thread.
2673+ template <typename ResourceString, typename Finalizer>
2674+ static ThreadSafeFunction New(napi_env env,
2675+ const Function& callback,
2676+ const Object& resource,
2677+ ResourceString resourceName,
2678+ size_t maxQueueSize,
2679+ size_t initialThreadCount,
2680+ Finalizer finalizeCallback);
2681+
2682+ // This API may only be called from the main thread.
2683+ template <typename ResourceString,
2684+ typename Finalizer,
2685+ typename FinalizerDataType>
2686+ static ThreadSafeFunction New(napi_env env,
2687+ const Function& callback,
2688+ const Object& resource,
2689+ ResourceString resourceName,
2690+ size_t maxQueueSize,
2691+ size_t initialThreadCount,
2692+ Finalizer finalizeCallback,
2693+ FinalizerDataType* data);
2694+
2695+ // This API may only be called from the main thread.
2696+ template <typename ResourceString, typename ContextType, typename Finalizer>
2697+ static ThreadSafeFunction New(napi_env env,
2698+ const Function& callback,
2699+ const Object& resource,
2700+ ResourceString resourceName,
2701+ size_t maxQueueSize,
2702+ size_t initialThreadCount,
2703+ ContextType* context,
2704+ Finalizer finalizeCallback);
2705+
2706+ // This API may only be called from the main thread.
2707+ template <typename ResourceString,
2708+ typename ContextType,
2709+ typename Finalizer,
2710+ typename FinalizerDataType>
2711+ static ThreadSafeFunction New(napi_env env,
2712+ const Function& callback,
2713+ const Object& resource,
2714+ ResourceString resourceName,
2715+ size_t maxQueueSize,
2716+ size_t initialThreadCount,
2717+ ContextType* context,
2718+ Finalizer finalizeCallback,
2719+ FinalizerDataType* data);
2720+
2721+ ThreadSafeFunction();
2722+ ThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2723+
2724+ operator napi_threadsafe_function() const;
2725+
2726+ // This API may be called from any thread.
2727+ napi_status BlockingCall() const;
2728+
2729+ // This API may be called from any thread.
2730+ template <typename Callback>
2731+ napi_status BlockingCall(Callback callback) const;
2732+
2733+ // This API may be called from any thread.
2734+ template <typename DataType, typename Callback>
2735+ napi_status BlockingCall(DataType* data, Callback callback) const;
2736+
2737+ // This API may be called from any thread.
2738+ napi_status NonBlockingCall() const;
2739+
2740+ // This API may be called from any thread.
2741+ template <typename Callback>
2742+ napi_status NonBlockingCall(Callback callback) const;
2743+
2744+ // This API may be called from any thread.
2745+ template <typename DataType, typename Callback>
2746+ napi_status NonBlockingCall(DataType* data, Callback callback) const;
2747+
2748+ // This API may only be called from the main thread.
2749+ void Ref(napi_env env) const;
2750+
2751+ // This API may only be called from the main thread.
2752+ void Unref(napi_env env) const;
2753+
2754+ // This API may be called from any thread.
2755+ napi_status Acquire() const;
2756+
2757+ // This API may be called from any thread.
2758+ napi_status Release() const;
2759+
2760+ // This API may be called from any thread.
2761+ napi_status Abort() const;
2762+
2763+ struct ConvertibleContext {
2764+ template <class T>
2765+ operator T*() {
2766+ return static_cast<T*>(context);
2767+ }
2768+ void* context;
2769+ };
2770+
2771+ // This API may be called from any thread.
2772+ ConvertibleContext GetContext() const;
2773+
2774+ private:
2775+ using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>;
2776+
2777+ template <typename ResourceString,
2778+ typename ContextType,
2779+ typename Finalizer,
2780+ typename FinalizerDataType>
2781+ static ThreadSafeFunction New(napi_env env,
2782+ const Function& callback,
2783+ const Object& resource,
2784+ ResourceString resourceName,
2785+ size_t maxQueueSize,
2786+ size_t initialThreadCount,
2787+ ContextType* context,
2788+ Finalizer finalizeCallback,
2789+ FinalizerDataType* data,
2790+ napi_finalize wrapper);
2791+
2792+ napi_status CallInternal(CallbackWrapper* callbackWrapper,
2793+ napi_threadsafe_function_call_mode mode) const;
2794+
2795+ static void CallJS(napi_env env,
2796+ napi_value jsCallback,
2797+ void* context,
2798+ void* data);
2799+
2800+ napi_threadsafe_function _tsfn;
2801+};
2802+
2803+// A TypedThreadSafeFunction by default has no context (nullptr) and can
2804+// accept any type (void) to its CallJs.
2805+template <typename ContextType = std::nullptr_t,
2806+ typename DataType = void,
2807+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) =
2808+ nullptr>
2809+class TypedThreadSafeFunction {
2810+ public:
2811+ // This API may only be called from the main thread.
2812+ // Helper function that returns nullptr if running Node-API 5+, otherwise a
2813+ // non-empty, no-op Function. This provides the ability to specify at
2814+ // compile-time a callback parameter to `New` that safely does no action
2815+ // when targeting _any_ Node-API version.
2816+#if NAPI_VERSION > 4
2817+ static std::nullptr_t EmptyFunctionFactory(Napi::Env env);
2818+#else
2819+ static Napi::Function EmptyFunctionFactory(Napi::Env env);
2820+#endif
2821+ static Napi::Function FunctionOrEmpty(Napi::Env env,
2822+ Napi::Function& callback);
2823+
2824+#if NAPI_VERSION > 4
2825+ // This API may only be called from the main thread.
2826+ // Creates a new threadsafe function with:
2827+ // Callback [missing] Resource [missing] Finalizer [missing]
2828+ template <typename ResourceString>
2829+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2830+ napi_env env,
2831+ ResourceString resourceName,
2832+ size_t maxQueueSize,
2833+ size_t initialThreadCount,
2834+ ContextType* context = nullptr);
2835+
2836+ // This API may only be called from the main thread.
2837+ // Creates a new threadsafe function with:
2838+ // Callback [missing] Resource [passed] Finalizer [missing]
2839+ template <typename ResourceString>
2840+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2841+ napi_env env,
2842+ const Object& resource,
2843+ ResourceString resourceName,
2844+ size_t maxQueueSize,
2845+ size_t initialThreadCount,
2846+ ContextType* context = nullptr);
2847+
2848+ // This API may only be called from the main thread.
2849+ // Creates a new threadsafe function with:
2850+ // Callback [missing] Resource [missing] Finalizer [passed]
2851+ template <typename ResourceString,
2852+ typename Finalizer,
2853+ typename FinalizerDataType = void>
2854+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2855+ napi_env env,
2856+ ResourceString resourceName,
2857+ size_t maxQueueSize,
2858+ size_t initialThreadCount,
2859+ ContextType* context,
2860+ Finalizer finalizeCallback,
2861+ FinalizerDataType* data = nullptr);
2862+
2863+ // This API may only be called from the main thread.
2864+ // Creates a new threadsafe function with:
2865+ // Callback [missing] Resource [passed] Finalizer [passed]
2866+ template <typename ResourceString,
2867+ typename Finalizer,
2868+ typename FinalizerDataType = void>
2869+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2870+ napi_env env,
2871+ const Object& resource,
2872+ ResourceString resourceName,
2873+ size_t maxQueueSize,
2874+ size_t initialThreadCount,
2875+ ContextType* context,
2876+ Finalizer finalizeCallback,
2877+ FinalizerDataType* data = nullptr);
2878+#endif
2879+
2880+ // This API may only be called from the main thread.
2881+ // Creates a new threadsafe function with:
2882+ // Callback [passed] Resource [missing] Finalizer [missing]
2883+ template <typename ResourceString>
2884+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2885+ napi_env env,
2886+ const Function& callback,
2887+ ResourceString resourceName,
2888+ size_t maxQueueSize,
2889+ size_t initialThreadCount,
2890+ ContextType* context = nullptr);
2891+
2892+ // This API may only be called from the main thread.
2893+ // Creates a new threadsafe function with:
2894+ // Callback [passed] Resource [passed] Finalizer [missing]
2895+ template <typename ResourceString>
2896+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2897+ napi_env env,
2898+ const Function& callback,
2899+ const Object& resource,
2900+ ResourceString resourceName,
2901+ size_t maxQueueSize,
2902+ size_t initialThreadCount,
2903+ ContextType* context = nullptr);
2904+
2905+ // This API may only be called from the main thread.
2906+ // Creates a new threadsafe function with:
2907+ // Callback [passed] Resource [missing] Finalizer [passed]
2908+ template <typename ResourceString,
2909+ typename Finalizer,
2910+ typename FinalizerDataType = void>
2911+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2912+ napi_env env,
2913+ const Function& callback,
2914+ ResourceString resourceName,
2915+ size_t maxQueueSize,
2916+ size_t initialThreadCount,
2917+ ContextType* context,
2918+ Finalizer finalizeCallback,
2919+ FinalizerDataType* data = nullptr);
2920+
2921+ // This API may only be called from the main thread.
2922+ // Creates a new threadsafe function with:
2923+ // Callback [passed] Resource [passed] Finalizer [passed]
2924+ template <typename CallbackType,
2925+ typename ResourceString,
2926+ typename Finalizer,
2927+ typename FinalizerDataType>
2928+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2929+ napi_env env,
2930+ CallbackType callback,
2931+ const Object& resource,
2932+ ResourceString resourceName,
2933+ size_t maxQueueSize,
2934+ size_t initialThreadCount,
2935+ ContextType* context,
2936+ Finalizer finalizeCallback,
2937+ FinalizerDataType* data = nullptr);
2938+
2939+ TypedThreadSafeFunction();
2940+ TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2941+
2942+ operator napi_threadsafe_function() const;
2943+
2944+ // This API may be called from any thread.
2945+ napi_status BlockingCall(DataType* data = nullptr) const;
2946+
2947+ // This API may be called from any thread.
2948+ napi_status NonBlockingCall(DataType* data = nullptr) const;
2949+
2950+ // This API may only be called from the main thread.
2951+ void Ref(napi_env env) const;
2952+
2953+ // This API may only be called from the main thread.
2954+ void Unref(napi_env env) const;
2955+
2956+ // This API may be called from any thread.
2957+ napi_status Acquire() const;
2958+
2959+ // This API may be called from any thread.
2960+ napi_status Release() const;
2961+
2962+ // This API may be called from any thread.
2963+ napi_status Abort() const;
2964+
2965+ // This API may be called from any thread.
2966+ ContextType* GetContext() const;
2967+
2968+ private:
2969+ template <typename ResourceString,
2970+ typename Finalizer,
2971+ typename FinalizerDataType>
2972+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2973+ napi_env env,
2974+ const Function& callback,
2975+ const Object& resource,
2976+ ResourceString resourceName,
2977+ size_t maxQueueSize,
2978+ size_t initialThreadCount,
2979+ ContextType* context,
2980+ Finalizer finalizeCallback,
2981+ FinalizerDataType* data,
2982+ napi_finalize wrapper);
2983+
2984+ static void CallJsInternal(napi_env env,
2985+ napi_value jsCallback,
2986+ void* context,
2987+ void* data);
2988+
2989+ protected:
2990+ napi_threadsafe_function _tsfn;
2991+};
2992+template <typename DataType>
2993+class AsyncProgressWorkerBase : public AsyncWorker {
2994+ public:
2995+ virtual void OnWorkProgress(DataType* data) = 0;
2996+ class ThreadSafeData {
2997+ public:
2998+ ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data)
2999+ : _asyncprogressworker(asyncprogressworker), _data(data) {}
3000+
3001+ AsyncProgressWorkerBase* asyncprogressworker() {
3002+ return _asyncprogressworker;
3003+ };
3004+ DataType* data() { return _data; };
3005+
3006+ private:
3007+ AsyncProgressWorkerBase* _asyncprogressworker;
3008+ DataType* _data;
3009+ };
3010+ void OnWorkComplete(Napi::Env env, napi_status status) override;
3011+
3012+ protected:
3013+ explicit AsyncProgressWorkerBase(const Object& receiver,
3014+ const Function& callback,
3015+ const char* resource_name,
3016+ const Object& resource,
3017+ size_t queue_size = 1);
3018+ virtual ~AsyncProgressWorkerBase();
3019+
3020+// Optional callback of Napi::ThreadSafeFunction only available after
3021+// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3022+#if NAPI_VERSION > 4
3023+ explicit AsyncProgressWorkerBase(Napi::Env env,
3024+ const char* resource_name,
3025+ const Object& resource,
3026+ size_t queue_size = 1);
3027+#endif
3028+
3029+ static inline void OnAsyncWorkProgress(Napi::Env env,
3030+ Napi::Function jsCallback,
3031+ void* data);
3032+
3033+ napi_status NonBlockingCall(DataType* data);
3034+
3035+ private:
3036+ ThreadSafeFunction _tsfn;
3037+ bool _work_completed = false;
3038+ napi_status _complete_status;
3039+ static inline void OnThreadSafeFunctionFinalize(
3040+ Napi::Env env, void* data, AsyncProgressWorkerBase* context);
3041+};
3042+
3043+template <class T>
3044+class AsyncProgressWorker : public AsyncProgressWorkerBase<void> {
3045+ public:
3046+ virtual ~AsyncProgressWorker();
3047+
3048+ class ExecutionProgress {
3049+ friend class AsyncProgressWorker;
3050+
3051+ public:
3052+ void Signal() const;
3053+ void Send(const T* data, size_t count) const;
3054+
3055+ private:
3056+ explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {}
3057+ AsyncProgressWorker* const _worker;
3058+ };
3059+
3060+ void OnWorkProgress(void*) override;
3061+
3062+ protected:
3063+ explicit AsyncProgressWorker(const Function& callback);
3064+ explicit AsyncProgressWorker(const Function& callback,
3065+ const char* resource_name);
3066+ explicit AsyncProgressWorker(const Function& callback,
3067+ const char* resource_name,
3068+ const Object& resource);
3069+ explicit AsyncProgressWorker(const Object& receiver,
3070+ const Function& callback);
3071+ explicit AsyncProgressWorker(const Object& receiver,
3072+ const Function& callback,
3073+ const char* resource_name);
3074+ explicit AsyncProgressWorker(const Object& receiver,
3075+ const Function& callback,
3076+ const char* resource_name,
3077+ const Object& resource);
3078+
3079+// Optional callback of Napi::ThreadSafeFunction only available after
3080+// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3081+#if NAPI_VERSION > 4
3082+ explicit AsyncProgressWorker(Napi::Env env);
3083+ explicit AsyncProgressWorker(Napi::Env env, const char* resource_name);
3084+ explicit AsyncProgressWorker(Napi::Env env,
3085+ const char* resource_name,
3086+ const Object& resource);
3087+#endif
3088+ virtual void Execute(const ExecutionProgress& progress) = 0;
3089+ virtual void OnProgress(const T* data, size_t count) = 0;
3090+
3091+ private:
3092+ void Execute() override;
3093+ void Signal();
3094+ void SendProgress_(const T* data, size_t count);
3095+
3096+ std::mutex _mutex;
3097+ T* _asyncdata;
3098+ size_t _asyncsize;
3099+ bool _signaled;
3100+};
3101+
3102+template <class T>
3103+class AsyncProgressQueueWorker
3104+ : public AsyncProgressWorkerBase<std::pair<T*, size_t>> {
3105+ public:
3106+ virtual ~AsyncProgressQueueWorker(){};
3107+
3108+ class ExecutionProgress {
3109+ friend class AsyncProgressQueueWorker;
3110+
3111+ public:
3112+ void Signal() const;
3113+ void Send(const T* data, size_t count) const;
3114+
3115+ private:
3116+ explicit ExecutionProgress(AsyncProgressQueueWorker* worker)
3117+ : _worker(worker) {}
3118+ AsyncProgressQueueWorker* const _worker;
3119+ };
3120+
3121+ void OnWorkComplete(Napi::Env env, napi_status status) override;
3122+ void OnWorkProgress(std::pair<T*, size_t>*) override;
3123+
3124+ protected:
3125+ explicit AsyncProgressQueueWorker(const Function& callback);
3126+ explicit AsyncProgressQueueWorker(const Function& callback,
3127+ const char* resource_name);
3128+ explicit AsyncProgressQueueWorker(const Function& callback,
3129+ const char* resource_name,
3130+ const Object& resource);
3131+ explicit AsyncProgressQueueWorker(const Object& receiver,
3132+ const Function& callback);
3133+ explicit AsyncProgressQueueWorker(const Object& receiver,
3134+ const Function& callback,
3135+ const char* resource_name);
3136+ explicit AsyncProgressQueueWorker(const Object& receiver,
3137+ const Function& callback,
3138+ const char* resource_name,
3139+ const Object& resource);
3140+
3141+// Optional callback of Napi::ThreadSafeFunction only available after
3142+// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3143+#if NAPI_VERSION > 4
3144+ explicit AsyncProgressQueueWorker(Napi::Env env);
3145+ explicit AsyncProgressQueueWorker(Napi::Env env, const char* resource_name);
3146+ explicit AsyncProgressQueueWorker(Napi::Env env,
3147+ const char* resource_name,
3148+ const Object& resource);
3149+#endif
3150+ virtual void Execute(const ExecutionProgress& progress) = 0;
3151+ virtual void OnProgress(const T* data, size_t count) = 0;
3152+
3153+ private:
3154+ void Execute() override;
3155+ void Signal() const;
3156+ void SendProgress_(const T* data, size_t count);
3157+};
3158+#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS
3159+
3160+// Memory management.
3161+class MemoryManagement {
3162+ public:
3163+ static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
3164+};
3165+
3166+// Version management
3167+class VersionManagement {
3168+ public:
3169+ static uint32_t GetNapiVersion(Env env);
3170+ static const napi_node_version* GetNodeVersion(Env env);
3171+};
3172+
3173+#if NAPI_VERSION > 5
3174+template <typename T>
3175+class Addon : public InstanceWrap<T> {
3176+ public:
3177+ static inline Object Init(Env env, Object exports);
3178+ static T* Unwrap(Object wrapper);
3179+
3180+ protected:
3181+ using AddonProp = ClassPropertyDescriptor<T>;
3182+ void DefineAddon(Object exports,
3183+ const std::initializer_list<AddonProp>& props);
3184+ Napi::Object DefineProperties(Object object,
3185+ const std::initializer_list<AddonProp>& props);
3186+
3187+ private:
3188+ Object entry_point_;
3189+};
3190+#endif // NAPI_VERSION > 5
3191+
3192+#ifdef NAPI_CPP_CUSTOM_NAMESPACE
3193+} // namespace NAPI_CPP_CUSTOM_NAMESPACE
3194+#endif
3195+
3196+} // namespace Napi
3197+
3198+// Inline implementations of all the above class methods are included here.
3199+#include "napi-inl.h"
3200+
3201+#endif // SRC_NAPI_H_
@@ -0,0 +1,3201 @@
1+#ifndef SRC_NAPI_H_
2+#define SRC_NAPI_H_
3+
4+#ifndef NAPI_HAS_THREADS
5+#if !defined(__wasm__) || (defined(__EMSCRIPTEN_PTHREADS__) || \
6+ (defined(__wasi__) && defined(_REENTRANT)))
7+#define NAPI_HAS_THREADS 1
8+#else
9+#define NAPI_HAS_THREADS 0
10+#endif
11+#endif
12+
13+#include <node_api.h>
14+#include <functional>
15+#include <initializer_list>
16+#include <memory>
17+#if NAPI_HAS_THREADS
18+#include <mutex>
19+#endif // NAPI_HAS_THREADS
20+#include <string>
21+#include <vector>
22+
23+// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known
24+// good version)
25+#if !defined(_MSC_VER) || _MSC_FULL_VER >= 190024210
26+#define NAPI_HAS_CONSTEXPR 1
27+#endif
28+
29+// VS2013 does not support char16_t literal strings, so we'll work around it
30+// using wchar_t strings and casting them. This is safe as long as the character
31+// sizes are the same.
32+#if defined(_MSC_VER) && _MSC_VER <= 1800
33+static_assert(sizeof(char16_t) == sizeof(wchar_t),
34+ "Size mismatch between char16_t and wchar_t");
35+#define NAPI_WIDE_TEXT(x) reinterpret_cast<char16_t*>(L##x)
36+#else
37+#define NAPI_WIDE_TEXT(x) u##x
38+#endif
39+
40+// If C++ exceptions are not explicitly enabled or disabled, enable them
41+// if exceptions were enabled in the compiler settings.
42+#if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
43+#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
44+#define NAPI_CPP_EXCEPTIONS
45+#else
46+#error Exception support not detected. \
47+ Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS.
48+#endif
49+#endif
50+
51+// If C++ NAPI_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE should
52+// not be set
53+#if defined(NAPI_CPP_EXCEPTIONS) && defined(NODE_ADDON_API_ENABLE_MAYBE)
54+#error NODE_ADDON_API_ENABLE_MAYBE should not be set when \
55+ NAPI_CPP_EXCEPTIONS is defined.
56+#endif
57+
58+#ifdef _NOEXCEPT
59+#define NAPI_NOEXCEPT _NOEXCEPT
60+#else
61+#define NAPI_NOEXCEPT noexcept
62+#endif
63+
64+#ifdef NAPI_CPP_EXCEPTIONS
65+
66+// When C++ exceptions are enabled, Errors are thrown directly. There is no need
67+// to return anything after the throw statements. The variadic parameter is an
68+// optional return value that is ignored.
69+// We need _VOID versions of the macros to avoid warnings resulting from
70+// leaving the NAPI_THROW_* `...` argument empty.
71+
72+#define NAPI_THROW(e, ...) throw e
73+#define NAPI_THROW_VOID(e) throw e
74+
75+#define NAPI_THROW_IF_FAILED(env, status, ...) \
76+ if ((status) != napi_ok) throw Napi::Error::New(env);
77+
78+#define NAPI_THROW_IF_FAILED_VOID(env, status) \
79+ if ((status) != napi_ok) throw Napi::Error::New(env);
80+
81+#else // NAPI_CPP_EXCEPTIONS
82+
83+// When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
84+// which are pending until the callback returns to JS. The variadic parameter
85+// is an optional return value; usually it is an empty result.
86+// We need _VOID versions of the macros to avoid warnings resulting from
87+// leaving the NAPI_THROW_* `...` argument empty.
88+
89+#define NAPI_THROW(e, ...) \
90+ do { \
91+ (e).ThrowAsJavaScriptException(); \
92+ return __VA_ARGS__; \
93+ } while (0)
94+
95+#define NAPI_THROW_VOID(e) \
96+ do { \
97+ (e).ThrowAsJavaScriptException(); \
98+ return; \
99+ } while (0)
100+
101+#define NAPI_THROW_IF_FAILED(env, status, ...) \
102+ if ((status) != napi_ok) { \
103+ Napi::Error::New(env).ThrowAsJavaScriptException(); \
104+ return __VA_ARGS__; \
105+ }
106+
107+#define NAPI_THROW_IF_FAILED_VOID(env, status) \
108+ if ((status) != napi_ok) { \
109+ Napi::Error::New(env).ThrowAsJavaScriptException(); \
110+ return; \
111+ }
112+
113+#endif // NAPI_CPP_EXCEPTIONS
114+
115+#ifdef NODE_ADDON_API_ENABLE_MAYBE
116+#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
117+ NAPI_THROW_IF_FAILED(env, status, Napi::Nothing<type>())
118+
119+#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \
120+ NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \
121+ return Napi::Just<type>(result);
122+#else
123+#define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
124+ NAPI_THROW_IF_FAILED(env, status, type())
125+
126+#define NAPI_RETURN_OR_THROW_IF_FAILED(env, status, result, type) \
127+ NAPI_MAYBE_THROW_IF_FAILED(env, status, type); \
128+ return result;
129+#endif
130+
131+#define NAPI_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
132+#define NAPI_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
133+
134+#define NAPI_DISALLOW_ASSIGN_COPY(CLASS) \
135+ NAPI_DISALLOW_ASSIGN(CLASS) \
136+ NAPI_DISALLOW_COPY(CLASS)
137+
138+#define NAPI_CHECK(condition, location, message) \
139+ do { \
140+ if (!(condition)) { \
141+ Napi::Error::Fatal((location), (message)); \
142+ } \
143+ } while (0)
144+
145+#define NAPI_FATAL_IF_FAILED(status, location, message) \
146+ NAPI_CHECK((status) == napi_ok, location, message)
147+
148+////////////////////////////////////////////////////////////////////////////////
149+/// Node-API C++ Wrapper Classes
150+///
151+/// These classes wrap the "Node-API" ABI-stable C APIs for Node.js, providing a
152+/// C++ object model and C++ exception-handling semantics with low overhead.
153+/// The wrappers are all header-only so that they do not affect the ABI.
154+////////////////////////////////////////////////////////////////////////////////
155+namespace Napi {
156+
157+#ifdef NAPI_CPP_CUSTOM_NAMESPACE
158+// NAPI_CPP_CUSTOM_NAMESPACE can be #define'd per-addon to avoid symbol
159+// conflicts between different instances of node-addon-api
160+
161+// First dummy definition of the namespace to make sure that Napi::(name) still
162+// refers to the right things inside this file.
163+namespace NAPI_CPP_CUSTOM_NAMESPACE {}
164+using namespace NAPI_CPP_CUSTOM_NAMESPACE;
165+
166+namespace NAPI_CPP_CUSTOM_NAMESPACE {
167+#endif
168+
169+// Forward declarations
170+class Env;
171+class Value;
172+class Boolean;
173+class Number;
174+#if NAPI_VERSION > 5
175+class BigInt;
176+#endif // NAPI_VERSION > 5
177+#if (NAPI_VERSION > 4)
178+class Date;
179+#endif
180+class String;
181+class Object;
182+class Array;
183+class ArrayBuffer;
184+class Function;
185+class Error;
186+class PropertyDescriptor;
187+class CallbackInfo;
188+class TypedArray;
189+template <typename T>
190+class TypedArrayOf;
191+
192+using Int8Array =
193+ TypedArrayOf<int8_t>; ///< Typed-array of signed 8-bit integers
194+using Uint8Array =
195+ TypedArrayOf<uint8_t>; ///< Typed-array of unsigned 8-bit integers
196+using Int16Array =
197+ TypedArrayOf<int16_t>; ///< Typed-array of signed 16-bit integers
198+using Uint16Array =
199+ TypedArrayOf<uint16_t>; ///< Typed-array of unsigned 16-bit integers
200+using Int32Array =
201+ TypedArrayOf<int32_t>; ///< Typed-array of signed 32-bit integers
202+using Uint32Array =
203+ TypedArrayOf<uint32_t>; ///< Typed-array of unsigned 32-bit integers
204+using Float32Array =
205+ TypedArrayOf<float>; ///< Typed-array of 32-bit floating-point values
206+using Float64Array =
207+ TypedArrayOf<double>; ///< Typed-array of 64-bit floating-point values
208+#if NAPI_VERSION > 5
209+using BigInt64Array =
210+ TypedArrayOf<int64_t>; ///< Typed array of signed 64-bit integers
211+using BigUint64Array =
212+ TypedArrayOf<uint64_t>; ///< Typed array of unsigned 64-bit integers
213+#endif // NAPI_VERSION > 5
214+
215+/// Defines the signature of a Node-API C++ module's registration callback
216+/// (init) function.
217+using ModuleRegisterCallback = Object (*)(Env env, Object exports);
218+
219+class MemoryManagement;
220+
221+/// A simple Maybe type, representing an object which may or may not have a
222+/// value.
223+///
224+/// If an API method returns a Maybe<>, the API method can potentially fail
225+/// either because an exception is thrown, or because an exception is pending,
226+/// e.g. because a previous API call threw an exception that hasn't been
227+/// caught yet. In that case, a "Nothing" value is returned.
228+template <class T>
229+class Maybe {
230+ public:
231+ bool IsNothing() const;
232+ bool IsJust() const;
233+
234+ /// Short-hand for Unwrap(), which doesn't return a value. Could be used
235+ /// where the actual value of the Maybe is not needed like Object::Set.
236+ /// If this Maybe is nothing (empty), node-addon-api will crash the
237+ /// process.
238+ void Check() const;
239+
240+ /// Return the value of type T contained in the Maybe. If this Maybe is
241+ /// nothing (empty), node-addon-api will crash the process.
242+ T Unwrap() const;
243+
244+ /// Return the value of type T contained in the Maybe, or using a default
245+ /// value if this Maybe is nothing (empty).
246+ T UnwrapOr(const T& default_value) const;
247+
248+ /// Converts this Maybe to a value of type T in the out. If this Maybe is
249+ /// nothing (empty), `false` is returned and `out` is left untouched.
250+ bool UnwrapTo(T* out) const;
251+
252+ bool operator==(const Maybe& other) const;
253+ bool operator!=(const Maybe& other) const;
254+
255+ private:
256+ Maybe();
257+ explicit Maybe(const T& t);
258+
259+ bool _has_value;
260+ T _value;
261+
262+ template <class U>
263+ friend Maybe<U> Nothing();
264+ template <class U>
265+ friend Maybe<U> Just(const U& u);
266+};
267+
268+template <class T>
269+inline Maybe<T> Nothing();
270+
271+template <class T>
272+inline Maybe<T> Just(const T& t);
273+
274+#if defined(NODE_ADDON_API_ENABLE_MAYBE)
275+template <typename T>
276+using MaybeOrValue = Maybe<T>;
277+#else
278+template <typename T>
279+using MaybeOrValue = T;
280+#endif
281+
282+/// Environment for Node-API values and operations.
283+///
284+/// All Node-API values and operations must be associated with an environment.
285+/// An environment instance is always provided to callback functions; that
286+/// environment must then be used for any creation of Node-API values or other
287+/// Node-API operations within the callback. (Many methods infer the
288+/// environment from the `this` instance that the method is called on.)
289+///
290+/// In the future, multiple environments per process may be supported,
291+/// although current implementations only support one environment per process.
292+///
293+/// In the V8 JavaScript engine, a Node-API environment approximately
294+/// corresponds to an Isolate.
295+class Env {
296+ private:
297+ napi_env _env;
298+#if NAPI_VERSION > 5
299+ template <typename T>
300+ static void DefaultFini(Env, T* data);
301+ template <typename DataType, typename HintType>
302+ static void DefaultFiniWithHint(Env, DataType* data, HintType* hint);
303+#endif // NAPI_VERSION > 5
304+ public:
305+ Env(napi_env env);
306+
307+ operator napi_env() const;
308+
309+ Object Global() const;
310+ Value Undefined() const;
311+ Value Null() const;
312+
313+ bool IsExceptionPending() const;
314+ Error GetAndClearPendingException() const;
315+
316+ MaybeOrValue<Value> RunScript(const char* utf8script) const;
317+ MaybeOrValue<Value> RunScript(const std::string& utf8script) const;
318+ MaybeOrValue<Value> RunScript(String script) const;
319+
320+#if NAPI_VERSION > 2
321+ template <typename Hook, typename Arg = void>
322+ class CleanupHook;
323+
324+ template <typename Hook>
325+ CleanupHook<Hook> AddCleanupHook(Hook hook);
326+
327+ template <typename Hook, typename Arg>
328+ CleanupHook<Hook, Arg> AddCleanupHook(Hook hook, Arg* arg);
329+#endif // NAPI_VERSION > 2
330+
331+#if NAPI_VERSION > 5
332+ template <typename T>
333+ T* GetInstanceData() const;
334+
335+ template <typename T>
336+ using Finalizer = void (*)(Env, T*);
337+ template <typename T, Finalizer<T> fini = Env::DefaultFini<T>>
338+ void SetInstanceData(T* data) const;
339+
340+ template <typename DataType, typename HintType>
341+ using FinalizerWithHint = void (*)(Env, DataType*, HintType*);
342+ template <typename DataType,
343+ typename HintType,
344+ FinalizerWithHint<DataType, HintType> fini =
345+ Env::DefaultFiniWithHint<DataType, HintType>>
346+ void SetInstanceData(DataType* data, HintType* hint) const;
347+#endif // NAPI_VERSION > 5
348+
349+#if NAPI_VERSION > 2
350+ template <typename Hook, typename Arg>
351+ class CleanupHook {
352+ public:
353+ CleanupHook();
354+ CleanupHook(Env env, Hook hook, Arg* arg);
355+ CleanupHook(Env env, Hook hook);
356+ bool Remove(Env env);
357+ bool IsEmpty() const;
358+
359+ private:
360+ static inline void Wrapper(void* data) NAPI_NOEXCEPT;
361+ static inline void WrapperWithArg(void* data) NAPI_NOEXCEPT;
362+
363+ void (*wrapper)(void* arg);
364+ struct CleanupData {
365+ Hook hook;
366+ Arg* arg;
367+ } * data;
368+ };
369+#endif // NAPI_VERSION > 2
370+
371+#if NAPI_VERSION > 8
372+ const char* GetModuleFileName() const;
373+#endif // NAPI_VERSION > 8
374+};
375+
376+/// A JavaScript value of unknown type.
377+///
378+/// For type-specific operations, convert to one of the Value subclasses using a
379+/// `To*` or `As()` method. The `To*` methods do type coercion; the `As()`
380+/// method does not.
381+///
382+/// Napi::Value value = ...
383+/// if (!value.IsString()) throw Napi::TypeError::New(env, "Invalid
384+/// arg..."); Napi::String str = value.As<Napi::String>(); // Cast to a
385+/// string value
386+///
387+/// Napi::Value anotherValue = ...
388+/// bool isTruthy = anotherValue.ToBoolean(); // Coerce to a boolean value
389+class Value {
390+ public:
391+ Value(); ///< Creates a new _empty_ Value instance.
392+ Value(napi_env env,
393+ napi_value value); ///< Wraps a Node-API value primitive.
394+
395+ /// Creates a JS value from a C++ primitive.
396+ ///
397+ /// `value` may be any of:
398+ /// - bool
399+ /// - Any integer type
400+ /// - Any floating point type
401+ /// - const char* (encoded using UTF-8, null-terminated)
402+ /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
403+ /// - std::string (encoded using UTF-8)
404+ /// - std::u16string
405+ /// - napi::Value
406+ /// - napi_value
407+ template <typename T>
408+ static Value From(napi_env env, const T& value);
409+
410+ /// Converts to a Node-API value primitive.
411+ ///
412+ /// If the instance is _empty_, this returns `nullptr`.
413+ operator napi_value() const;
414+
415+ /// Tests if this value strictly equals another value.
416+ bool operator==(const Value& other) const;
417+
418+ /// Tests if this value does not strictly equal another value.
419+ bool operator!=(const Value& other) const;
420+
421+ /// Tests if this value strictly equals another value.
422+ bool StrictEquals(const Value& other) const;
423+
424+ /// Gets the environment the value is associated with.
425+ Napi::Env Env() const;
426+
427+ /// Checks if the value is empty (uninitialized).
428+ ///
429+ /// An empty value is invalid, and most attempts to perform an operation on an
430+ /// empty value will result in an exception. Note an empty value is distinct
431+ /// from JavaScript `null` or `undefined`, which are valid values.
432+ ///
433+ /// When C++ exceptions are disabled at compile time, a method with a `Value`
434+ /// return type may return an empty value to indicate a pending exception. So
435+ /// when not using C++ exceptions, callers should check whether the value is
436+ /// empty before attempting to use it.
437+ bool IsEmpty() const;
438+
439+ napi_valuetype Type() const; ///< Gets the type of the value.
440+
441+ bool IsUndefined()
442+ const; ///< Tests if a value is an undefined JavaScript value.
443+ bool IsNull() const; ///< Tests if a value is a null JavaScript value.
444+ bool IsBoolean() const; ///< Tests if a value is a JavaScript boolean.
445+ bool IsNumber() const; ///< Tests if a value is a JavaScript number.
446+#if NAPI_VERSION > 5
447+ bool IsBigInt() const; ///< Tests if a value is a JavaScript bigint.
448+#endif // NAPI_VERSION > 5
449+#if (NAPI_VERSION > 4)
450+ bool IsDate() const; ///< Tests if a value is a JavaScript date.
451+#endif
452+ bool IsString() const; ///< Tests if a value is a JavaScript string.
453+ bool IsSymbol() const; ///< Tests if a value is a JavaScript symbol.
454+ bool IsArray() const; ///< Tests if a value is a JavaScript array.
455+ bool IsArrayBuffer()
456+ const; ///< Tests if a value is a JavaScript array buffer.
457+ bool IsTypedArray() const; ///< Tests if a value is a JavaScript typed array.
458+ bool IsObject() const; ///< Tests if a value is a JavaScript object.
459+ bool IsFunction() const; ///< Tests if a value is a JavaScript function.
460+ bool IsPromise() const; ///< Tests if a value is a JavaScript promise.
461+ bool IsDataView() const; ///< Tests if a value is a JavaScript data view.
462+ bool IsBuffer() const; ///< Tests if a value is a Node buffer.
463+ bool IsExternal() const; ///< Tests if a value is a pointer to external data.
464+
465+ /// Casts to another type of `Napi::Value`, when the actual type is known or
466+ /// assumed.
467+ ///
468+ /// This conversion does NOT coerce the type. Calling any methods
469+ /// inappropriate for the actual value type will throw `Napi::Error`.
470+ ///
471+ /// If `NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS` is defined, this method
472+ /// asserts that the actual type is the expected type.
473+ template <typename T>
474+ T As() const;
475+
476+ MaybeOrValue<Boolean> ToBoolean()
477+ const; ///< Coerces a value to a JavaScript boolean.
478+ MaybeOrValue<Number> ToNumber()
479+ const; ///< Coerces a value to a JavaScript number.
480+ MaybeOrValue<String> ToString()
481+ const; ///< Coerces a value to a JavaScript string.
482+ MaybeOrValue<Object> ToObject()
483+ const; ///< Coerces a value to a JavaScript object.
484+
485+ protected:
486+ /// !cond INTERNAL
487+ napi_env _env;
488+ napi_value _value;
489+ /// !endcond
490+};
491+
492+/// A JavaScript boolean value.
493+class Boolean : public Value {
494+ public:
495+ static Boolean New(napi_env env, ///< Node-API environment
496+ bool value ///< Boolean value
497+ );
498+
499+ static void CheckCast(napi_env env, napi_value value);
500+
501+ Boolean(); ///< Creates a new _empty_ Boolean instance.
502+ Boolean(napi_env env,
503+ napi_value value); ///< Wraps a Node-API value primitive.
504+
505+ operator bool() const; ///< Converts a Boolean value to a boolean primitive.
506+ bool Value() const; ///< Converts a Boolean value to a boolean primitive.
507+};
508+
509+/// A JavaScript number value.
510+class Number : public Value {
511+ public:
512+ static Number New(napi_env env, ///< Node-API environment
513+ double value ///< Number value
514+ );
515+
516+ static void CheckCast(napi_env env, napi_value value);
517+
518+ Number(); ///< Creates a new _empty_ Number instance.
519+ Number(napi_env env,
520+ napi_value value); ///< Wraps a Node-API value primitive.
521+
522+ operator int32_t()
523+ const; ///< Converts a Number value to a 32-bit signed integer value.
524+ operator uint32_t()
525+ const; ///< Converts a Number value to a 32-bit unsigned integer value.
526+ operator int64_t()
527+ const; ///< Converts a Number value to a 64-bit signed integer value.
528+ operator float()
529+ const; ///< Converts a Number value to a 32-bit floating-point value.
530+ operator double()
531+ const; ///< Converts a Number value to a 64-bit floating-point value.
532+
533+ int32_t Int32Value()
534+ const; ///< Converts a Number value to a 32-bit signed integer value.
535+ uint32_t Uint32Value()
536+ const; ///< Converts a Number value to a 32-bit unsigned integer value.
537+ int64_t Int64Value()
538+ const; ///< Converts a Number value to a 64-bit signed integer value.
539+ float FloatValue()
540+ const; ///< Converts a Number value to a 32-bit floating-point value.
541+ double DoubleValue()
542+ const; ///< Converts a Number value to a 64-bit floating-point value.
543+};
544+
545+#if NAPI_VERSION > 5
546+/// A JavaScript bigint value.
547+class BigInt : public Value {
548+ public:
549+ static BigInt New(napi_env env, ///< Node-API environment
550+ int64_t value ///< Number value
551+ );
552+ static BigInt New(napi_env env, ///< Node-API environment
553+ uint64_t value ///< Number value
554+ );
555+
556+ /// Creates a new BigInt object using a specified sign bit and a
557+ /// specified list of digits/words.
558+ /// The resulting number is calculated as:
559+ /// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
560+ static BigInt New(napi_env env, ///< Node-API environment
561+ int sign_bit, ///< Sign bit. 1 if negative.
562+ size_t word_count, ///< Number of words in array
563+ const uint64_t* words ///< Array of words
564+ );
565+
566+ static void CheckCast(napi_env env, napi_value value);
567+
568+ BigInt(); ///< Creates a new _empty_ BigInt instance.
569+ BigInt(napi_env env,
570+ napi_value value); ///< Wraps a Node-API value primitive.
571+
572+ int64_t Int64Value(bool* lossless)
573+ const; ///< Converts a BigInt value to a 64-bit signed integer value.
574+ uint64_t Uint64Value(bool* lossless)
575+ const; ///< Converts a BigInt value to a 64-bit unsigned integer value.
576+
577+ size_t WordCount() const; ///< The number of 64-bit words needed to store
578+ ///< the result of ToWords().
579+
580+ /// Writes the contents of this BigInt to a specified memory location.
581+ /// `sign_bit` must be provided and will be set to 1 if this BigInt is
582+ /// negative.
583+ /// `*word_count` has to be initialized to the length of the `words` array.
584+ /// Upon return, it will be set to the actual number of words that would
585+ /// be needed to store this BigInt (i.e. the return value of `WordCount()`).
586+ void ToWords(int* sign_bit, size_t* word_count, uint64_t* words);
587+};
588+#endif // NAPI_VERSION > 5
589+
590+#if (NAPI_VERSION > 4)
591+/// A JavaScript date value.
592+class Date : public Value {
593+ public:
594+ /// Creates a new Date value from a double primitive.
595+ static Date New(napi_env env, ///< Node-API environment
596+ double value ///< Number value
597+ );
598+
599+ static void CheckCast(napi_env env, napi_value value);
600+
601+ Date(); ///< Creates a new _empty_ Date instance.
602+ Date(napi_env env, napi_value value); ///< Wraps a Node-API value primitive.
603+ operator double() const; ///< Converts a Date value to double primitive
604+
605+ double ValueOf() const; ///< Converts a Date value to a double primitive.
606+};
607+#endif
608+
609+/// A JavaScript string or symbol value (that can be used as a property name).
610+class Name : public Value {
611+ public:
612+ static void CheckCast(napi_env env, napi_value value);
613+
614+ Name(); ///< Creates a new _empty_ Name instance.
615+ Name(napi_env env,
616+ napi_value value); ///< Wraps a Node-API value primitive.
617+};
618+
619+/// A JavaScript string value.
620+class String : public Name {
621+ public:
622+ /// Creates a new String value from a UTF-8 encoded C++ string.
623+ static String New(napi_env env, ///< Node-API environment
624+ const std::string& value ///< UTF-8 encoded C++ string
625+ );
626+
627+ /// Creates a new String value from a UTF-16 encoded C++ string.
628+ static String New(napi_env env, ///< Node-API environment
629+ const std::u16string& value ///< UTF-16 encoded C++ string
630+ );
631+
632+ /// Creates a new String value from a UTF-8 encoded C string.
633+ static String New(
634+ napi_env env, ///< Node-API environment
635+ const char* value ///< UTF-8 encoded null-terminated C string
636+ );
637+
638+ /// Creates a new String value from a UTF-16 encoded C string.
639+ static String New(
640+ napi_env env, ///< Node-API environment
641+ const char16_t* value ///< UTF-16 encoded null-terminated C string
642+ );
643+
644+ /// Creates a new String value from a UTF-8 encoded C string with specified
645+ /// length.
646+ static String New(napi_env env, ///< Node-API environment
647+ const char* value, ///< UTF-8 encoded C string (not
648+ ///< necessarily null-terminated)
649+ size_t length ///< length of the string in bytes
650+ );
651+
652+ /// Creates a new String value from a UTF-16 encoded C string with specified
653+ /// length.
654+ static String New(
655+ napi_env env, ///< Node-API environment
656+ const char16_t* value, ///< UTF-16 encoded C string (not necessarily
657+ ///< null-terminated)
658+ size_t length ///< Length of the string in 2-byte code units
659+ );
660+
661+ /// Creates a new String based on the original object's type.
662+ ///
663+ /// `value` may be any of:
664+ /// - const char* (encoded using UTF-8, null-terminated)
665+ /// - const char16_t* (encoded using UTF-16-LE, null-terminated)
666+ /// - std::string (encoded using UTF-8)
667+ /// - std::u16string
668+ template <typename T>
669+ static String From(napi_env env, const T& value);
670+
671+ static void CheckCast(napi_env env, napi_value value);
672+
673+ String(); ///< Creates a new _empty_ String instance.
674+ String(napi_env env,
675+ napi_value value); ///< Wraps a Node-API value primitive.
676+
677+ operator std::string()
678+ const; ///< Converts a String value to a UTF-8 encoded C++ string.
679+ operator std::u16string()
680+ const; ///< Converts a String value to a UTF-16 encoded C++ string.
681+ std::string Utf8Value()
682+ const; ///< Converts a String value to a UTF-8 encoded C++ string.
683+ std::u16string Utf16Value()
684+ const; ///< Converts a String value to a UTF-16 encoded C++ string.
685+};
686+
687+/// A JavaScript symbol value.
688+class Symbol : public Name {
689+ public:
690+ /// Creates a new Symbol value with an optional description.
691+ static Symbol New(
692+ napi_env env, ///< Node-API environment
693+ const char* description =
694+ nullptr ///< Optional UTF-8 encoded null-terminated C string
695+ /// describing the symbol
696+ );
697+
698+ /// Creates a new Symbol value with a description.
699+ static Symbol New(
700+ napi_env env, ///< Node-API environment
701+ const std::string&
702+ description ///< UTF-8 encoded C++ string describing the symbol
703+ );
704+
705+ /// Creates a new Symbol value with a description.
706+ static Symbol New(napi_env env, ///< Node-API environment
707+ String description ///< String value describing the symbol
708+ );
709+
710+ /// Creates a new Symbol value with a description.
711+ static Symbol New(
712+ napi_env env, ///< Node-API environment
713+ napi_value description ///< String value describing the symbol
714+ );
715+
716+ /// Get a public Symbol (e.g. Symbol.iterator).
717+ static MaybeOrValue<Symbol> WellKnown(napi_env, const std::string& name);
718+
719+ // Create a symbol in the global registry, UTF-8 Encoded cpp string
720+ static MaybeOrValue<Symbol> For(napi_env env, const std::string& description);
721+
722+ // Create a symbol in the global registry, C style string (null terminated)
723+ static MaybeOrValue<Symbol> For(napi_env env, const char* description);
724+
725+ // Create a symbol in the global registry, String value describing the symbol
726+ static MaybeOrValue<Symbol> For(napi_env env, String description);
727+
728+ // Create a symbol in the global registry, napi_value describing the symbol
729+ static MaybeOrValue<Symbol> For(napi_env env, napi_value description);
730+
731+ static void CheckCast(napi_env env, napi_value value);
732+
733+ Symbol(); ///< Creates a new _empty_ Symbol instance.
734+ Symbol(napi_env env,
735+ napi_value value); ///< Wraps a Node-API value primitive.
736+};
737+
738+class TypeTaggable : public Value {
739+ public:
740+#if NAPI_VERSION >= 8
741+ void TypeTag(const napi_type_tag* type_tag) const;
742+ bool CheckTypeTag(const napi_type_tag* type_tag) const;
743+#endif // NAPI_VERSION >= 8
744+ protected:
745+ TypeTaggable();
746+ TypeTaggable(napi_env env, napi_value value);
747+};
748+
749+/// A JavaScript object value.
750+class Object : public TypeTaggable {
751+ public:
752+ /// Enables property and element assignments using indexing syntax.
753+ ///
754+ /// This is a convenient helper to get and set object properties. As
755+ /// getting and setting object properties may throw with JavaScript
756+ /// exceptions, it is notable that these operations may fail.
757+ /// When NODE_ADDON_API_ENABLE_MAYBE is defined, the process will abort
758+ /// on JavaScript exceptions.
759+ ///
760+ /// Example:
761+ ///
762+ /// Napi::Value propertyValue = object1['A'];
763+ /// object2['A'] = propertyValue;
764+ /// Napi::Value elementValue = array[0];
765+ /// array[1] = elementValue;
766+ template <typename Key>
767+ class PropertyLValue {
768+ public:
769+ /// Converts an L-value to a value.
770+ operator Value() const;
771+
772+ /// Assigns a value to the property. The type of value can be
773+ /// anything supported by `Object::Set`.
774+ template <typename ValueType>
775+ PropertyLValue& operator=(ValueType value);
776+
777+ private:
778+ PropertyLValue() = delete;
779+ PropertyLValue(Object object, Key key);
780+ napi_env _env;
781+ napi_value _object;
782+ Key _key;
783+
784+ friend class Napi::Object;
785+ };
786+
787+ /// Creates a new Object value.
788+ static Object New(napi_env env ///< Node-API environment
789+ );
790+
791+ static void CheckCast(napi_env env, napi_value value);
792+
793+ Object(); ///< Creates a new _empty_ Object instance.
794+ Object(napi_env env,
795+ napi_value value); ///< Wraps a Node-API value primitive.
796+
797+ /// Gets or sets a named property.
798+ PropertyLValue<std::string> operator[](
799+ const char* utf8name ///< UTF-8 encoded null-terminated property name
800+ );
801+
802+ /// Gets or sets a named property.
803+ PropertyLValue<std::string> operator[](
804+ const std::string& utf8name ///< UTF-8 encoded property name
805+ );
806+
807+ /// Gets or sets an indexed property or array element.
808+ PropertyLValue<uint32_t> operator[](
809+ uint32_t index /// Property / element index
810+ );
811+
812+ /// Gets or sets an indexed property or array element.
813+ PropertyLValue<Value> operator[](Value index /// Property / element index
814+ ) const;
815+
816+ /// Gets a named property.
817+ MaybeOrValue<Value> operator[](
818+ const char* utf8name ///< UTF-8 encoded null-terminated property name
819+ ) const;
820+
821+ /// Gets a named property.
822+ MaybeOrValue<Value> operator[](
823+ const std::string& utf8name ///< UTF-8 encoded property name
824+ ) const;
825+
826+ /// Gets an indexed property or array element.
827+ MaybeOrValue<Value> operator[](uint32_t index ///< Property / element index
828+ ) const;
829+
830+ /// Checks whether a property is present.
831+ MaybeOrValue<bool> Has(napi_value key ///< Property key primitive
832+ ) const;
833+
834+ /// Checks whether a property is present.
835+ MaybeOrValue<bool> Has(Value key ///< Property key
836+ ) const;
837+
838+ /// Checks whether a named property is present.
839+ MaybeOrValue<bool> Has(
840+ const char* utf8name ///< UTF-8 encoded null-terminated property name
841+ ) const;
842+
843+ /// Checks whether a named property is present.
844+ MaybeOrValue<bool> Has(
845+ const std::string& utf8name ///< UTF-8 encoded property name
846+ ) const;
847+
848+ /// Checks whether a own property is present.
849+ MaybeOrValue<bool> HasOwnProperty(napi_value key ///< Property key primitive
850+ ) const;
851+
852+ /// Checks whether a own property is present.
853+ MaybeOrValue<bool> HasOwnProperty(Value key ///< Property key
854+ ) const;
855+
856+ /// Checks whether a own property is present.
857+ MaybeOrValue<bool> HasOwnProperty(
858+ const char* utf8name ///< UTF-8 encoded null-terminated property name
859+ ) const;
860+
861+ /// Checks whether a own property is present.
862+ MaybeOrValue<bool> HasOwnProperty(
863+ const std::string& utf8name ///< UTF-8 encoded property name
864+ ) const;
865+
866+ /// Gets a property.
867+ MaybeOrValue<Value> Get(napi_value key ///< Property key primitive
868+ ) const;
869+
870+ /// Gets a property.
871+ MaybeOrValue<Value> Get(Value key ///< Property key
872+ ) const;
873+
874+ /// Gets a named property.
875+ MaybeOrValue<Value> Get(
876+ const char* utf8name ///< UTF-8 encoded null-terminated property name
877+ ) const;
878+
879+ /// Gets a named property.
880+ MaybeOrValue<Value> Get(
881+ const std::string& utf8name ///< UTF-8 encoded property name
882+ ) const;
883+
884+ /// Sets a property.
885+ template <typename ValueType>
886+ MaybeOrValue<bool> Set(napi_value key, ///< Property key primitive
887+ const ValueType& value ///< Property value primitive
888+ ) const;
889+
890+ /// Sets a property.
891+ template <typename ValueType>
892+ MaybeOrValue<bool> Set(Value key, ///< Property key
893+ const ValueType& value ///< Property value
894+ ) const;
895+
896+ /// Sets a named property.
897+ template <typename ValueType>
898+ MaybeOrValue<bool> Set(
899+ const char* utf8name, ///< UTF-8 encoded null-terminated property name
900+ const ValueType& value) const;
901+
902+ /// Sets a named property.
903+ template <typename ValueType>
904+ MaybeOrValue<bool> Set(
905+ const std::string& utf8name, ///< UTF-8 encoded property name
906+ const ValueType& value ///< Property value primitive
907+ ) const;
908+
909+ /// Delete property.
910+ MaybeOrValue<bool> Delete(napi_value key ///< Property key primitive
911+ ) const;
912+
913+ /// Delete property.
914+ MaybeOrValue<bool> Delete(Value key ///< Property key
915+ ) const;
916+
917+ /// Delete property.
918+ MaybeOrValue<bool> Delete(
919+ const char* utf8name ///< UTF-8 encoded null-terminated property name
920+ ) const;
921+
922+ /// Delete property.
923+ MaybeOrValue<bool> Delete(
924+ const std::string& utf8name ///< UTF-8 encoded property name
925+ ) const;
926+
927+ /// Checks whether an indexed property is present.
928+ MaybeOrValue<bool> Has(uint32_t index ///< Property / element index
929+ ) const;
930+
931+ /// Gets an indexed property or array element.
932+ MaybeOrValue<Value> Get(uint32_t index ///< Property / element index
933+ ) const;
934+
935+ /// Sets an indexed property or array element.
936+ template <typename ValueType>
937+ MaybeOrValue<bool> Set(uint32_t index, ///< Property / element index
938+ const ValueType& value ///< Property value primitive
939+ ) const;
940+
941+ /// Deletes an indexed property or array element.
942+ MaybeOrValue<bool> Delete(uint32_t index ///< Property / element index
943+ ) const;
944+
945+ /// This operation can fail in case of Proxy.[[OwnPropertyKeys]] and
946+ /// Proxy.[[GetOwnProperty]] calling into JavaScript. See:
947+ /// -
948+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys
949+ /// -
950+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
951+ MaybeOrValue<Array> GetPropertyNames() const; ///< Get all property names
952+
953+ /// Defines a property on the object.
954+ ///
955+ /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
956+ /// into JavaScript. See
957+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
958+ MaybeOrValue<bool> DefineProperty(
959+ const PropertyDescriptor&
960+ property ///< Descriptor for the property to be defined
961+ ) const;
962+
963+ /// Defines properties on the object.
964+ ///
965+ /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
966+ /// into JavaScript. See
967+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
968+ MaybeOrValue<bool> DefineProperties(
969+ const std::initializer_list<PropertyDescriptor>& properties
970+ ///< List of descriptors for the properties to be defined
971+ ) const;
972+
973+ /// Defines properties on the object.
974+ ///
975+ /// This operation can fail in case of Proxy.[[DefineOwnProperty]] calling
976+ /// into JavaScript. See
977+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc
978+ MaybeOrValue<bool> DefineProperties(
979+ const std::vector<PropertyDescriptor>& properties
980+ ///< Vector of descriptors for the properties to be defined
981+ ) const;
982+
983+ /// Checks if an object is an instance created by a constructor function.
984+ ///
985+ /// This is equivalent to the JavaScript `instanceof` operator.
986+ ///
987+ /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
988+ /// JavaScript.
989+ /// See
990+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
991+ MaybeOrValue<bool> InstanceOf(
992+ const Function& constructor ///< Constructor function
993+ ) const;
994+
995+ template <typename Finalizer, typename T>
996+ inline void AddFinalizer(Finalizer finalizeCallback, T* data) const;
997+
998+ template <typename Finalizer, typename T, typename Hint>
999+ inline void AddFinalizer(Finalizer finalizeCallback,
1000+ T* data,
1001+ Hint* finalizeHint) const;
1002+
1003+#ifdef NAPI_CPP_EXCEPTIONS
1004+ class const_iterator;
1005+
1006+ inline const_iterator begin() const;
1007+
1008+ inline const_iterator end() const;
1009+
1010+ class iterator;
1011+
1012+ inline iterator begin();
1013+
1014+ inline iterator end();
1015+#endif // NAPI_CPP_EXCEPTIONS
1016+
1017+#if NAPI_VERSION >= 8
1018+ /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
1019+ /// JavaScript.
1020+ /// See
1021+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1022+ MaybeOrValue<bool> Freeze() const;
1023+ /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
1024+ /// JavaScript.
1025+ /// See
1026+ /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1027+ MaybeOrValue<bool> Seal() const;
1028+#endif // NAPI_VERSION >= 8
1029+};
1030+
1031+template <typename T>
1032+class External : public TypeTaggable {
1033+ public:
1034+ static External New(napi_env env, T* data);
1035+
1036+ // Finalizer must implement `void operator()(Env env, T* data)`.
1037+ template <typename Finalizer>
1038+ static External New(napi_env env, T* data, Finalizer finalizeCallback);
1039+ // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1040+ template <typename Finalizer, typename Hint>
1041+ static External New(napi_env env,
1042+ T* data,
1043+ Finalizer finalizeCallback,
1044+ Hint* finalizeHint);
1045+
1046+ static void CheckCast(napi_env env, napi_value value);
1047+
1048+ External();
1049+ External(napi_env env, napi_value value);
1050+
1051+ T* Data() const;
1052+};
1053+
1054+class Array : public Object {
1055+ public:
1056+ static Array New(napi_env env);
1057+ static Array New(napi_env env, size_t length);
1058+
1059+ static void CheckCast(napi_env env, napi_value value);
1060+
1061+ Array();
1062+ Array(napi_env env, napi_value value);
1063+
1064+ uint32_t Length() const;
1065+};
1066+
1067+#ifdef NAPI_CPP_EXCEPTIONS
1068+class Object::const_iterator {
1069+ private:
1070+ enum class Type { BEGIN, END };
1071+
1072+ inline const_iterator(const Object* object, const Type type);
1073+
1074+ public:
1075+ inline const_iterator& operator++();
1076+
1077+ inline bool operator==(const const_iterator& other) const;
1078+
1079+ inline bool operator!=(const const_iterator& other) const;
1080+
1081+ inline const std::pair<Value, Object::PropertyLValue<Value>> operator*()
1082+ const;
1083+
1084+ private:
1085+ const Napi::Object* _object;
1086+ Array _keys;
1087+ uint32_t _index;
1088+
1089+ friend class Object;
1090+};
1091+
1092+class Object::iterator {
1093+ private:
1094+ enum class Type { BEGIN, END };
1095+
1096+ inline iterator(Object* object, const Type type);
1097+
1098+ public:
1099+ inline iterator& operator++();
1100+
1101+ inline bool operator==(const iterator& other) const;
1102+
1103+ inline bool operator!=(const iterator& other) const;
1104+
1105+ inline std::pair<Value, Object::PropertyLValue<Value>> operator*();
1106+
1107+ private:
1108+ Napi::Object* _object;
1109+ Array _keys;
1110+ uint32_t _index;
1111+
1112+ friend class Object;
1113+};
1114+#endif // NAPI_CPP_EXCEPTIONS
1115+
1116+/// A JavaScript array buffer value.
1117+class ArrayBuffer : public Object {
1118+ public:
1119+ /// Creates a new ArrayBuffer instance over a new automatically-allocated
1120+ /// buffer.
1121+ static ArrayBuffer New(
1122+ napi_env env, ///< Node-API environment
1123+ size_t byteLength ///< Length of the buffer to be allocated, in bytes
1124+ );
1125+
1126+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1127+ /// Creates a new ArrayBuffer instance, using an external buffer with
1128+ /// specified byte length.
1129+ static ArrayBuffer New(
1130+ napi_env env, ///< Node-API environment
1131+ void* externalData, ///< Pointer to the external buffer to be used by
1132+ ///< the array
1133+ size_t byteLength ///< Length of the external buffer to be used by the
1134+ ///< array, in bytes
1135+ );
1136+
1137+ /// Creates a new ArrayBuffer instance, using an external buffer with
1138+ /// specified byte length.
1139+ template <typename Finalizer>
1140+ static ArrayBuffer New(
1141+ napi_env env, ///< Node-API environment
1142+ void* externalData, ///< Pointer to the external buffer to be used by
1143+ ///< the array
1144+ size_t byteLength, ///< Length of the external buffer to be used by the
1145+ ///< array,
1146+ /// in bytes
1147+ Finalizer finalizeCallback ///< Function to be called when the array
1148+ ///< buffer is destroyed;
1149+ /// must implement `void operator()(Env env,
1150+ /// void* externalData)`
1151+ );
1152+
1153+ /// Creates a new ArrayBuffer instance, using an external buffer with
1154+ /// specified byte length.
1155+ template <typename Finalizer, typename Hint>
1156+ static ArrayBuffer New(
1157+ napi_env env, ///< Node-API environment
1158+ void* externalData, ///< Pointer to the external buffer to be used by
1159+ ///< the array
1160+ size_t byteLength, ///< Length of the external buffer to be used by the
1161+ ///< array,
1162+ /// in bytes
1163+ Finalizer finalizeCallback, ///< Function to be called when the array
1164+ ///< buffer is destroyed;
1165+ /// must implement `void operator()(Env
1166+ /// env, void* externalData, Hint* hint)`
1167+ Hint* finalizeHint ///< Hint (second parameter) to be passed to the
1168+ ///< finalize callback
1169+ );
1170+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1171+
1172+ static void CheckCast(napi_env env, napi_value value);
1173+
1174+ ArrayBuffer(); ///< Creates a new _empty_ ArrayBuffer instance.
1175+ ArrayBuffer(napi_env env,
1176+ napi_value value); ///< Wraps a Node-API value primitive.
1177+
1178+ void* Data(); ///< Gets a pointer to the data buffer.
1179+ size_t ByteLength(); ///< Gets the length of the array buffer in bytes.
1180+
1181+#if NAPI_VERSION >= 7
1182+ bool IsDetached() const;
1183+ void Detach();
1184+#endif // NAPI_VERSION >= 7
1185+};
1186+
1187+/// A JavaScript typed-array value with unknown array type.
1188+///
1189+/// For type-specific operations, cast to a `TypedArrayOf<T>` instance using the
1190+/// `As()` method:
1191+///
1192+/// Napi::TypedArray array = ...
1193+/// if (t.TypedArrayType() == napi_int32_array) {
1194+/// Napi::Int32Array int32Array = t.As<Napi::Int32Array>();
1195+/// }
1196+class TypedArray : public Object {
1197+ public:
1198+ static void CheckCast(napi_env env, napi_value value);
1199+
1200+ TypedArray(); ///< Creates a new _empty_ TypedArray instance.
1201+ TypedArray(napi_env env,
1202+ napi_value value); ///< Wraps a Node-API value primitive.
1203+
1204+ napi_typedarray_type TypedArrayType()
1205+ const; ///< Gets the type of this typed-array.
1206+ Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1207+
1208+ uint8_t ElementSize()
1209+ const; ///< Gets the size in bytes of one element in the array.
1210+ size_t ElementLength() const; ///< Gets the number of elements in the array.
1211+ size_t ByteOffset()
1212+ const; ///< Gets the offset into the buffer where the array starts.
1213+ size_t ByteLength() const; ///< Gets the length of the array in bytes.
1214+
1215+ protected:
1216+ /// !cond INTERNAL
1217+ napi_typedarray_type _type;
1218+ size_t _length;
1219+
1220+ TypedArray(napi_env env,
1221+ napi_value value,
1222+ napi_typedarray_type type,
1223+ size_t length);
1224+
1225+ template <typename T>
1226+ static
1227+#if defined(NAPI_HAS_CONSTEXPR)
1228+ constexpr
1229+#endif
1230+ napi_typedarray_type
1231+ TypedArrayTypeForPrimitiveType() {
1232+ return std::is_same<T, int8_t>::value ? napi_int8_array
1233+ : std::is_same<T, uint8_t>::value ? napi_uint8_array
1234+ : std::is_same<T, int16_t>::value ? napi_int16_array
1235+ : std::is_same<T, uint16_t>::value ? napi_uint16_array
1236+ : std::is_same<T, int32_t>::value ? napi_int32_array
1237+ : std::is_same<T, uint32_t>::value ? napi_uint32_array
1238+ : std::is_same<T, float>::value ? napi_float32_array
1239+ : std::is_same<T, double>::value ? napi_float64_array
1240+#if NAPI_VERSION > 5
1241+ : std::is_same<T, int64_t>::value ? napi_bigint64_array
1242+ : std::is_same<T, uint64_t>::value ? napi_biguint64_array
1243+#endif // NAPI_VERSION > 5
1244+ : napi_int8_array;
1245+ }
1246+ /// !endcond
1247+};
1248+
1249+/// A JavaScript typed-array value with known array type.
1250+///
1251+/// Note while it is possible to create and access Uint8 "clamped" arrays using
1252+/// this class, the _clamping_ behavior is only applied in JavaScript.
1253+template <typename T>
1254+class TypedArrayOf : public TypedArray {
1255+ public:
1256+ /// Creates a new TypedArray instance over a new automatically-allocated array
1257+ /// buffer.
1258+ ///
1259+ /// The array type parameter can normally be omitted (because it is inferred
1260+ /// from the template parameter T), except when creating a "clamped" array:
1261+ ///
1262+ /// Uint8Array::New(env, length, napi_uint8_clamped_array)
1263+ static TypedArrayOf New(
1264+ napi_env env, ///< Node-API environment
1265+ size_t elementLength, ///< Length of the created array, as a number of
1266+ ///< elements
1267+#if defined(NAPI_HAS_CONSTEXPR)
1268+ napi_typedarray_type type =
1269+ TypedArray::TypedArrayTypeForPrimitiveType<T>()
1270+#else
1271+ napi_typedarray_type type
1272+#endif
1273+ ///< Type of array, if different from the default array type for the
1274+ ///< template parameter T.
1275+ );
1276+
1277+ /// Creates a new TypedArray instance over a provided array buffer.
1278+ ///
1279+ /// The array type parameter can normally be omitted (because it is inferred
1280+ /// from the template parameter T), except when creating a "clamped" array:
1281+ ///
1282+ /// Uint8Array::New(env, length, buffer, 0, napi_uint8_clamped_array)
1283+ static TypedArrayOf New(
1284+ napi_env env, ///< Node-API environment
1285+ size_t elementLength, ///< Length of the created array, as a number of
1286+ ///< elements
1287+ Napi::ArrayBuffer arrayBuffer, ///< Backing array buffer instance to use
1288+ size_t bufferOffset, ///< Offset into the array buffer where the
1289+ ///< typed-array starts
1290+#if defined(NAPI_HAS_CONSTEXPR)
1291+ napi_typedarray_type type =
1292+ TypedArray::TypedArrayTypeForPrimitiveType<T>()
1293+#else
1294+ napi_typedarray_type type
1295+#endif
1296+ ///< Type of array, if different from the default array type for the
1297+ ///< template parameter T.
1298+ );
1299+
1300+ static void CheckCast(napi_env env, napi_value value);
1301+
1302+ TypedArrayOf(); ///< Creates a new _empty_ TypedArrayOf instance.
1303+ TypedArrayOf(napi_env env,
1304+ napi_value value); ///< Wraps a Node-API value primitive.
1305+
1306+ T& operator[](size_t index); ///< Gets or sets an element in the array.
1307+ const T& operator[](size_t index) const; ///< Gets an element in the array.
1308+
1309+ /// Gets a pointer to the array's backing buffer.
1310+ ///
1311+ /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer,
1312+ /// because the typed-array may have a non-zero `ByteOffset()` into the
1313+ /// `ArrayBuffer`.
1314+ T* Data();
1315+
1316+ /// Gets a pointer to the array's backing buffer.
1317+ ///
1318+ /// This is not necessarily the same as the `ArrayBuffer::Data()` pointer,
1319+ /// because the typed-array may have a non-zero `ByteOffset()` into the
1320+ /// `ArrayBuffer`.
1321+ const T* Data() const;
1322+
1323+ private:
1324+ T* _data;
1325+
1326+ TypedArrayOf(napi_env env,
1327+ napi_value value,
1328+ napi_typedarray_type type,
1329+ size_t length,
1330+ T* data);
1331+};
1332+
1333+/// The DataView provides a low-level interface for reading/writing multiple
1334+/// number types in an ArrayBuffer irrespective of the platform's endianness.
1335+class DataView : public Object {
1336+ public:
1337+ static DataView New(napi_env env, Napi::ArrayBuffer arrayBuffer);
1338+ static DataView New(napi_env env,
1339+ Napi::ArrayBuffer arrayBuffer,
1340+ size_t byteOffset);
1341+ static DataView New(napi_env env,
1342+ Napi::ArrayBuffer arrayBuffer,
1343+ size_t byteOffset,
1344+ size_t byteLength);
1345+
1346+ static void CheckCast(napi_env env, napi_value value);
1347+
1348+ DataView(); ///< Creates a new _empty_ DataView instance.
1349+ DataView(napi_env env,
1350+ napi_value value); ///< Wraps a Node-API value primitive.
1351+
1352+ Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1353+ size_t ByteOffset()
1354+ const; ///< Gets the offset into the buffer where the array starts.
1355+ size_t ByteLength() const; ///< Gets the length of the array in bytes.
1356+
1357+ void* Data() const;
1358+
1359+ float GetFloat32(size_t byteOffset) const;
1360+ double GetFloat64(size_t byteOffset) const;
1361+ int8_t GetInt8(size_t byteOffset) const;
1362+ int16_t GetInt16(size_t byteOffset) const;
1363+ int32_t GetInt32(size_t byteOffset) const;
1364+ uint8_t GetUint8(size_t byteOffset) const;
1365+ uint16_t GetUint16(size_t byteOffset) const;
1366+ uint32_t GetUint32(size_t byteOffset) const;
1367+
1368+ void SetFloat32(size_t byteOffset, float value) const;
1369+ void SetFloat64(size_t byteOffset, double value) const;
1370+ void SetInt8(size_t byteOffset, int8_t value) const;
1371+ void SetInt16(size_t byteOffset, int16_t value) const;
1372+ void SetInt32(size_t byteOffset, int32_t value) const;
1373+ void SetUint8(size_t byteOffset, uint8_t value) const;
1374+ void SetUint16(size_t byteOffset, uint16_t value) const;
1375+ void SetUint32(size_t byteOffset, uint32_t value) const;
1376+
1377+ private:
1378+ template <typename T>
1379+ T ReadData(size_t byteOffset) const;
1380+
1381+ template <typename T>
1382+ void WriteData(size_t byteOffset, T value) const;
1383+
1384+ void* _data;
1385+ size_t _length;
1386+};
1387+
1388+class Function : public Object {
1389+ public:
1390+ using VoidCallback = void (*)(const CallbackInfo& info);
1391+ using Callback = Value (*)(const CallbackInfo& info);
1392+
1393+ template <VoidCallback cb>
1394+ static Function New(napi_env env,
1395+ const char* utf8name = nullptr,
1396+ void* data = nullptr);
1397+
1398+ template <Callback cb>
1399+ static Function New(napi_env env,
1400+ const char* utf8name = nullptr,
1401+ void* data = nullptr);
1402+
1403+ template <VoidCallback cb>
1404+ static Function New(napi_env env,
1405+ const std::string& utf8name,
1406+ void* data = nullptr);
1407+
1408+ template <Callback cb>
1409+ static Function New(napi_env env,
1410+ const std::string& utf8name,
1411+ void* data = nullptr);
1412+
1413+ /// Callable must implement operator() accepting a const CallbackInfo&
1414+ /// and return either void or Value.
1415+ template <typename Callable>
1416+ static Function New(napi_env env,
1417+ Callable cb,
1418+ const char* utf8name = nullptr,
1419+ void* data = nullptr);
1420+ /// Callable must implement operator() accepting a const CallbackInfo&
1421+ /// and return either void or Value.
1422+ template <typename Callable>
1423+ static Function New(napi_env env,
1424+ Callable cb,
1425+ const std::string& utf8name,
1426+ void* data = nullptr);
1427+
1428+ static void CheckCast(napi_env env, napi_value value);
1429+
1430+ Function();
1431+ Function(napi_env env, napi_value value);
1432+
1433+ MaybeOrValue<Value> operator()(
1434+ const std::initializer_list<napi_value>& args) const;
1435+
1436+ MaybeOrValue<Value> Call(const std::initializer_list<napi_value>& args) const;
1437+ MaybeOrValue<Value> Call(const std::vector<napi_value>& args) const;
1438+ MaybeOrValue<Value> Call(const std::vector<Value>& args) const;
1439+ MaybeOrValue<Value> Call(size_t argc, const napi_value* args) const;
1440+ MaybeOrValue<Value> Call(napi_value recv,
1441+ const std::initializer_list<napi_value>& args) const;
1442+ MaybeOrValue<Value> Call(napi_value recv,
1443+ const std::vector<napi_value>& args) const;
1444+ MaybeOrValue<Value> Call(napi_value recv,
1445+ const std::vector<Value>& args) const;
1446+ MaybeOrValue<Value> Call(napi_value recv,
1447+ size_t argc,
1448+ const napi_value* args) const;
1449+
1450+ MaybeOrValue<Value> MakeCallback(
1451+ napi_value recv,
1452+ const std::initializer_list<napi_value>& args,
1453+ napi_async_context context = nullptr) const;
1454+ MaybeOrValue<Value> MakeCallback(napi_value recv,
1455+ const std::vector<napi_value>& args,
1456+ napi_async_context context = nullptr) const;
1457+ MaybeOrValue<Value> MakeCallback(napi_value recv,
1458+ size_t argc,
1459+ const napi_value* args,
1460+ napi_async_context context = nullptr) const;
1461+
1462+ MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const;
1463+ MaybeOrValue<Object> New(const std::vector<napi_value>& args) const;
1464+ MaybeOrValue<Object> New(size_t argc, const napi_value* args) const;
1465+};
1466+
1467+class Promise : public Object {
1468+ public:
1469+ class Deferred {
1470+ public:
1471+ static Deferred New(napi_env env);
1472+ Deferred(napi_env env);
1473+
1474+ Napi::Promise Promise() const;
1475+ Napi::Env Env() const;
1476+
1477+ void Resolve(napi_value value) const;
1478+ void Reject(napi_value value) const;
1479+
1480+ private:
1481+ napi_env _env;
1482+ napi_deferred _deferred;
1483+ napi_value _promise;
1484+ };
1485+
1486+ static void CheckCast(napi_env env, napi_value value);
1487+
1488+ Promise(napi_env env, napi_value value);
1489+};
1490+
1491+template <typename T>
1492+class Buffer : public Uint8Array {
1493+ public:
1494+ static Buffer<T> New(napi_env env, size_t length);
1495+#ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1496+ static Buffer<T> New(napi_env env, T* data, size_t length);
1497+
1498+ // Finalizer must implement `void operator()(Env env, T* data)`.
1499+ template <typename Finalizer>
1500+ static Buffer<T> New(napi_env env,
1501+ T* data,
1502+ size_t length,
1503+ Finalizer finalizeCallback);
1504+ // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1505+ template <typename Finalizer, typename Hint>
1506+ static Buffer<T> New(napi_env env,
1507+ T* data,
1508+ size_t length,
1509+ Finalizer finalizeCallback,
1510+ Hint* finalizeHint);
1511+#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
1512+
1513+ static Buffer<T> NewOrCopy(napi_env env, T* data, size_t length);
1514+ // Finalizer must implement `void operator()(Env env, T* data)`.
1515+ template <typename Finalizer>
1516+ static Buffer<T> NewOrCopy(napi_env env,
1517+ T* data,
1518+ size_t length,
1519+ Finalizer finalizeCallback);
1520+ // Finalizer must implement `void operator()(Env env, T* data, Hint* hint)`.
1521+ template <typename Finalizer, typename Hint>
1522+ static Buffer<T> NewOrCopy(napi_env env,
1523+ T* data,
1524+ size_t length,
1525+ Finalizer finalizeCallback,
1526+ Hint* finalizeHint);
1527+
1528+ static Buffer<T> Copy(napi_env env, const T* data, size_t length);
1529+
1530+ static void CheckCast(napi_env env, napi_value value);
1531+
1532+ Buffer();
1533+ Buffer(napi_env env, napi_value value);
1534+ size_t Length() const;
1535+ T* Data() const;
1536+
1537+ private:
1538+};
1539+
1540+/// Holds a counted reference to a value; initially a weak reference unless
1541+/// otherwise specified, may be changed to/from a strong reference by adjusting
1542+/// the refcount.
1543+///
1544+/// The referenced value is not immediately destroyed when the reference count
1545+/// is zero; it is merely then eligible for garbage-collection if there are no
1546+/// other references to the value.
1547+template <typename T>
1548+class Reference {
1549+ public:
1550+ static Reference<T> New(const T& value, uint32_t initialRefcount = 0);
1551+
1552+ Reference();
1553+ Reference(napi_env env, napi_ref ref);
1554+ ~Reference();
1555+
1556+ // A reference can be moved but cannot be copied.
1557+ Reference(Reference<T>&& other);
1558+ Reference<T>& operator=(Reference<T>&& other);
1559+ NAPI_DISALLOW_ASSIGN(Reference<T>)
1560+
1561+ operator napi_ref() const;
1562+ bool operator==(const Reference<T>& other) const;
1563+ bool operator!=(const Reference<T>& other) const;
1564+
1565+ Napi::Env Env() const;
1566+ bool IsEmpty() const;
1567+
1568+ // Note when getting the value of a Reference it is usually correct to do so
1569+ // within a HandleScope so that the value handle gets cleaned up efficiently.
1570+ T Value() const;
1571+
1572+ uint32_t Ref() const;
1573+ uint32_t Unref() const;
1574+ void Reset();
1575+ void Reset(const T& value, uint32_t refcount = 0);
1576+
1577+ // Call this on a reference that is declared as static data, to prevent its
1578+ // destructor from running at program shutdown time, which would attempt to
1579+ // reset the reference when the environment is no longer valid. Avoid using
1580+ // this if at all possible. If you do need to use static data, MAKE SURE to
1581+ // warn your users that your addon is NOT threadsafe.
1582+ void SuppressDestruct();
1583+
1584+ protected:
1585+ Reference(const Reference<T>&);
1586+
1587+ /// !cond INTERNAL
1588+ napi_env _env;
1589+ napi_ref _ref;
1590+ /// !endcond
1591+
1592+ private:
1593+ bool _suppressDestruct;
1594+};
1595+
1596+class ObjectReference : public Reference<Object> {
1597+ public:
1598+ ObjectReference();
1599+ ObjectReference(napi_env env, napi_ref ref);
1600+
1601+ // A reference can be moved but cannot be copied.
1602+ ObjectReference(Reference<Object>&& other);
1603+ ObjectReference& operator=(Reference<Object>&& other);
1604+ ObjectReference(ObjectReference&& other);
1605+ ObjectReference& operator=(ObjectReference&& other);
1606+ NAPI_DISALLOW_ASSIGN(ObjectReference)
1607+
1608+ MaybeOrValue<Napi::Value> Get(const char* utf8name) const;
1609+ MaybeOrValue<Napi::Value> Get(const std::string& utf8name) const;
1610+ MaybeOrValue<bool> Set(const char* utf8name, napi_value value) const;
1611+ MaybeOrValue<bool> Set(const char* utf8name, Napi::Value value) const;
1612+ MaybeOrValue<bool> Set(const char* utf8name, const char* utf8value) const;
1613+ MaybeOrValue<bool> Set(const char* utf8name, bool boolValue) const;
1614+ MaybeOrValue<bool> Set(const char* utf8name, double numberValue) const;
1615+ MaybeOrValue<bool> Set(const std::string& utf8name, napi_value value) const;
1616+ MaybeOrValue<bool> Set(const std::string& utf8name, Napi::Value value) const;
1617+ MaybeOrValue<bool> Set(const std::string& utf8name,
1618+ std::string& utf8value) const;
1619+ MaybeOrValue<bool> Set(const std::string& utf8name, bool boolValue) const;
1620+ MaybeOrValue<bool> Set(const std::string& utf8name, double numberValue) const;
1621+
1622+ MaybeOrValue<Napi::Value> Get(uint32_t index) const;
1623+ MaybeOrValue<bool> Set(uint32_t index, const napi_value value) const;
1624+ MaybeOrValue<bool> Set(uint32_t index, const Napi::Value value) const;
1625+ MaybeOrValue<bool> Set(uint32_t index, const char* utf8value) const;
1626+ MaybeOrValue<bool> Set(uint32_t index, const std::string& utf8value) const;
1627+ MaybeOrValue<bool> Set(uint32_t index, bool boolValue) const;
1628+ MaybeOrValue<bool> Set(uint32_t index, double numberValue) const;
1629+
1630+ protected:
1631+ ObjectReference(const ObjectReference&);
1632+};
1633+
1634+class FunctionReference : public Reference<Function> {
1635+ public:
1636+ FunctionReference();
1637+ FunctionReference(napi_env env, napi_ref ref);
1638+
1639+ // A reference can be moved but cannot be copied.
1640+ FunctionReference(Reference<Function>&& other);
1641+ FunctionReference& operator=(Reference<Function>&& other);
1642+ FunctionReference(FunctionReference&& other);
1643+ FunctionReference& operator=(FunctionReference&& other);
1644+ NAPI_DISALLOW_ASSIGN_COPY(FunctionReference)
1645+
1646+ MaybeOrValue<Napi::Value> operator()(
1647+ const std::initializer_list<napi_value>& args) const;
1648+
1649+ MaybeOrValue<Napi::Value> Call(
1650+ const std::initializer_list<napi_value>& args) const;
1651+ MaybeOrValue<Napi::Value> Call(const std::vector<napi_value>& args) const;
1652+ MaybeOrValue<Napi::Value> Call(
1653+ napi_value recv, const std::initializer_list<napi_value>& args) const;
1654+ MaybeOrValue<Napi::Value> Call(napi_value recv,
1655+ const std::vector<napi_value>& args) const;
1656+ MaybeOrValue<Napi::Value> Call(napi_value recv,
1657+ size_t argc,
1658+ const napi_value* args) const;
1659+
1660+ MaybeOrValue<Napi::Value> MakeCallback(
1661+ napi_value recv,
1662+ const std::initializer_list<napi_value>& args,
1663+ napi_async_context context = nullptr) const;
1664+ MaybeOrValue<Napi::Value> MakeCallback(
1665+ napi_value recv,
1666+ const std::vector<napi_value>& args,
1667+ napi_async_context context = nullptr) const;
1668+ MaybeOrValue<Napi::Value> MakeCallback(
1669+ napi_value recv,
1670+ size_t argc,
1671+ const napi_value* args,
1672+ napi_async_context context = nullptr) const;
1673+
1674+ MaybeOrValue<Object> New(const std::initializer_list<napi_value>& args) const;
1675+ MaybeOrValue<Object> New(const std::vector<napi_value>& args) const;
1676+};
1677+
1678+// Shortcuts to creating a new reference with inferred type and refcount = 0.
1679+template <typename T>
1680+Reference<T> Weak(T value);
1681+ObjectReference Weak(Object value);
1682+FunctionReference Weak(Function value);
1683+
1684+// Shortcuts to creating a new reference with inferred type and refcount = 1.
1685+template <typename T>
1686+Reference<T> Persistent(T value);
1687+ObjectReference Persistent(Object value);
1688+FunctionReference Persistent(Function value);
1689+
1690+/// A persistent reference to a JavaScript error object. Use of this class
1691+/// depends somewhat on whether C++ exceptions are enabled at compile time.
1692+///
1693+/// ### Handling Errors With C++ Exceptions
1694+///
1695+/// If C++ exceptions are enabled, then the `Error` class extends
1696+/// `std::exception` and enables integrated error-handling for C++ exceptions
1697+/// and JavaScript exceptions.
1698+///
1699+/// If a Node-API call fails without executing any JavaScript code (for
1700+/// example due to an invalid argument), then the Node-API wrapper
1701+/// automatically converts and throws the error as a C++ exception of type
1702+/// `Napi::Error`. Or if a JavaScript function called by C++ code via Node-API
1703+/// throws a JavaScript exception, then the Node-API wrapper automatically
1704+/// converts and throws it as a C++ exception of type `Napi::Error`.
1705+///
1706+/// If a C++ exception of type `Napi::Error` escapes from a Node-API C++
1707+/// callback, then the Node-API wrapper automatically converts and throws it
1708+/// as a JavaScript exception. Therefore, catching a C++ exception of type
1709+/// `Napi::Error` prevents a JavaScript exception from being thrown.
1710+///
1711+/// #### Example 1A - Throwing a C++ exception:
1712+///
1713+/// Napi::Env env = ...
1714+/// throw Napi::Error::New(env, "Example exception");
1715+///
1716+/// Following C++ statements will not be executed. The exception will bubble
1717+/// up as a C++ exception of type `Napi::Error`, until it is either caught
1718+/// while still in C++, or else automatically propataged as a JavaScript
1719+/// exception when the callback returns to JavaScript.
1720+///
1721+/// #### Example 2A - Propagating a Node-API C++ exception:
1722+///
1723+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1724+/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1725+///
1726+/// Following C++ statements will not be executed. The exception will bubble
1727+/// up as a C++ exception of type `Napi::Error`, until it is either caught
1728+/// while still in C++, or else automatically propagated as a JavaScript
1729+/// exception when the callback returns to JavaScript.
1730+///
1731+/// #### Example 3A - Handling a Node-API C++ exception:
1732+///
1733+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1734+/// Napi::Value result;
1735+/// try {
1736+/// result = jsFunctionThatThrows({ arg1, arg2 });
1737+/// } catch (const Napi::Error& e) {
1738+/// cerr << "Caught JavaScript exception: " + e.what();
1739+/// }
1740+///
1741+/// Since the exception was caught here, it will not be propagated as a
1742+/// JavaScript exception.
1743+///
1744+/// ### Handling Errors Without C++ Exceptions
1745+///
1746+/// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`)
1747+/// then this class does not extend `std::exception`, and APIs in the `Napi`
1748+/// namespace do not throw C++ exceptions when they fail. Instead, they raise
1749+/// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code
1750+/// should check `Value::IsEmpty()` before attempting to use a returned value,
1751+/// and may use methods on the `Env` class to check for, get, and clear a
1752+/// pending JavaScript exception. If the pending exception is not cleared, it
1753+/// will be thrown when the native callback returns to JavaScript.
1754+///
1755+/// #### Example 1B - Throwing a JS exception
1756+///
1757+/// Napi::Env env = ...
1758+/// Napi::Error::New(env, "Example
1759+/// exception").ThrowAsJavaScriptException(); return;
1760+///
1761+/// After throwing a JS exception, the code should generally return
1762+/// immediately from the native callback, after performing any necessary
1763+/// cleanup.
1764+///
1765+/// #### Example 2B - Propagating a Node-API JS exception:
1766+///
1767+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1768+/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1769+/// if (result.IsEmpty()) return;
1770+///
1771+/// An empty value result from a Node-API call indicates an error occurred,
1772+/// and a JavaScript exception is pending. To let the exception propagate, the
1773+/// code should generally return immediately from the native callback, after
1774+/// performing any necessary cleanup.
1775+///
1776+/// #### Example 3B - Handling a Node-API JS exception:
1777+///
1778+/// Napi::Function jsFunctionThatThrows = someObj.As<Napi::Function>();
1779+/// Napi::Value result = jsFunctionThatThrows({ arg1, arg2 });
1780+/// if (result.IsEmpty()) {
1781+/// Napi::Error e = env.GetAndClearPendingException();
1782+/// cerr << "Caught JavaScript exception: " + e.Message();
1783+/// }
1784+///
1785+/// Since the exception was cleared here, it will not be propagated as a
1786+/// JavaScript exception after the native callback returns.
1787+class Error : public ObjectReference
1788+#ifdef NAPI_CPP_EXCEPTIONS
1789+ ,
1790+ public std::exception
1791+#endif // NAPI_CPP_EXCEPTIONS
1792+{
1793+ public:
1794+ static Error New(napi_env env);
1795+ static Error New(napi_env env, const char* message);
1796+ static Error New(napi_env env, const std::string& message);
1797+
1798+ static NAPI_NO_RETURN void Fatal(const char* location, const char* message);
1799+
1800+ Error();
1801+ Error(napi_env env, napi_value value);
1802+
1803+ // An error can be moved or copied.
1804+ Error(Error&& other);
1805+ Error& operator=(Error&& other);
1806+ Error(const Error&);
1807+ Error& operator=(const Error&);
1808+
1809+ const std::string& Message() const NAPI_NOEXCEPT;
1810+ void ThrowAsJavaScriptException() const;
1811+
1812+ Object Value() const;
1813+
1814+#ifdef NAPI_CPP_EXCEPTIONS
1815+ const char* what() const NAPI_NOEXCEPT override;
1816+#endif // NAPI_CPP_EXCEPTIONS
1817+
1818+ protected:
1819+ /// !cond INTERNAL
1820+ using create_error_fn = napi_status (*)(napi_env envb,
1821+ napi_value code,
1822+ napi_value msg,
1823+ napi_value* result);
1824+
1825+ template <typename TError>
1826+ static TError New(napi_env env,
1827+ const char* message,
1828+ size_t length,
1829+ create_error_fn create_error);
1830+ /// !endcond
1831+
1832+ private:
1833+ static inline const char* ERROR_WRAP_VALUE() NAPI_NOEXCEPT;
1834+ mutable std::string _message;
1835+};
1836+
1837+class TypeError : public Error {
1838+ public:
1839+ static TypeError New(napi_env env, const char* message);
1840+ static TypeError New(napi_env env, const std::string& message);
1841+
1842+ TypeError();
1843+ TypeError(napi_env env, napi_value value);
1844+};
1845+
1846+class RangeError : public Error {
1847+ public:
1848+ static RangeError New(napi_env env, const char* message);
1849+ static RangeError New(napi_env env, const std::string& message);
1850+
1851+ RangeError();
1852+ RangeError(napi_env env, napi_value value);
1853+};
1854+
1855+#if NAPI_VERSION > 8
1856+class SyntaxError : public Error {
1857+ public:
1858+ static SyntaxError New(napi_env env, const char* message);
1859+ static SyntaxError New(napi_env env, const std::string& message);
1860+
1861+ SyntaxError();
1862+ SyntaxError(napi_env env, napi_value value);
1863+};
1864+#endif // NAPI_VERSION > 8
1865+
1866+class CallbackInfo {
1867+ public:
1868+ CallbackInfo(napi_env env, napi_callback_info info);
1869+ ~CallbackInfo();
1870+
1871+ // Disallow copying to prevent multiple free of _dynamicArgs
1872+ NAPI_DISALLOW_ASSIGN_COPY(CallbackInfo)
1873+
1874+ Napi::Env Env() const;
1875+ Value NewTarget() const;
1876+ bool IsConstructCall() const;
1877+ size_t Length() const;
1878+ const Value operator[](size_t index) const;
1879+ Value This() const;
1880+ void* Data() const;
1881+ void SetData(void* data);
1882+ explicit operator napi_callback_info() const;
1883+
1884+ private:
1885+ const size_t _staticArgCount = 6;
1886+ napi_env _env;
1887+ napi_callback_info _info;
1888+ napi_value _this;
1889+ size_t _argc;
1890+ napi_value* _argv;
1891+ napi_value _staticArgs[6];
1892+ napi_value* _dynamicArgs;
1893+ void* _data;
1894+};
1895+
1896+class PropertyDescriptor {
1897+ public:
1898+ using GetterCallback = Napi::Value (*)(const Napi::CallbackInfo& info);
1899+ using SetterCallback = void (*)(const Napi::CallbackInfo& info);
1900+
1901+#ifndef NODE_ADDON_API_DISABLE_DEPRECATED
1902+ template <typename Getter>
1903+ static PropertyDescriptor Accessor(
1904+ const char* utf8name,
1905+ Getter getter,
1906+ napi_property_attributes attributes = napi_default,
1907+ void* data = nullptr);
1908+ template <typename Getter>
1909+ static PropertyDescriptor Accessor(
1910+ const std::string& utf8name,
1911+ Getter getter,
1912+ napi_property_attributes attributes = napi_default,
1913+ void* data = nullptr);
1914+ template <typename Getter>
1915+ static PropertyDescriptor Accessor(
1916+ napi_value name,
1917+ Getter getter,
1918+ napi_property_attributes attributes = napi_default,
1919+ void* data = nullptr);
1920+ template <typename Getter>
1921+ static PropertyDescriptor Accessor(
1922+ Name name,
1923+ Getter getter,
1924+ napi_property_attributes attributes = napi_default,
1925+ void* data = nullptr);
1926+ template <typename Getter, typename Setter>
1927+ static PropertyDescriptor Accessor(
1928+ const char* utf8name,
1929+ Getter getter,
1930+ Setter setter,
1931+ napi_property_attributes attributes = napi_default,
1932+ void* data = nullptr);
1933+ template <typename Getter, typename Setter>
1934+ static PropertyDescriptor Accessor(
1935+ const std::string& utf8name,
1936+ Getter getter,
1937+ Setter setter,
1938+ napi_property_attributes attributes = napi_default,
1939+ void* data = nullptr);
1940+ template <typename Getter, typename Setter>
1941+ static PropertyDescriptor Accessor(
1942+ napi_value name,
1943+ Getter getter,
1944+ Setter setter,
1945+ napi_property_attributes attributes = napi_default,
1946+ void* data = nullptr);
1947+ template <typename Getter, typename Setter>
1948+ static PropertyDescriptor Accessor(
1949+ Name name,
1950+ Getter getter,
1951+ Setter setter,
1952+ napi_property_attributes attributes = napi_default,
1953+ void* data = nullptr);
1954+ template <typename Callable>
1955+ static PropertyDescriptor Function(
1956+ const char* utf8name,
1957+ Callable cb,
1958+ napi_property_attributes attributes = napi_default,
1959+ void* data = nullptr);
1960+ template <typename Callable>
1961+ static PropertyDescriptor Function(
1962+ const std::string& utf8name,
1963+ Callable cb,
1964+ napi_property_attributes attributes = napi_default,
1965+ void* data = nullptr);
1966+ template <typename Callable>
1967+ static PropertyDescriptor Function(
1968+ napi_value name,
1969+ Callable cb,
1970+ napi_property_attributes attributes = napi_default,
1971+ void* data = nullptr);
1972+ template <typename Callable>
1973+ static PropertyDescriptor Function(
1974+ Name name,
1975+ Callable cb,
1976+ napi_property_attributes attributes = napi_default,
1977+ void* data = nullptr);
1978+#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
1979+
1980+ template <GetterCallback Getter>
1981+ static PropertyDescriptor Accessor(
1982+ const char* utf8name,
1983+ napi_property_attributes attributes = napi_default,
1984+ void* data = nullptr);
1985+
1986+ template <GetterCallback Getter>
1987+ static PropertyDescriptor Accessor(
1988+ const std::string& utf8name,
1989+ napi_property_attributes attributes = napi_default,
1990+ void* data = nullptr);
1991+
1992+ template <GetterCallback Getter>
1993+ static PropertyDescriptor Accessor(
1994+ Name name,
1995+ napi_property_attributes attributes = napi_default,
1996+ void* data = nullptr);
1997+
1998+ template <GetterCallback Getter, SetterCallback Setter>
1999+ static PropertyDescriptor Accessor(
2000+ const char* utf8name,
2001+ napi_property_attributes attributes = napi_default,
2002+ void* data = nullptr);
2003+
2004+ template <GetterCallback Getter, SetterCallback Setter>
2005+ static PropertyDescriptor Accessor(
2006+ const std::string& utf8name,
2007+ napi_property_attributes attributes = napi_default,
2008+ void* data = nullptr);
2009+
2010+ template <GetterCallback Getter, SetterCallback Setter>
2011+ static PropertyDescriptor Accessor(
2012+ Name name,
2013+ napi_property_attributes attributes = napi_default,
2014+ void* data = nullptr);
2015+
2016+ template <typename Getter>
2017+ static PropertyDescriptor Accessor(
2018+ Napi::Env env,
2019+ Napi::Object object,
2020+ const char* utf8name,
2021+ Getter getter,
2022+ napi_property_attributes attributes = napi_default,
2023+ void* data = nullptr);
2024+ template <typename Getter>
2025+ static PropertyDescriptor Accessor(
2026+ Napi::Env env,
2027+ Napi::Object object,
2028+ const std::string& utf8name,
2029+ Getter getter,
2030+ napi_property_attributes attributes = napi_default,
2031+ void* data = nullptr);
2032+ template <typename Getter>
2033+ static PropertyDescriptor Accessor(
2034+ Napi::Env env,
2035+ Napi::Object object,
2036+ Name name,
2037+ Getter getter,
2038+ napi_property_attributes attributes = napi_default,
2039+ void* data = nullptr);
2040+ template <typename Getter, typename Setter>
2041+ static PropertyDescriptor Accessor(
2042+ Napi::Env env,
2043+ Napi::Object object,
2044+ const char* utf8name,
2045+ Getter getter,
2046+ Setter setter,
2047+ napi_property_attributes attributes = napi_default,
2048+ void* data = nullptr);
2049+ template <typename Getter, typename Setter>
2050+ static PropertyDescriptor Accessor(
2051+ Napi::Env env,
2052+ Napi::Object object,
2053+ const std::string& utf8name,
2054+ Getter getter,
2055+ Setter setter,
2056+ napi_property_attributes attributes = napi_default,
2057+ void* data = nullptr);
2058+ template <typename Getter, typename Setter>
2059+ static PropertyDescriptor Accessor(
2060+ Napi::Env env,
2061+ Napi::Object object,
2062+ Name name,
2063+ Getter getter,
2064+ Setter setter,
2065+ napi_property_attributes attributes = napi_default,
2066+ void* data = nullptr);
2067+ template <typename Callable>
2068+ static PropertyDescriptor Function(
2069+ Napi::Env env,
2070+ Napi::Object object,
2071+ const char* utf8name,
2072+ Callable cb,
2073+ napi_property_attributes attributes = napi_default,
2074+ void* data = nullptr);
2075+ template <typename Callable>
2076+ static PropertyDescriptor Function(
2077+ Napi::Env env,
2078+ Napi::Object object,
2079+ const std::string& utf8name,
2080+ Callable cb,
2081+ napi_property_attributes attributes = napi_default,
2082+ void* data = nullptr);
2083+ template <typename Callable>
2084+ static PropertyDescriptor Function(
2085+ Napi::Env env,
2086+ Napi::Object object,
2087+ Name name,
2088+ Callable cb,
2089+ napi_property_attributes attributes = napi_default,
2090+ void* data = nullptr);
2091+ static PropertyDescriptor Value(
2092+ const char* utf8name,
2093+ napi_value value,
2094+ napi_property_attributes attributes = napi_default);
2095+ static PropertyDescriptor Value(
2096+ const std::string& utf8name,
2097+ napi_value value,
2098+ napi_property_attributes attributes = napi_default);
2099+ static PropertyDescriptor Value(
2100+ napi_value name,
2101+ napi_value value,
2102+ napi_property_attributes attributes = napi_default);
2103+ static PropertyDescriptor Value(
2104+ Name name,
2105+ Napi::Value value,
2106+ napi_property_attributes attributes = napi_default);
2107+
2108+ PropertyDescriptor(napi_property_descriptor desc);
2109+
2110+ operator napi_property_descriptor&();
2111+ operator const napi_property_descriptor&() const;
2112+
2113+ private:
2114+ napi_property_descriptor _desc;
2115+};
2116+
2117+/// Property descriptor for use with `ObjectWrap::DefineClass()`.
2118+///
2119+/// This is different from the standalone `PropertyDescriptor` because it is
2120+/// specific to each `ObjectWrap<T>` subclass. This prevents using descriptors
2121+/// from a different class when defining a new class (preventing the callbacks
2122+/// from having incorrect `this` pointers).
2123+template <typename T>
2124+class ClassPropertyDescriptor {
2125+ public:
2126+ ClassPropertyDescriptor(napi_property_descriptor desc) : _desc(desc) {}
2127+
2128+ operator napi_property_descriptor&() { return _desc; }
2129+ operator const napi_property_descriptor&() const { return _desc; }
2130+
2131+ private:
2132+ napi_property_descriptor _desc;
2133+};
2134+
2135+template <typename T, typename TCallback>
2136+struct MethodCallbackData {
2137+ TCallback callback;
2138+ void* data;
2139+};
2140+
2141+template <typename T, typename TGetterCallback, typename TSetterCallback>
2142+struct AccessorCallbackData {
2143+ TGetterCallback getterCallback;
2144+ TSetterCallback setterCallback;
2145+ void* data;
2146+};
2147+
2148+template <typename T>
2149+class InstanceWrap {
2150+ public:
2151+ using InstanceVoidMethodCallback = void (T::*)(const CallbackInfo& info);
2152+ using InstanceMethodCallback = Napi::Value (T::*)(const CallbackInfo& info);
2153+ using InstanceGetterCallback = Napi::Value (T::*)(const CallbackInfo& info);
2154+ using InstanceSetterCallback = void (T::*)(const CallbackInfo& info,
2155+ const Napi::Value& value);
2156+
2157+ using PropertyDescriptor = ClassPropertyDescriptor<T>;
2158+
2159+ static PropertyDescriptor InstanceMethod(
2160+ const char* utf8name,
2161+ InstanceVoidMethodCallback method,
2162+ napi_property_attributes attributes = napi_default,
2163+ void* data = nullptr);
2164+ static PropertyDescriptor InstanceMethod(
2165+ const char* utf8name,
2166+ InstanceMethodCallback method,
2167+ napi_property_attributes attributes = napi_default,
2168+ void* data = nullptr);
2169+ static PropertyDescriptor InstanceMethod(
2170+ Symbol name,
2171+ InstanceVoidMethodCallback method,
2172+ napi_property_attributes attributes = napi_default,
2173+ void* data = nullptr);
2174+ static PropertyDescriptor InstanceMethod(
2175+ Symbol name,
2176+ InstanceMethodCallback method,
2177+ napi_property_attributes attributes = napi_default,
2178+ void* data = nullptr);
2179+ template <InstanceVoidMethodCallback method>
2180+ static PropertyDescriptor InstanceMethod(
2181+ const char* utf8name,
2182+ napi_property_attributes attributes = napi_default,
2183+ void* data = nullptr);
2184+ template <InstanceMethodCallback method>
2185+ static PropertyDescriptor InstanceMethod(
2186+ const char* utf8name,
2187+ napi_property_attributes attributes = napi_default,
2188+ void* data = nullptr);
2189+ template <InstanceVoidMethodCallback method>
2190+ static PropertyDescriptor InstanceMethod(
2191+ Symbol name,
2192+ napi_property_attributes attributes = napi_default,
2193+ void* data = nullptr);
2194+ template <InstanceMethodCallback method>
2195+ static PropertyDescriptor InstanceMethod(
2196+ Symbol name,
2197+ napi_property_attributes attributes = napi_default,
2198+ void* data = nullptr);
2199+ static PropertyDescriptor InstanceAccessor(
2200+ const char* utf8name,
2201+ InstanceGetterCallback getter,
2202+ InstanceSetterCallback setter,
2203+ napi_property_attributes attributes = napi_default,
2204+ void* data = nullptr);
2205+ static PropertyDescriptor InstanceAccessor(
2206+ Symbol name,
2207+ InstanceGetterCallback getter,
2208+ InstanceSetterCallback setter,
2209+ napi_property_attributes attributes = napi_default,
2210+ void* data = nullptr);
2211+ template <InstanceGetterCallback getter,
2212+ InstanceSetterCallback setter = nullptr>
2213+ static PropertyDescriptor InstanceAccessor(
2214+ const char* utf8name,
2215+ napi_property_attributes attributes = napi_default,
2216+ void* data = nullptr);
2217+ template <InstanceGetterCallback getter,
2218+ InstanceSetterCallback setter = nullptr>
2219+ static PropertyDescriptor InstanceAccessor(
2220+ Symbol name,
2221+ napi_property_attributes attributes = napi_default,
2222+ void* data = nullptr);
2223+ static PropertyDescriptor InstanceValue(
2224+ const char* utf8name,
2225+ Napi::Value value,
2226+ napi_property_attributes attributes = napi_default);
2227+ static PropertyDescriptor InstanceValue(
2228+ Symbol name,
2229+ Napi::Value value,
2230+ napi_property_attributes attributes = napi_default);
2231+
2232+ protected:
2233+ static void AttachPropData(napi_env env,
2234+ napi_value value,
2235+ const napi_property_descriptor* prop);
2236+
2237+ private:
2238+ using This = InstanceWrap<T>;
2239+
2240+ using InstanceVoidMethodCallbackData =
2241+ MethodCallbackData<T, InstanceVoidMethodCallback>;
2242+ using InstanceMethodCallbackData =
2243+ MethodCallbackData<T, InstanceMethodCallback>;
2244+ using InstanceAccessorCallbackData =
2245+ AccessorCallbackData<T, InstanceGetterCallback, InstanceSetterCallback>;
2246+
2247+ static napi_value InstanceVoidMethodCallbackWrapper(napi_env env,
2248+ napi_callback_info info);
2249+ static napi_value InstanceMethodCallbackWrapper(napi_env env,
2250+ napi_callback_info info);
2251+ static napi_value InstanceGetterCallbackWrapper(napi_env env,
2252+ napi_callback_info info);
2253+ static napi_value InstanceSetterCallbackWrapper(napi_env env,
2254+ napi_callback_info info);
2255+
2256+ template <InstanceSetterCallback method>
2257+ static napi_value WrappedMethod(napi_env env,
2258+ napi_callback_info info) NAPI_NOEXCEPT;
2259+
2260+ template <InstanceSetterCallback setter>
2261+ struct SetterTag {};
2262+
2263+ template <InstanceSetterCallback setter>
2264+ static napi_callback WrapSetter(SetterTag<setter>) NAPI_NOEXCEPT {
2265+ return &This::WrappedMethod<setter>;
2266+ }
2267+ static napi_callback WrapSetter(SetterTag<nullptr>) NAPI_NOEXCEPT {
2268+ return nullptr;
2269+ }
2270+};
2271+
2272+/// Base class to be extended by C++ classes exposed to JavaScript; each C++
2273+/// class instance gets "wrapped" by a JavaScript object that is managed by this
2274+/// class.
2275+///
2276+/// At initialization time, the `DefineClass()` method must be used to
2277+/// hook up the accessor and method callbacks. It takes a list of
2278+/// property descriptors, which can be constructed via the various
2279+/// static methods on the base class.
2280+///
2281+/// #### Example:
2282+///
2283+/// class Example: public Napi::ObjectWrap<Example> {
2284+/// public:
2285+/// static void Initialize(Napi::Env& env, Napi::Object& target) {
2286+/// Napi::Function constructor = DefineClass(env, "Example", {
2287+/// InstanceAccessor<&Example::GetSomething,
2288+/// &Example::SetSomething>("value"),
2289+/// InstanceMethod<&Example::DoSomething>("doSomething"),
2290+/// });
2291+/// target.Set("Example", constructor);
2292+/// }
2293+///
2294+/// Example(const Napi::CallbackInfo& info); // Constructor
2295+/// Napi::Value GetSomething(const Napi::CallbackInfo& info);
2296+/// void SetSomething(const Napi::CallbackInfo& info, const Napi::Value&
2297+/// value); Napi::Value DoSomething(const Napi::CallbackInfo& info);
2298+/// }
2299+template <typename T>
2300+class ObjectWrap : public InstanceWrap<T>, public Reference<Object> {
2301+ public:
2302+ ObjectWrap(const CallbackInfo& callbackInfo);
2303+ virtual ~ObjectWrap();
2304+
2305+ static T* Unwrap(Object wrapper);
2306+
2307+ // Methods exposed to JavaScript must conform to one of these callback
2308+ // signatures.
2309+ using StaticVoidMethodCallback = void (*)(const CallbackInfo& info);
2310+ using StaticMethodCallback = Napi::Value (*)(const CallbackInfo& info);
2311+ using StaticGetterCallback = Napi::Value (*)(const CallbackInfo& info);
2312+ using StaticSetterCallback = void (*)(const CallbackInfo& info,
2313+ const Napi::Value& value);
2314+
2315+ using PropertyDescriptor = ClassPropertyDescriptor<T>;
2316+
2317+ static Function DefineClass(
2318+ Napi::Env env,
2319+ const char* utf8name,
2320+ const std::initializer_list<PropertyDescriptor>& properties,
2321+ void* data = nullptr);
2322+ static Function DefineClass(Napi::Env env,
2323+ const char* utf8name,
2324+ const std::vector<PropertyDescriptor>& properties,
2325+ void* data = nullptr);
2326+ static PropertyDescriptor StaticMethod(
2327+ const char* utf8name,
2328+ StaticVoidMethodCallback method,
2329+ napi_property_attributes attributes = napi_default,
2330+ void* data = nullptr);
2331+ static PropertyDescriptor StaticMethod(
2332+ const char* utf8name,
2333+ StaticMethodCallback method,
2334+ napi_property_attributes attributes = napi_default,
2335+ void* data = nullptr);
2336+ static PropertyDescriptor StaticMethod(
2337+ Symbol name,
2338+ StaticVoidMethodCallback method,
2339+ napi_property_attributes attributes = napi_default,
2340+ void* data = nullptr);
2341+ static PropertyDescriptor StaticMethod(
2342+ Symbol name,
2343+ StaticMethodCallback method,
2344+ napi_property_attributes attributes = napi_default,
2345+ void* data = nullptr);
2346+ template <StaticVoidMethodCallback method>
2347+ static PropertyDescriptor StaticMethod(
2348+ const char* utf8name,
2349+ napi_property_attributes attributes = napi_default,
2350+ void* data = nullptr);
2351+ template <StaticVoidMethodCallback method>
2352+ static PropertyDescriptor StaticMethod(
2353+ Symbol name,
2354+ napi_property_attributes attributes = napi_default,
2355+ void* data = nullptr);
2356+ template <StaticMethodCallback method>
2357+ static PropertyDescriptor StaticMethod(
2358+ const char* utf8name,
2359+ napi_property_attributes attributes = napi_default,
2360+ void* data = nullptr);
2361+ template <StaticMethodCallback method>
2362+ static PropertyDescriptor StaticMethod(
2363+ Symbol name,
2364+ napi_property_attributes attributes = napi_default,
2365+ void* data = nullptr);
2366+ static PropertyDescriptor StaticAccessor(
2367+ const char* utf8name,
2368+ StaticGetterCallback getter,
2369+ StaticSetterCallback setter,
2370+ napi_property_attributes attributes = napi_default,
2371+ void* data = nullptr);
2372+ static PropertyDescriptor StaticAccessor(
2373+ Symbol name,
2374+ StaticGetterCallback getter,
2375+ StaticSetterCallback setter,
2376+ napi_property_attributes attributes = napi_default,
2377+ void* data = nullptr);
2378+ template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr>
2379+ static PropertyDescriptor StaticAccessor(
2380+ const char* utf8name,
2381+ napi_property_attributes attributes = napi_default,
2382+ void* data = nullptr);
2383+ template <StaticGetterCallback getter, StaticSetterCallback setter = nullptr>
2384+ static PropertyDescriptor StaticAccessor(
2385+ Symbol name,
2386+ napi_property_attributes attributes = napi_default,
2387+ void* data = nullptr);
2388+ static PropertyDescriptor StaticValue(
2389+ const char* utf8name,
2390+ Napi::Value value,
2391+ napi_property_attributes attributes = napi_default);
2392+ static PropertyDescriptor StaticValue(
2393+ Symbol name,
2394+ Napi::Value value,
2395+ napi_property_attributes attributes = napi_default);
2396+ static Napi::Value OnCalledAsFunction(const Napi::CallbackInfo& callbackInfo);
2397+ virtual void Finalize(Napi::Env env);
2398+
2399+ private:
2400+ using This = ObjectWrap<T>;
2401+
2402+ static napi_value ConstructorCallbackWrapper(napi_env env,
2403+ napi_callback_info info);
2404+ static napi_value StaticVoidMethodCallbackWrapper(napi_env env,
2405+ napi_callback_info info);
2406+ static napi_value StaticMethodCallbackWrapper(napi_env env,
2407+ napi_callback_info info);
2408+ static napi_value StaticGetterCallbackWrapper(napi_env env,
2409+ napi_callback_info info);
2410+ static napi_value StaticSetterCallbackWrapper(napi_env env,
2411+ napi_callback_info info);
2412+ static void FinalizeCallback(napi_env env, void* data, void* hint);
2413+ static Function DefineClass(Napi::Env env,
2414+ const char* utf8name,
2415+ const size_t props_count,
2416+ const napi_property_descriptor* props,
2417+ void* data = nullptr);
2418+
2419+ using StaticVoidMethodCallbackData =
2420+ MethodCallbackData<T, StaticVoidMethodCallback>;
2421+ using StaticMethodCallbackData = MethodCallbackData<T, StaticMethodCallback>;
2422+
2423+ using StaticAccessorCallbackData =
2424+ AccessorCallbackData<T, StaticGetterCallback, StaticSetterCallback>;
2425+
2426+ template <StaticSetterCallback method>
2427+ static napi_value WrappedMethod(napi_env env,
2428+ napi_callback_info info) NAPI_NOEXCEPT;
2429+
2430+ template <StaticSetterCallback setter>
2431+ struct StaticSetterTag {};
2432+
2433+ template <StaticSetterCallback setter>
2434+ static napi_callback WrapStaticSetter(StaticSetterTag<setter>) NAPI_NOEXCEPT {
2435+ return &This::WrappedMethod<setter>;
2436+ }
2437+ static napi_callback WrapStaticSetter(StaticSetterTag<nullptr>)
2438+ NAPI_NOEXCEPT {
2439+ return nullptr;
2440+ }
2441+
2442+ bool _construction_failed = true;
2443+};
2444+
2445+class HandleScope {
2446+ public:
2447+ HandleScope(napi_env env, napi_handle_scope scope);
2448+ explicit HandleScope(Napi::Env env);
2449+ ~HandleScope();
2450+
2451+ // Disallow copying to prevent double close of napi_handle_scope
2452+ NAPI_DISALLOW_ASSIGN_COPY(HandleScope)
2453+
2454+ operator napi_handle_scope() const;
2455+
2456+ Napi::Env Env() const;
2457+
2458+ private:
2459+ napi_env _env;
2460+ napi_handle_scope _scope;
2461+};
2462+
2463+class EscapableHandleScope {
2464+ public:
2465+ EscapableHandleScope(napi_env env, napi_escapable_handle_scope scope);
2466+ explicit EscapableHandleScope(Napi::Env env);
2467+ ~EscapableHandleScope();
2468+
2469+ // Disallow copying to prevent double close of napi_escapable_handle_scope
2470+ NAPI_DISALLOW_ASSIGN_COPY(EscapableHandleScope)
2471+
2472+ operator napi_escapable_handle_scope() const;
2473+
2474+ Napi::Env Env() const;
2475+ Value Escape(napi_value escapee);
2476+
2477+ private:
2478+ napi_env _env;
2479+ napi_escapable_handle_scope _scope;
2480+};
2481+
2482+#if (NAPI_VERSION > 2)
2483+class CallbackScope {
2484+ public:
2485+ CallbackScope(napi_env env, napi_callback_scope scope);
2486+ CallbackScope(napi_env env, napi_async_context context);
2487+ virtual ~CallbackScope();
2488+
2489+ // Disallow copying to prevent double close of napi_callback_scope
2490+ NAPI_DISALLOW_ASSIGN_COPY(CallbackScope)
2491+
2492+ operator napi_callback_scope() const;
2493+
2494+ Napi::Env Env() const;
2495+
2496+ private:
2497+ napi_env _env;
2498+ napi_callback_scope _scope;
2499+};
2500+#endif
2501+
2502+class AsyncContext {
2503+ public:
2504+ explicit AsyncContext(napi_env env, const char* resource_name);
2505+ explicit AsyncContext(napi_env env,
2506+ const char* resource_name,
2507+ const Object& resource);
2508+ virtual ~AsyncContext();
2509+
2510+ AsyncContext(AsyncContext&& other);
2511+ AsyncContext& operator=(AsyncContext&& other);
2512+ NAPI_DISALLOW_ASSIGN_COPY(AsyncContext)
2513+
2514+ operator napi_async_context() const;
2515+
2516+ Napi::Env Env() const;
2517+
2518+ private:
2519+ napi_env _env;
2520+ napi_async_context _context;
2521+};
2522+
2523+#if NAPI_HAS_THREADS
2524+class AsyncWorker {
2525+ public:
2526+ virtual ~AsyncWorker();
2527+
2528+ NAPI_DISALLOW_ASSIGN_COPY(AsyncWorker)
2529+
2530+ operator napi_async_work() const;
2531+
2532+ Napi::Env Env() const;
2533+
2534+ void Queue();
2535+ void Cancel();
2536+ void SuppressDestruct();
2537+
2538+ ObjectReference& Receiver();
2539+ FunctionReference& Callback();
2540+
2541+ virtual void OnExecute(Napi::Env env);
2542+ virtual void OnWorkComplete(Napi::Env env, napi_status status);
2543+
2544+ protected:
2545+ explicit AsyncWorker(const Function& callback);
2546+ explicit AsyncWorker(const Function& callback, const char* resource_name);
2547+ explicit AsyncWorker(const Function& callback,
2548+ const char* resource_name,
2549+ const Object& resource);
2550+ explicit AsyncWorker(const Object& receiver, const Function& callback);
2551+ explicit AsyncWorker(const Object& receiver,
2552+ const Function& callback,
2553+ const char* resource_name);
2554+ explicit AsyncWorker(const Object& receiver,
2555+ const Function& callback,
2556+ const char* resource_name,
2557+ const Object& resource);
2558+
2559+ explicit AsyncWorker(Napi::Env env);
2560+ explicit AsyncWorker(Napi::Env env, const char* resource_name);
2561+ explicit AsyncWorker(Napi::Env env,
2562+ const char* resource_name,
2563+ const Object& resource);
2564+
2565+ virtual void Execute() = 0;
2566+ virtual void OnOK();
2567+ virtual void OnError(const Error& e);
2568+ virtual void Destroy();
2569+ virtual std::vector<napi_value> GetResult(Napi::Env env);
2570+
2571+ void SetError(const std::string& error);
2572+
2573+ private:
2574+ static inline void OnAsyncWorkExecute(napi_env env, void* asyncworker);
2575+ static inline void OnAsyncWorkComplete(napi_env env,
2576+ napi_status status,
2577+ void* asyncworker);
2578+
2579+ napi_env _env;
2580+ napi_async_work _work;
2581+ ObjectReference _receiver;
2582+ FunctionReference _callback;
2583+ std::string _error;
2584+ bool _suppress_destruct;
2585+};
2586+#endif // NAPI_HAS_THREADS
2587+
2588+#if (NAPI_VERSION > 3 && NAPI_HAS_THREADS)
2589+class ThreadSafeFunction {
2590+ public:
2591+ // This API may only be called from the main thread.
2592+ template <typename ResourceString>
2593+ static ThreadSafeFunction New(napi_env env,
2594+ const Function& callback,
2595+ ResourceString resourceName,
2596+ size_t maxQueueSize,
2597+ size_t initialThreadCount);
2598+
2599+ // This API may only be called from the main thread.
2600+ template <typename ResourceString, typename ContextType>
2601+ static ThreadSafeFunction New(napi_env env,
2602+ const Function& callback,
2603+ ResourceString resourceName,
2604+ size_t maxQueueSize,
2605+ size_t initialThreadCount,
2606+ ContextType* context);
2607+
2608+ // This API may only be called from the main thread.
2609+ template <typename ResourceString, typename Finalizer>
2610+ static ThreadSafeFunction New(napi_env env,
2611+ const Function& callback,
2612+ ResourceString resourceName,
2613+ size_t maxQueueSize,
2614+ size_t initialThreadCount,
2615+ Finalizer finalizeCallback);
2616+
2617+ // This API may only be called from the main thread.
2618+ template <typename ResourceString,
2619+ typename Finalizer,
2620+ typename FinalizerDataType>
2621+ static ThreadSafeFunction New(napi_env env,
2622+ const Function& callback,
2623+ ResourceString resourceName,
2624+ size_t maxQueueSize,
2625+ size_t initialThreadCount,
2626+ Finalizer finalizeCallback,
2627+ FinalizerDataType* data);
2628+
2629+ // This API may only be called from the main thread.
2630+ template <typename ResourceString, typename ContextType, typename Finalizer>
2631+ static ThreadSafeFunction New(napi_env env,
2632+ const Function& callback,
2633+ ResourceString resourceName,
2634+ size_t maxQueueSize,
2635+ size_t initialThreadCount,
2636+ ContextType* context,
2637+ Finalizer finalizeCallback);
2638+
2639+ // This API may only be called from the main thread.
2640+ template <typename ResourceString,
2641+ typename ContextType,
2642+ typename Finalizer,
2643+ typename FinalizerDataType>
2644+ static ThreadSafeFunction New(napi_env env,
2645+ const Function& callback,
2646+ ResourceString resourceName,
2647+ size_t maxQueueSize,
2648+ size_t initialThreadCount,
2649+ ContextType* context,
2650+ Finalizer finalizeCallback,
2651+ FinalizerDataType* data);
2652+
2653+ // This API may only be called from the main thread.
2654+ template <typename ResourceString>
2655+ static ThreadSafeFunction New(napi_env env,
2656+ const Function& callback,
2657+ const Object& resource,
2658+ ResourceString resourceName,
2659+ size_t maxQueueSize,
2660+ size_t initialThreadCount);
2661+
2662+ // This API may only be called from the main thread.
2663+ template <typename ResourceString, typename ContextType>
2664+ static ThreadSafeFunction New(napi_env env,
2665+ const Function& callback,
2666+ const Object& resource,
2667+ ResourceString resourceName,
2668+ size_t maxQueueSize,
2669+ size_t initialThreadCount,
2670+ ContextType* context);
2671+
2672+ // This API may only be called from the main thread.
2673+ template <typename ResourceString, typename Finalizer>
2674+ static ThreadSafeFunction New(napi_env env,
2675+ const Function& callback,
2676+ const Object& resource,
2677+ ResourceString resourceName,
2678+ size_t maxQueueSize,
2679+ size_t initialThreadCount,
2680+ Finalizer finalizeCallback);
2681+
2682+ // This API may only be called from the main thread.
2683+ template <typename ResourceString,
2684+ typename Finalizer,
2685+ typename FinalizerDataType>
2686+ static ThreadSafeFunction New(napi_env env,
2687+ const Function& callback,
2688+ const Object& resource,
2689+ ResourceString resourceName,
2690+ size_t maxQueueSize,
2691+ size_t initialThreadCount,
2692+ Finalizer finalizeCallback,
2693+ FinalizerDataType* data);
2694+
2695+ // This API may only be called from the main thread.
2696+ template <typename ResourceString, typename ContextType, typename Finalizer>
2697+ static ThreadSafeFunction New(napi_env env,
2698+ const Function& callback,
2699+ const Object& resource,
2700+ ResourceString resourceName,
2701+ size_t maxQueueSize,
2702+ size_t initialThreadCount,
2703+ ContextType* context,
2704+ Finalizer finalizeCallback);
2705+
2706+ // This API may only be called from the main thread.
2707+ template <typename ResourceString,
2708+ typename ContextType,
2709+ typename Finalizer,
2710+ typename FinalizerDataType>
2711+ static ThreadSafeFunction New(napi_env env,
2712+ const Function& callback,
2713+ const Object& resource,
2714+ ResourceString resourceName,
2715+ size_t maxQueueSize,
2716+ size_t initialThreadCount,
2717+ ContextType* context,
2718+ Finalizer finalizeCallback,
2719+ FinalizerDataType* data);
2720+
2721+ ThreadSafeFunction();
2722+ ThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2723+
2724+ operator napi_threadsafe_function() const;
2725+
2726+ // This API may be called from any thread.
2727+ napi_status BlockingCall() const;
2728+
2729+ // This API may be called from any thread.
2730+ template <typename Callback>
2731+ napi_status BlockingCall(Callback callback) const;
2732+
2733+ // This API may be called from any thread.
2734+ template <typename DataType, typename Callback>
2735+ napi_status BlockingCall(DataType* data, Callback callback) const;
2736+
2737+ // This API may be called from any thread.
2738+ napi_status NonBlockingCall() const;
2739+
2740+ // This API may be called from any thread.
2741+ template <typename Callback>
2742+ napi_status NonBlockingCall(Callback callback) const;
2743+
2744+ // This API may be called from any thread.
2745+ template <typename DataType, typename Callback>
2746+ napi_status NonBlockingCall(DataType* data, Callback callback) const;
2747+
2748+ // This API may only be called from the main thread.
2749+ void Ref(napi_env env) const;
2750+
2751+ // This API may only be called from the main thread.
2752+ void Unref(napi_env env) const;
2753+
2754+ // This API may be called from any thread.
2755+ napi_status Acquire() const;
2756+
2757+ // This API may be called from any thread.
2758+ napi_status Release() const;
2759+
2760+ // This API may be called from any thread.
2761+ napi_status Abort() const;
2762+
2763+ struct ConvertibleContext {
2764+ template <class T>
2765+ operator T*() {
2766+ return static_cast<T*>(context);
2767+ }
2768+ void* context;
2769+ };
2770+
2771+ // This API may be called from any thread.
2772+ ConvertibleContext GetContext() const;
2773+
2774+ private:
2775+ using CallbackWrapper = std::function<void(Napi::Env, Napi::Function)>;
2776+
2777+ template <typename ResourceString,
2778+ typename ContextType,
2779+ typename Finalizer,
2780+ typename FinalizerDataType>
2781+ static ThreadSafeFunction New(napi_env env,
2782+ const Function& callback,
2783+ const Object& resource,
2784+ ResourceString resourceName,
2785+ size_t maxQueueSize,
2786+ size_t initialThreadCount,
2787+ ContextType* context,
2788+ Finalizer finalizeCallback,
2789+ FinalizerDataType* data,
2790+ napi_finalize wrapper);
2791+
2792+ napi_status CallInternal(CallbackWrapper* callbackWrapper,
2793+ napi_threadsafe_function_call_mode mode) const;
2794+
2795+ static void CallJS(napi_env env,
2796+ napi_value jsCallback,
2797+ void* context,
2798+ void* data);
2799+
2800+ napi_threadsafe_function _tsfn;
2801+};
2802+
2803+// A TypedThreadSafeFunction by default has no context (nullptr) and can
2804+// accept any type (void) to its CallJs.
2805+template <typename ContextType = std::nullptr_t,
2806+ typename DataType = void,
2807+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*) =
2808+ nullptr>
2809+class TypedThreadSafeFunction {
2810+ public:
2811+ // This API may only be called from the main thread.
2812+ // Helper function that returns nullptr if running Node-API 5+, otherwise a
2813+ // non-empty, no-op Function. This provides the ability to specify at
2814+ // compile-time a callback parameter to `New` that safely does no action
2815+ // when targeting _any_ Node-API version.
2816+#if NAPI_VERSION > 4
2817+ static std::nullptr_t EmptyFunctionFactory(Napi::Env env);
2818+#else
2819+ static Napi::Function EmptyFunctionFactory(Napi::Env env);
2820+#endif
2821+ static Napi::Function FunctionOrEmpty(Napi::Env env,
2822+ Napi::Function& callback);
2823+
2824+#if NAPI_VERSION > 4
2825+ // This API may only be called from the main thread.
2826+ // Creates a new threadsafe function with:
2827+ // Callback [missing] Resource [missing] Finalizer [missing]
2828+ template <typename ResourceString>
2829+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2830+ napi_env env,
2831+ ResourceString resourceName,
2832+ size_t maxQueueSize,
2833+ size_t initialThreadCount,
2834+ ContextType* context = nullptr);
2835+
2836+ // This API may only be called from the main thread.
2837+ // Creates a new threadsafe function with:
2838+ // Callback [missing] Resource [passed] Finalizer [missing]
2839+ template <typename ResourceString>
2840+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2841+ napi_env env,
2842+ const Object& resource,
2843+ ResourceString resourceName,
2844+ size_t maxQueueSize,
2845+ size_t initialThreadCount,
2846+ ContextType* context = nullptr);
2847+
2848+ // This API may only be called from the main thread.
2849+ // Creates a new threadsafe function with:
2850+ // Callback [missing] Resource [missing] Finalizer [passed]
2851+ template <typename ResourceString,
2852+ typename Finalizer,
2853+ typename FinalizerDataType = void>
2854+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2855+ napi_env env,
2856+ ResourceString resourceName,
2857+ size_t maxQueueSize,
2858+ size_t initialThreadCount,
2859+ ContextType* context,
2860+ Finalizer finalizeCallback,
2861+ FinalizerDataType* data = nullptr);
2862+
2863+ // This API may only be called from the main thread.
2864+ // Creates a new threadsafe function with:
2865+ // Callback [missing] Resource [passed] Finalizer [passed]
2866+ template <typename ResourceString,
2867+ typename Finalizer,
2868+ typename FinalizerDataType = void>
2869+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2870+ napi_env env,
2871+ const Object& resource,
2872+ ResourceString resourceName,
2873+ size_t maxQueueSize,
2874+ size_t initialThreadCount,
2875+ ContextType* context,
2876+ Finalizer finalizeCallback,
2877+ FinalizerDataType* data = nullptr);
2878+#endif
2879+
2880+ // This API may only be called from the main thread.
2881+ // Creates a new threadsafe function with:
2882+ // Callback [passed] Resource [missing] Finalizer [missing]
2883+ template <typename ResourceString>
2884+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2885+ napi_env env,
2886+ const Function& callback,
2887+ ResourceString resourceName,
2888+ size_t maxQueueSize,
2889+ size_t initialThreadCount,
2890+ ContextType* context = nullptr);
2891+
2892+ // This API may only be called from the main thread.
2893+ // Creates a new threadsafe function with:
2894+ // Callback [passed] Resource [passed] Finalizer [missing]
2895+ template <typename ResourceString>
2896+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2897+ napi_env env,
2898+ const Function& callback,
2899+ const Object& resource,
2900+ ResourceString resourceName,
2901+ size_t maxQueueSize,
2902+ size_t initialThreadCount,
2903+ ContextType* context = nullptr);
2904+
2905+ // This API may only be called from the main thread.
2906+ // Creates a new threadsafe function with:
2907+ // Callback [passed] Resource [missing] Finalizer [passed]
2908+ template <typename ResourceString,
2909+ typename Finalizer,
2910+ typename FinalizerDataType = void>
2911+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2912+ napi_env env,
2913+ const Function& callback,
2914+ ResourceString resourceName,
2915+ size_t maxQueueSize,
2916+ size_t initialThreadCount,
2917+ ContextType* context,
2918+ Finalizer finalizeCallback,
2919+ FinalizerDataType* data = nullptr);
2920+
2921+ // This API may only be called from the main thread.
2922+ // Creates a new threadsafe function with:
2923+ // Callback [passed] Resource [passed] Finalizer [passed]
2924+ template <typename CallbackType,
2925+ typename ResourceString,
2926+ typename Finalizer,
2927+ typename FinalizerDataType>
2928+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2929+ napi_env env,
2930+ CallbackType callback,
2931+ const Object& resource,
2932+ ResourceString resourceName,
2933+ size_t maxQueueSize,
2934+ size_t initialThreadCount,
2935+ ContextType* context,
2936+ Finalizer finalizeCallback,
2937+ FinalizerDataType* data = nullptr);
2938+
2939+ TypedThreadSafeFunction();
2940+ TypedThreadSafeFunction(napi_threadsafe_function tsFunctionValue);
2941+
2942+ operator napi_threadsafe_function() const;
2943+
2944+ // This API may be called from any thread.
2945+ napi_status BlockingCall(DataType* data = nullptr) const;
2946+
2947+ // This API may be called from any thread.
2948+ napi_status NonBlockingCall(DataType* data = nullptr) const;
2949+
2950+ // This API may only be called from the main thread.
2951+ void Ref(napi_env env) const;
2952+
2953+ // This API may only be called from the main thread.
2954+ void Unref(napi_env env) const;
2955+
2956+ // This API may be called from any thread.
2957+ napi_status Acquire() const;
2958+
2959+ // This API may be called from any thread.
2960+ napi_status Release() const;
2961+
2962+ // This API may be called from any thread.
2963+ napi_status Abort() const;
2964+
2965+ // This API may be called from any thread.
2966+ ContextType* GetContext() const;
2967+
2968+ private:
2969+ template <typename ResourceString,
2970+ typename Finalizer,
2971+ typename FinalizerDataType>
2972+ static TypedThreadSafeFunction<ContextType, DataType, CallJs> New(
2973+ napi_env env,
2974+ const Function& callback,
2975+ const Object& resource,
2976+ ResourceString resourceName,
2977+ size_t maxQueueSize,
2978+ size_t initialThreadCount,
2979+ ContextType* context,
2980+ Finalizer finalizeCallback,
2981+ FinalizerDataType* data,
2982+ napi_finalize wrapper);
2983+
2984+ static void CallJsInternal(napi_env env,
2985+ napi_value jsCallback,
2986+ void* context,
2987+ void* data);
2988+
2989+ protected:
2990+ napi_threadsafe_function _tsfn;
2991+};
2992+template <typename DataType>
2993+class AsyncProgressWorkerBase : public AsyncWorker {
2994+ public:
2995+ virtual void OnWorkProgress(DataType* data) = 0;
2996+ class ThreadSafeData {
2997+ public:
2998+ ThreadSafeData(AsyncProgressWorkerBase* asyncprogressworker, DataType* data)
2999+ : _asyncprogressworker(asyncprogressworker), _data(data) {}
3000+
3001+ AsyncProgressWorkerBase* asyncprogressworker() {
3002+ return _asyncprogressworker;
3003+ };
3004+ DataType* data() { return _data; };
3005+
3006+ private:
3007+ AsyncProgressWorkerBase* _asyncprogressworker;
3008+ DataType* _data;
3009+ };
3010+ void OnWorkComplete(Napi::Env env, napi_status status) override;
3011+
3012+ protected:
3013+ explicit AsyncProgressWorkerBase(const Object& receiver,
3014+ const Function& callback,
3015+ const char* resource_name,
3016+ const Object& resource,
3017+ size_t queue_size = 1);
3018+ virtual ~AsyncProgressWorkerBase();
3019+
3020+// Optional callback of Napi::ThreadSafeFunction only available after
3021+// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3022+#if NAPI_VERSION > 4
3023+ explicit AsyncProgressWorkerBase(Napi::Env env,
3024+ const char* resource_name,
3025+ const Object& resource,
3026+ size_t queue_size = 1);
3027+#endif
3028+
3029+ static inline void OnAsyncWorkProgress(Napi::Env env,
3030+ Napi::Function jsCallback,
3031+ void* data);
3032+
3033+ napi_status NonBlockingCall(DataType* data);
3034+
3035+ private:
3036+ ThreadSafeFunction _tsfn;
3037+ bool _work_completed = false;
3038+ napi_status _complete_status;
3039+ static inline void OnThreadSafeFunctionFinalize(
3040+ Napi::Env env, void* data, AsyncProgressWorkerBase* context);
3041+};
3042+
3043+template <class T>
3044+class AsyncProgressWorker : public AsyncProgressWorkerBase<void> {
3045+ public:
3046+ virtual ~AsyncProgressWorker();
3047+
3048+ class ExecutionProgress {
3049+ friend class AsyncProgressWorker;
3050+
3051+ public:
3052+ void Signal() const;
3053+ void Send(const T* data, size_t count) const;
3054+
3055+ private:
3056+ explicit ExecutionProgress(AsyncProgressWorker* worker) : _worker(worker) {}
3057+ AsyncProgressWorker* const _worker;
3058+ };
3059+
3060+ void OnWorkProgress(void*) override;
3061+
3062+ protected:
3063+ explicit AsyncProgressWorker(const Function& callback);
3064+ explicit AsyncProgressWorker(const Function& callback,
3065+ const char* resource_name);
3066+ explicit AsyncProgressWorker(const Function& callback,
3067+ const char* resource_name,
3068+ const Object& resource);
3069+ explicit AsyncProgressWorker(const Object& receiver,
3070+ const Function& callback);
3071+ explicit AsyncProgressWorker(const Object& receiver,
3072+ const Function& callback,
3073+ const char* resource_name);
3074+ explicit AsyncProgressWorker(const Object& receiver,
3075+ const Function& callback,
3076+ const char* resource_name,
3077+ const Object& resource);
3078+
3079+// Optional callback of Napi::ThreadSafeFunction only available after
3080+// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3081+#if NAPI_VERSION > 4
3082+ explicit AsyncProgressWorker(Napi::Env env);
3083+ explicit AsyncProgressWorker(Napi::Env env, const char* resource_name);
3084+ explicit AsyncProgressWorker(Napi::Env env,
3085+ const char* resource_name,
3086+ const Object& resource);
3087+#endif
3088+ virtual void Execute(const ExecutionProgress& progress) = 0;
3089+ virtual void OnProgress(const T* data, size_t count) = 0;
3090+
3091+ private:
3092+ void Execute() override;
3093+ void Signal();
3094+ void SendProgress_(const T* data, size_t count);
3095+
3096+ std::mutex _mutex;
3097+ T* _asyncdata;
3098+ size_t _asyncsize;
3099+ bool _signaled;
3100+};
3101+
3102+template <class T>
3103+class AsyncProgressQueueWorker
3104+ : public AsyncProgressWorkerBase<std::pair<T*, size_t>> {
3105+ public:
3106+ virtual ~AsyncProgressQueueWorker(){};
3107+
3108+ class ExecutionProgress {
3109+ friend class AsyncProgressQueueWorker;
3110+
3111+ public:
3112+ void Signal() const;
3113+ void Send(const T* data, size_t count) const;
3114+
3115+ private:
3116+ explicit ExecutionProgress(AsyncProgressQueueWorker* worker)
3117+ : _worker(worker) {}
3118+ AsyncProgressQueueWorker* const _worker;
3119+ };
3120+
3121+ void OnWorkComplete(Napi::Env env, napi_status status) override;
3122+ void OnWorkProgress(std::pair<T*, size_t>*) override;
3123+
3124+ protected:
3125+ explicit AsyncProgressQueueWorker(const Function& callback);
3126+ explicit AsyncProgressQueueWorker(const Function& callback,
3127+ const char* resource_name);
3128+ explicit AsyncProgressQueueWorker(const Function& callback,
3129+ const char* resource_name,
3130+ const Object& resource);
3131+ explicit AsyncProgressQueueWorker(const Object& receiver,
3132+ const Function& callback);
3133+ explicit AsyncProgressQueueWorker(const Object& receiver,
3134+ const Function& callback,
3135+ const char* resource_name);
3136+ explicit AsyncProgressQueueWorker(const Object& receiver,
3137+ const Function& callback,
3138+ const char* resource_name,
3139+ const Object& resource);
3140+
3141+// Optional callback of Napi::ThreadSafeFunction only available after
3142+// NAPI_VERSION 4. Refs: https://github.com/nodejs/node/pull/27791
3143+#if NAPI_VERSION > 4
3144+ explicit AsyncProgressQueueWorker(Napi::Env env);
3145+ explicit AsyncProgressQueueWorker(Napi::Env env, const char* resource_name);
3146+ explicit AsyncProgressQueueWorker(Napi::Env env,
3147+ const char* resource_name,
3148+ const Object& resource);
3149+#endif
3150+ virtual void Execute(const ExecutionProgress& progress) = 0;
3151+ virtual void OnProgress(const T* data, size_t count) = 0;
3152+
3153+ private:
3154+ void Execute() override;
3155+ void Signal() const;
3156+ void SendProgress_(const T* data, size_t count);
3157+};
3158+#endif // NAPI_VERSION > 3 && NAPI_HAS_THREADS
3159+
3160+// Memory management.
3161+class MemoryManagement {
3162+ public:
3163+ static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
3164+};
3165+
3166+// Version management
3167+class VersionManagement {
3168+ public:
3169+ static uint32_t GetNapiVersion(Env env);
3170+ static const napi_node_version* GetNodeVersion(Env env);
3171+};
3172+
3173+#if NAPI_VERSION > 5
3174+template <typename T>
3175+class Addon : public InstanceWrap<T> {
3176+ public:
3177+ static inline Object Init(Env env, Object exports);
3178+ static T* Unwrap(Object wrapper);
3179+
3180+ protected:
3181+ using AddonProp = ClassPropertyDescriptor<T>;
3182+ void DefineAddon(Object exports,
3183+ const std::initializer_list<AddonProp>& props);
3184+ Napi::Object DefineProperties(Object object,
3185+ const std::initializer_list<AddonProp>& props);
3186+
3187+ private:
3188+ Object entry_point_;
3189+};
3190+#endif // NAPI_VERSION > 5
3191+
3192+#ifdef NAPI_CPP_CUSTOM_NAMESPACE
3193+} // namespace NAPI_CPP_CUSTOM_NAMESPACE
3194+#endif
3195+
3196+} // namespace Napi
3197+
3198+// Inline implementations of all the above class methods are included here.
3199+#include "napi-inl.h"
3200+
3201+#endif // SRC_NAPI_H_
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