neon 3.0.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/README.md +70 -5
  2. package/dist/_chunks/auth_selection-DGgq6ifc.js +83 -0
  3. package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
  4. package/dist/_chunks/credentials-MYdHdKah.js +188 -0
  5. package/dist/_chunks/env-NbA61JR3.js +585 -0
  6. package/dist/_chunks/env_services-Tz9G4JeT.js +531 -0
  7. package/dist/_chunks/paths-DMq0Lt7a.js +151 -0
  8. package/dist/_chunks/profiles-Ir29rqns.js +217 -0
  9. package/dist/_chunks/psql-DWH-kc69.js +2169 -0
  10. package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
  11. package/dist/_chunks/secure_file-BucZj4yQ.js +39 -0
  12. package/dist/analytics.js +163 -207
  13. package/dist/api.js +815 -758
  14. package/dist/auth.js +121 -141
  15. package/dist/auth_context.js +39 -53
  16. package/dist/cli.js +4 -7
  17. package/dist/commands/api.js +220 -250
  18. package/dist/commands/api_keys.js +251 -314
  19. package/dist/commands/auth.js +283 -328
  20. package/dist/commands/bootstrap.js +372 -437
  21. package/dist/commands/branches.js +304 -455
  22. package/dist/commands/bucket.js +374 -514
  23. package/dist/commands/checkout.js +213 -298
  24. package/dist/commands/config.js +573 -690
  25. package/dist/commands/connection_string.js +137 -165
  26. package/dist/commands/data_api.js +238 -260
  27. package/dist/commands/databases.js +67 -76
  28. package/dist/commands/deploy.js +31 -25
  29. package/dist/commands/dev.js +639 -719
  30. package/dist/commands/diff.js +156 -200
  31. package/dist/commands/env.js +255 -305
  32. package/dist/commands/functions.js +275 -355
  33. package/dist/commands/index.js +70 -65
  34. package/dist/commands/init.js +84 -119
  35. package/dist/commands/inspect.js +55 -55
  36. package/dist/commands/ip_allow.js +88 -120
  37. package/dist/commands/link.js +874 -1019
  38. package/dist/commands/logs.js +291 -0
  39. package/dist/commands/neon_auth.js +725 -933
  40. package/dist/commands/operations.js +34 -25
  41. package/dist/commands/orgs.js +28 -18
  42. package/dist/commands/profile.js +615 -846
  43. package/dist/commands/projects.js +313 -373
  44. package/dist/commands/psql.js +60 -58
  45. package/dist/commands/roles.js +55 -58
  46. package/dist/commands/schema_diff.js +87 -131
  47. package/dist/commands/set_context.js +34 -26
  48. package/dist/commands/snapshots.js +288 -413
  49. package/dist/commands/status.js +41 -37
  50. package/dist/commands/user.js +21 -10
  51. package/dist/commands/vpc_endpoints.js +85 -113
  52. package/dist/config.js +7 -6
  53. package/dist/config_format.js +50 -66
  54. package/dist/config_template.js +128 -157
  55. package/dist/context.js +183 -235
  56. package/dist/current_branch_fast_path.js +40 -49
  57. package/dist/dev/env.js +2 -446
  58. package/dist/dev/functions.js +54 -68
  59. package/dist/dev/inputs.js +46 -58
  60. package/dist/dev/runtime.js +135 -164
  61. package/dist/dev/websocket.js +766 -959
  62. package/dist/env.js +27 -33
  63. package/dist/env_file.js +118 -132
  64. package/dist/env_services.js +2 -51
  65. package/dist/errors.js +57 -68
  66. package/dist/functions_api.js +45 -43
  67. package/dist/help.js +189 -140
  68. package/dist/index.js +182 -257
  69. package/dist/init/agents.js +137 -118
  70. package/dist/init/auth.js +58 -68
  71. package/dist/init/bootstrap.js +325 -396
  72. package/dist/init/build_config.js +4 -2
  73. package/dist/init/detect_agent.js +56 -101
  74. package/dist/init/editors.js +35 -52
  75. package/dist/init/enrich_output.js +51 -66
  76. package/dist/init/extension.js +134 -171
  77. package/dist/init/inspect.js +179 -266
  78. package/dist/init/interactive.js +510 -622
  79. package/dist/init/neonctl.js +117 -168
  80. package/dist/init/orchestrate.js +157 -173
  81. package/dist/init/phases/auth.js +188 -202
  82. package/dist/init/phases/cleanup.js +23 -23
  83. package/dist/init/phases/db.js +251 -277
  84. package/dist/init/phases/getting_started.js +213 -223
  85. package/dist/init/phases/mcp.js +174 -224
  86. package/dist/init/phases/migrations.js +247 -248
  87. package/dist/init/phases/neon_auth.js +114 -133
  88. package/dist/init/phases/setup.js +546 -703
  89. package/dist/init/phases/skills.js +75 -86
  90. package/dist/init/phases/status.js +72 -67
  91. package/dist/init/resolve_context.js +102 -99
  92. package/dist/init/route_command.js +91 -98
  93. package/dist/init/skills.js +174 -218
  94. package/dist/init/vsix.js +77 -99
  95. package/dist/log.js +17 -16
  96. package/dist/neon_services.js +104 -129
  97. package/dist/parameters.gen.js +481 -471
  98. package/dist/pkg.js +17 -19
  99. package/dist/profile_keys.js +44 -47
  100. package/dist/psql/cli.js +44 -47
  101. package/dist/psql/command/cmd_cond.js +231 -406
  102. package/dist/psql/command/cmd_connect.js +557 -764
  103. package/dist/psql/command/cmd_copy.js +728 -984
  104. package/dist/psql/command/cmd_describe.js +1499 -1688
  105. package/dist/psql/command/cmd_format.js +733 -905
  106. package/dist/psql/command/cmd_io.js +2 -2193
  107. package/dist/psql/command/cmd_lo.js +297 -359
  108. package/dist/psql/command/cmd_meta.js +727 -878
  109. package/dist/psql/command/cmd_misc.js +138 -172
  110. package/dist/psql/command/cmd_pipeline.js +2 -1148
  111. package/dist/psql/command/cmd_restrict.js +119 -155
  112. package/dist/psql/command/cmd_show.js +529 -688
  113. package/dist/psql/command/dispatch.js +260 -325
  114. package/dist/psql/command/inputQueue.js +35 -33
  115. package/dist/psql/command/shared.js +49 -63
  116. package/dist/psql/complete/filenames.js +90 -133
  117. package/dist/psql/complete/index.js +59 -97
  118. package/dist/psql/complete/matcher.js +236 -300
  119. package/dist/psql/complete/psqlVars.js +218 -223
  120. package/dist/psql/complete/queries.js +159 -177
  121. package/dist/psql/complete/rules.js +1493 -2299
  122. package/dist/psql/core/common.js +2 -1253
  123. package/dist/psql/core/help.js +456 -546
  124. package/dist/psql/core/mainloop.js +692 -1303
  125. package/dist/psql/core/prompt.js +391 -408
  126. package/dist/psql/core/settings.js +429 -644
  127. package/dist/psql/core/sqlHelp.js +480 -554
  128. package/dist/psql/core/startup.js +2 -846
  129. package/dist/psql/core/syncVars.js +67 -110
  130. package/dist/psql/core/variables.js +156 -278
  131. package/dist/psql/describe/formatters.js +884 -1285
  132. package/dist/psql/describe/processNamePattern.js +173 -260
  133. package/dist/psql/describe/queries.js +1368 -2403
  134. package/dist/psql/describe/versionGate.js +32 -41
  135. package/dist/psql/index.js +2 -2030
  136. package/dist/psql/io/history.js +232 -271
  137. package/dist/psql/io/input.js +103 -108
  138. package/dist/psql/io/lineEditor/buffer.js +238 -319
  139. package/dist/psql/io/lineEditor/complete.js +135 -213
  140. package/dist/psql/io/lineEditor/filename.js +139 -148
  141. package/dist/psql/io/lineEditor/index.js +653 -870
  142. package/dist/psql/io/lineEditor/keymap.js +544 -702
  143. package/dist/psql/io/lineEditor/vt100.js +294 -341
  144. package/dist/psql/io/pgpass.js +158 -187
  145. package/dist/psql/io/pgservice.js +146 -183
  146. package/dist/psql/io/psqlrc.js +328 -403
  147. package/dist/psql/print/aligned.js +1020 -1683
  148. package/dist/psql/print/asciidoc.js +180 -214
  149. package/dist/psql/print/crosstab.js +281 -442
  150. package/dist/psql/print/csv.js +48 -70
  151. package/dist/psql/print/html.js +195 -226
  152. package/dist/psql/print/json.js +75 -88
  153. package/dist/psql/print/latex.js +291 -364
  154. package/dist/psql/print/pager.js +171 -242
  155. package/dist/psql/print/troff.js +194 -226
  156. package/dist/psql/print/unaligned.js +69 -95
  157. package/dist/psql/print/units.js +167 -169
  158. package/dist/psql/scanner/slash.js +428 -483
  159. package/dist/psql/scanner/sql.js +445 -889
  160. package/dist/psql/scanner/stringutils.js +309 -379
  161. package/dist/psql/types/index.js +8 -7
  162. package/dist/psql/types/scanner.js +25 -22
  163. package/dist/psql/wire/connection.js +2042 -2803
  164. package/dist/psql/wire/copy.js +84 -100
  165. package/dist/psql/wire/notify.js +39 -59
  166. package/dist/psql/wire/pipeline.js +305 -518
  167. package/dist/psql/wire/protocol.js +349 -417
  168. package/dist/psql/wire/sasl.js +180 -265
  169. package/dist/psql/wire/tls.js +400 -561
  170. package/dist/storage_api.js +115 -129
  171. package/dist/test_utils/fixtures.js +94 -113
  172. package/dist/test_utils/oauth_server.js +10 -7
  173. package/dist/test_utils/project_dir.js +33 -0
  174. package/dist/utils/ai_gateway_notice.js +131 -162
  175. package/dist/utils/api_enums.js +21 -28
  176. package/dist/utils/auth.js +10 -4
  177. package/dist/utils/branch_notice.js +20 -19
  178. package/dist/utils/branch_picker.js +83 -89
  179. package/dist/utils/cli_name.js +15 -12
  180. package/dist/utils/compute_units.js +20 -27
  181. package/dist/utils/config_diff.js +127 -158
  182. package/dist/utils/enrichers.js +95 -148
  183. package/dist/utils/esbuild.js +130 -189
  184. package/dist/utils/flags.js +35 -47
  185. package/dist/utils/formats.js +8 -15
  186. package/dist/utils/git_diff.js +69 -80
  187. package/dist/utils/inspect_db.js +101 -143
  188. package/dist/utils/inspect_queries.js +179 -142
  189. package/dist/utils/middlewares.js +39 -45
  190. package/dist/utils/openapi.js +87 -99
  191. package/dist/utils/package_manager.js +312 -110
  192. package/dist/utils/point_in_time.js +49 -53
  193. package/dist/utils/psql.js +89 -106
  194. package/dist/utils/service_picker.js +55 -58
  195. package/dist/utils/string.js +5 -5
  196. package/dist/utils/ui.js +38 -55
  197. package/dist/utils/write_sync.js +26 -35
  198. package/dist/utils/zip.js +4 -3
  199. package/dist/writer.js +67 -87
  200. package/package.json +11 -6
  201. package/dist/_shared/auth_selection.js +0 -86
  202. package/dist/_shared/credentials.js +0 -209
  203. package/dist/_shared/env-core/env.js +0 -558
  204. package/dist/_shared/env-core/reuse-secrets.js +0 -223
  205. package/dist/_shared/paths.js +0 -148
  206. package/dist/_shared/profiles.js +0 -276
  207. package/dist/_shared/secure_file.js +0 -43
@@ -1,159 +1,106 @@
1
1
  import { isNeonApiError, messageFromBody } from "../api.js";
2
2
  import { isConfigInit, isCurrentBranchProbe } from "../context.js";
3
3
  import { looksLikeBranchId } from "./formats.js";
4
- export const branchIdResolve = async ({ branch, apiClient, projectId, }) => {
5
- branch = branch.toString();
6
- if (looksLikeBranchId(branch)) {
7
- return branch;
8
- }
9
- const { data } = await apiClient.listProjectBranches({
10
- projectId,
11
- });
12
- const branchData = data.branches.find((b) => b.name === branch);
13
- if (!branchData) {
14
- throw new Error(`Branch ${branch} not found.\nAvailable branches: ${data.branches
15
- .map((b) => b.name)
16
- .join(", ")}`);
17
- }
18
- return branchData.id;
4
+ //#region src/utils/enrichers.ts
5
+ const branchIdResolve = async ({ branch, apiClient, projectId }) => {
6
+ branch = branch.toString();
7
+ if (looksLikeBranchId(branch)) return branch;
8
+ const { data } = await apiClient.listProjectBranches({ projectId });
9
+ const branchData = data.branches.find((b) => b.name === branch);
10
+ if (!branchData) throw new Error(`Branch ${branch} not found.\nAvailable branches: ${data.branches.map((b) => b.name).join(", ")}`);
11
+ return branchData.id;
19
12
  };
20
13
  const getBranchIdFromProps = async (props) => {
21
- const branch = "branch" in props && typeof props.branch === "string"
22
- ? props.branch
23
- : props.id;
24
- if (branch) {
25
- return await branchIdResolve({
26
- branch,
27
- apiClient: props.apiClient,
28
- projectId: props.projectId,
29
- });
30
- }
31
- const { data } = await props.apiClient.listProjectBranches({
32
- projectId: props.projectId,
33
- });
34
- const defaultBranch = data.branches.find((b) => b.default);
35
- if (defaultBranch) {
36
- return defaultBranch.id;
37
- }
38
- throw new Error("No default branch found");
14
+ const branch = "branch" in props && typeof props.branch === "string" ? props.branch : props.id;
15
+ if (branch) return await branchIdResolve({
16
+ branch,
17
+ apiClient: props.apiClient,
18
+ projectId: props.projectId
19
+ });
20
+ const { data } = await props.apiClient.listProjectBranches({ projectId: props.projectId });
21
+ const defaultBranch = data.branches.find((b) => b.default);
22
+ if (defaultBranch) return defaultBranch.id;
23
+ throw new Error("No default branch found");
39
24
  };
40
- export const branchIdFromProps = async (props) => {
41
- props.branchId = await getBranchIdFromProps(props);
42
- return props.branchId;
25
+ const branchIdFromProps = async (props) => {
26
+ props.branchId = await getBranchIdFromProps(props);
27
+ return props.branchId;
43
28
  };
44
- export const resolveBranchRef = async (props) => {
45
- const branch = typeof props.branch === "string" ? props.branch : props.id;
46
- const { data } = await props.apiClient.listProjectBranches({
47
- projectId: props.projectId,
48
- });
49
- const branches = data.branches;
50
- if (branch) {
51
- const ref = branch.toString();
52
- const found = looksLikeBranchId(ref)
53
- ? branches.find((b) => b.id === ref)
54
- : branches.find((b) => b.name === ref);
55
- if (found) {
56
- return {
57
- branchId: found.id,
58
- branchName: found.name ?? found.id,
59
- usedDefault: false,
60
- };
61
- }
62
- // A `br-…` id absent from the listing is still usable as an id (trust it like
63
- // branchIdResolve does); only an unresolved *name* is a genuine error.
64
- if (looksLikeBranchId(ref)) {
65
- return { branchId: ref, branchName: ref, usedDefault: false };
66
- }
67
- throw new Error(`Branch ${ref} not found.\nAvailable branches: ${branches
68
- .map((b) => b.name)
69
- .join(", ")}`);
70
- }
71
- const defaultBranch = branches.find((b) => b.default);
72
- if (!defaultBranch) {
73
- throw new Error("No default branch found");
74
- }
75
- return {
76
- branchId: defaultBranch.id,
77
- branchName: defaultBranch.name ?? defaultBranch.id,
78
- usedDefault: true,
79
- };
29
+ const resolveBranchRef = async (props) => {
30
+ const branch = typeof props.branch === "string" ? props.branch : props.id;
31
+ const { data } = await props.apiClient.listProjectBranches({ projectId: props.projectId });
32
+ const branches = data.branches;
33
+ if (branch) {
34
+ const ref = branch.toString();
35
+ const found = looksLikeBranchId(ref) ? branches.find((b) => b.id === ref) : branches.find((b) => b.name === ref);
36
+ if (found) return {
37
+ branchId: found.id,
38
+ branchName: found.name ?? found.id,
39
+ usedDefault: false
40
+ };
41
+ if (looksLikeBranchId(ref)) return {
42
+ branchId: ref,
43
+ branchName: ref,
44
+ usedDefault: false
45
+ };
46
+ throw new Error(`Branch ${ref} not found.\nAvailable branches: ${branches.map((b) => b.name).join(", ")}`);
47
+ }
48
+ const defaultBranch = branches.find((b) => b.default);
49
+ if (!defaultBranch) throw new Error("No default branch found");
50
+ return {
51
+ branchId: defaultBranch.id,
52
+ branchName: defaultBranch.name ?? defaultBranch.id,
53
+ usedDefault: true
54
+ };
80
55
  };
81
- export const resolveSingleDatabase = async (props) => {
82
- const { data } = await props.apiClient.listProjectBranchDatabases(props.projectId, props.branchId);
83
- const databases = data.databases;
84
- if (props.database !== undefined) {
85
- if (!databases.find((d) => d.name === props.database)) {
86
- throw new Error(`Database not found: ${props.database}. Available databases on branch ${props.branchId}: ${databases.map((d) => d.name).join(", ")}`);
87
- }
88
- return props.database;
89
- }
90
- if (databases.length === 0) {
91
- throw new Error(`No databases found for the branch: ${props.branchId}`);
92
- }
93
- if (databases.length === 1) {
94
- return databases[0].name;
95
- }
96
- throw new Error(`Multiple databases found for the branch, please provide one with the --database option: ${databases.map((d) => d.name).join(", ")}`);
56
+ const resolveSingleDatabase = async (props) => {
57
+ const { data } = await props.apiClient.listProjectBranchDatabases(props.projectId, props.branchId);
58
+ const databases = data.databases;
59
+ if (props.database !== void 0) {
60
+ if (!databases.find((d) => d.name === props.database)) throw new Error(`Database not found: ${props.database}. Available databases on branch ${props.branchId}: ${databases.map((d) => d.name).join(", ")}`);
61
+ return props.database;
62
+ }
63
+ if (databases.length === 0) throw new Error(`No databases found for the branch: ${props.branchId}`);
64
+ if (databases.length === 1) return databases[0].name;
65
+ throw new Error(`Multiple databases found for the branch, please provide one with the --database option: ${databases.map((d) => d.name).join(", ")}`);
97
66
  };
98
- export const fillSingleProject = async (props) => {
99
- // The offline `--current-branch` probe needs no project at all and runs with no
100
- // API client (auth was skipped), so resolving a single project here would both
101
- // hit the network and dereference a null client. Skip it entirely.
102
- if (isCurrentBranchProbe(props)) {
103
- return props;
104
- }
105
- // `config init` is purely local (scaffold + npm install) and runs with no API
106
- // client, so resolving a single project here would dereference a null client.
107
- if (isConfigInit(props)) {
108
- return props;
109
- }
110
- if (props.projectId) {
111
- return { ...props, projectId: props.projectId };
112
- }
113
- // If no orgId is provided, try to auto-fill it if there's only one org
114
- let orgId = props.orgId;
115
- if (!orgId) {
116
- const { data: orgsData } = await props.apiClient.getCurrentUserOrganizations();
117
- if (orgsData.organizations.length === 1) {
118
- orgId = orgsData.organizations[0].id;
119
- }
120
- }
121
- try {
122
- const { data } = await props.apiClient.listProjects({
123
- limit: 2,
124
- org_id: orgId,
125
- });
126
- if (data.projects.length === 0) {
127
- throw new Error("No projects found");
128
- }
129
- if (data.projects.length > 1) {
130
- throw new Error(`Multiple projects found, please provide one with the --project-id option`);
131
- }
132
- return {
133
- ...props,
134
- projectId: data.projects[0].id,
135
- };
136
- }
137
- catch (error) {
138
- // If the API error is about missing org_id, provide a user-friendly message
139
- if (isNeonApiError(error) &&
140
- error.status === 400 &&
141
- messageFromBody(error.data)?.includes("org_id is required")) {
142
- throw new Error("Multiple projects found, please provide one with the --project-id option");
143
- }
144
- throw error;
145
- }
67
+ const fillSingleProject = async (props) => {
68
+ if (isCurrentBranchProbe(props)) return props;
69
+ if (isConfigInit(props)) return props;
70
+ if (props.projectId) return {
71
+ ...props,
72
+ projectId: props.projectId
73
+ };
74
+ let orgId = props.orgId;
75
+ if (!orgId) {
76
+ const { data: orgsData } = await props.apiClient.getCurrentUserOrganizations();
77
+ if (orgsData.organizations.length === 1) orgId = orgsData.organizations[0].id;
78
+ }
79
+ try {
80
+ const { data } = await props.apiClient.listProjects({
81
+ limit: 2,
82
+ org_id: orgId
83
+ });
84
+ if (data.projects.length === 0) throw new Error("No projects found");
85
+ if (data.projects.length > 1) throw new Error(`Multiple projects found, please provide one with the --project-id option`);
86
+ return {
87
+ ...props,
88
+ projectId: data.projects[0].id
89
+ };
90
+ } catch (error) {
91
+ if (isNeonApiError(error) && error.status === 400 && messageFromBody(error.data)?.includes("org_id is required")) throw new Error("Multiple projects found, please provide one with the --project-id option");
92
+ throw error;
93
+ }
146
94
  };
147
- export const fillSingleOrg = async (props) => {
148
- if (props.orgId) {
149
- return props;
150
- }
151
- const { data } = await props.apiClient.getCurrentUserOrganizations();
152
- if (data.organizations.length === 0) {
153
- throw new Error("No organizations found");
154
- }
155
- if (data.organizations.length > 1) {
156
- throw new Error(`Multiple organizations found, please provide one with the --org-id option`);
157
- }
158
- return { ...props, orgId: data.organizations[0].id };
95
+ const fillSingleOrg = async (props) => {
96
+ if (props.orgId) return props;
97
+ const { data } = await props.apiClient.getCurrentUserOrganizations();
98
+ if (data.organizations.length === 0) throw new Error("No organizations found");
99
+ if (data.organizations.length > 1) throw new Error(`Multiple organizations found, please provide one with the --org-id option`);
100
+ return {
101
+ ...props,
102
+ orgId: data.organizations[0].id
103
+ };
159
104
  };
105
+ //#endregion
106
+ export { branchIdFromProps, branchIdResolve, fillSingleOrg, fillSingleProject, resolveBranchRef, resolveSingleDatabase };
@@ -1,210 +1,151 @@
1
- import { spawn } from "node:child_process";
1
+ import { globalInstallCommand, resolveInvokingPackageManager } from "./package_manager.js";
2
2
  import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
3
  import { basename, join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { spawn } from "node:child_process";
5
6
  import which from "which";
6
- const NOT_FOUND = "esbuild not found. neon ships esbuild for most platforms; if you see " +
7
- "this, install esbuild and ensure it is on your PATH (e.g. `npm i -g " +
8
- "esbuild`), or set NEON_ESBUILD_PATH to an esbuild binary.";
9
- // Prepended to the ESM bundle. Bundled dependencies are frequently CommonJS, but an ESM
10
- // output (`--format=esm`) has no `require` / `__filename` / `__dirname` in scope — so any
11
- // bundled CJS code that calls `require(...)` would fail at load with
12
- // `Dynamic require of "x" is not supported`. Re-create those globals via `createRequire`
13
- // so CJS and ESM dependencies coexist in the single `index.mjs`.
7
+ //#region src/utils/esbuild.ts
8
+ const notFoundMessage = () => {
9
+ const install = globalInstallCommand(resolveInvokingPackageManager(), "esbuild");
10
+ const how = install ? `install esbuild and ensure it is on your PATH (e.g. \`${install.command} ${install.args.join(" ")}\`), or ` : "put an esbuild binary on your PATH, or ";
11
+ return `esbuild not found. neon ships esbuild for most platforms, so this is unexpected. ${how[0].toUpperCase()}${how.slice(1)}set NEON_ESBUILD_PATH to an esbuild binary.`;
12
+ };
14
13
  const ESM_CJS_INTEROP_BANNER = "import{createRequire as ___cr}from'module';import{fileURLToPath as ___f}from'url';import{dirname as ___d}from'path';const require=___cr(import.meta.url);const __filename=___f(import.meta.url);const __dirname=___d(__filename);";
15
14
  const defaultDeps = {
16
- // @yao-pkg/pkg defines process.pkg inside the packaged binary.
17
- isPackaged: () => process.pkg !== undefined,
18
- loadEsbuild: (name) => import(name),
15
+ isPackaged: () => process.pkg !== void 0,
16
+ loadEsbuild: (name) => import(name)
19
17
  };
20
- // Internal signal: the esbuild JS module could not be imported (exotic platform
21
- // or not installed). Tells bundleEntry to fall back to the binary; never shown
22
- // to the user.
23
- class ModuleNotAvailable extends Error {
24
- }
18
+ var ModuleNotAvailable = class extends Error {};
25
19
  const message = (err) => err instanceof Error ? err.message : String(err);
26
20
  const toFilesByBasename = (files) => {
27
- const out = {};
28
- for (const f of files)
29
- out[basename(f.path)] = f.contents;
30
- return out;
21
+ const out = {};
22
+ for (const f of files) out[basename(f.path)] = f.contents;
23
+ return out;
31
24
  };
32
25
  const bundleViaModule = async (source, loadEsbuild, externalPackages) => {
33
- // esbuild is resolved by a COMPUTED specifier, never the literal string
34
- // 'esbuild'. Both rollup (bundle step) and @yao-pkg/pkg (binary step)
35
- // statically scan for literal import()/require() calls and would otherwise
36
- // pull esbuild and its native Go binary into the bundle/snapshot — bloating
37
- // the packaged CLI and emitting "cannot bundle native binary" warnings. The
38
- // packaged binary never imports esbuild at all (the isPackaged guard sends it
39
- // to the binary path), so keeping this specifier invisible to the scanners is
40
- // what keeps esbuild out of the snapshot.
41
- // Do NOT "simplify" this back to import('esbuild').
42
- const name = ["es", "build"].join("");
43
- let esbuild;
44
- try {
45
- esbuild = await loadEsbuild(name);
46
- }
47
- catch {
48
- throw new ModuleNotAvailable();
49
- }
50
- // Mirrors the binary-path bundling flags; write:false keeps output in memory.
51
- // logLevel:'silent' suppresses esbuild's own stderr — the rejected error
52
- // still carries the diagnostic, matching the binary path's captured-stderr.
53
- const result = await esbuild
54
- .build({
55
- entryPoints: [source],
56
- bundle: true,
57
- // Emit `index.mjs` (not `out.js`): the Functions runtime imports the archive's entry
58
- // by the conventional `index.{js,mjs}` name, and `.mjs` makes Node treat the ESM
59
- // output as a module without needing a `package.json` type marker alongside it.
60
- outfile: "index.mjs",
61
- write: false,
62
- minify: true,
63
- format: "esm",
64
- platform: "node",
65
- // Bundle dependencies into the entry so the deployed archive is self-contained (the
66
- // Functions runtime has no node_modules). Node built-ins stay external on
67
- // platform:'node'. The banner re-creates require/__filename/__dirname for bundled CJS.
68
- banner: { js: ESM_CJS_INTEROP_BANNER },
69
- // Only what the policy declared unbundleable; everything else is still inlined.
70
- external: [...externalPackages],
71
- // Reveals which packages were inlined, so a deploy can report an undeclared
72
- // native dependency. Free here — esbuild is already running.
73
- metafile: true,
74
- logLevel: "silent",
75
- })
76
- .catch((err) => {
77
- throw new Error(`Failed to bundle function from ${source}. ${message(err)}`.trim());
78
- });
79
- const files = result.outputFiles ?? [];
80
- // write:false with one entry always yields index.mjs (no source map — we don't emit one);
81
- // an empty set means the API contract changed under us — fail loud rather than ship an
82
- // empty archive.
83
- if (files.length === 0) {
84
- throw new Error(`Failed to bundle function from ${source}. esbuild produced no output.`);
85
- }
86
- return {
87
- files: toFilesByBasename(files),
88
- ...(result.metafile ? { metafile: result.metafile } : {}),
89
- warnings: [],
90
- };
26
+ const name = ["es", "build"].join("");
27
+ let esbuild;
28
+ try {
29
+ esbuild = await loadEsbuild(name);
30
+ } catch {
31
+ throw new ModuleNotAvailable();
32
+ }
33
+ const result = await esbuild.build({
34
+ entryPoints: [source],
35
+ bundle: true,
36
+ outfile: "index.mjs",
37
+ write: false,
38
+ minify: true,
39
+ format: "esm",
40
+ platform: "node",
41
+ banner: { js: ESM_CJS_INTEROP_BANNER },
42
+ external: [...externalPackages],
43
+ metafile: true,
44
+ logLevel: "silent"
45
+ }).catch((err) => {
46
+ throw new Error(`Failed to bundle function from ${source}. ${message(err)}`.trim());
47
+ });
48
+ const files = result.outputFiles ?? [];
49
+ if (files.length === 0) throw new Error(`Failed to bundle function from ${source}. esbuild produced no output.`);
50
+ return {
51
+ files: toFilesByBasename(files),
52
+ ...result.metafile ? { metafile: result.metafile } : {},
53
+ warnings: []
54
+ };
91
55
  };
92
- // Find the esbuild binary at deploy time. An explicit override is authoritative
93
- // (so it fails loudly if wrong); otherwise prefer the host PATH, then a locally
94
- // installed copy.
95
56
  const resolveEsbuild = () => {
96
- const override = process.env.NEON_ESBUILD_PATH;
97
- if (override) {
98
- if (existsSync(override))
99
- return override;
100
- throw new Error(NOT_FOUND);
101
- }
102
- const onPath = which.sync("esbuild", { nothrow: true });
103
- if (onPath)
104
- return onPath;
105
- // CWD-relative (not install-relative): helps the dev checkout where esbuild is
106
- // a devDependency. In `npm i -g` and pkg installs the PATH branch above wins.
107
- const local = join(process.cwd(), "node_modules", ".bin", "esbuild");
108
- if (existsSync(local))
109
- return local;
110
- throw new Error(NOT_FOUND);
57
+ const override = process.env.NEON_ESBUILD_PATH;
58
+ if (override) {
59
+ if (existsSync(override)) return override;
60
+ throw new Error(`NEON_ESBUILD_PATH is set to ${override}, but no file exists there. Point it at an esbuild binary, or unset it to use the one neon ships.`);
61
+ }
62
+ const onPath = which.sync("esbuild", { nothrow: true });
63
+ if (onPath) return onPath;
64
+ const local = join(process.cwd(), "node_modules", ".bin", "esbuild");
65
+ if (existsSync(local)) return local;
66
+ throw new Error(notFoundMessage());
111
67
  };
112
68
  const runEsbuild = (bin, args) => new Promise((resolve, reject) => {
113
- // stderr is captured (NOT inherited): with --log-level=error a success emits
114
- // nothing, and a failure's diagnostic is read out below. Never use 'inherit'.
115
- const child = spawn(bin, args, { stdio: ["ignore", "ignore", "pipe"] });
116
- let stderr = "";
117
- child.stderr.on("data", (chunk) => {
118
- stderr += chunk.toString();
119
- });
120
- child.on("error", reject);
121
- child.on("close", (code) => {
122
- resolve({ code, stderr });
123
- });
69
+ const child = spawn(bin, args, { stdio: [
70
+ "ignore",
71
+ "ignore",
72
+ "pipe"
73
+ ] });
74
+ let stderr = "";
75
+ child.stderr.on("data", (chunk) => {
76
+ stderr += chunk.toString();
77
+ });
78
+ child.on("error", reject);
79
+ child.on("close", (code) => {
80
+ resolve({
81
+ code,
82
+ stderr
83
+ });
84
+ });
124
85
  });
125
86
  const bundleViaBinary = async (source, externalPackages) => {
126
- const bin = resolveEsbuild();
127
- const outDir = mkdtempSync(join(tmpdir(), "neon-fn-bundle-"));
128
- const outfile = join(outDir, "index.mjs");
129
- const metafilePath = join(outDir, "meta.json");
130
- try {
131
- const { code, stderr } = await runEsbuild(bin, [
132
- source,
133
- "--bundle",
134
- `--outfile=${outfile}`,
135
- "--minify",
136
- "--format=esm",
137
- "--platform=node",
138
- `--banner:js=${ESM_CJS_INTEROP_BANNER}`,
139
- // One flag per package, mirroring the module path's `external` array.
140
- ...externalPackages.map((pkg) => `--external:${pkg}`),
141
- // Written beside the output so a deploy can report an undeclared native
142
- // dependency here too, not only on the module path.
143
- `--metafile=${metafilePath}`,
144
- "--log-level=error",
145
- ]);
146
- if (code !== 0) {
147
- throw new Error(`Failed to bundle function from ${source}. ${stderr.trim()}`.trim());
148
- }
149
- // No `--sourcemap`: the Functions runtime has no source-map support, so an uploaded
150
- // `index.mjs.map` is never consumed — emitting it only inflated the archive.
151
- const metafile = readMetafile(metafilePath);
152
- return {
153
- files: { "index.mjs": new Uint8Array(readFileSync(outfile)) },
154
- ...(metafile.metafile ? { metafile: metafile.metafile } : {}),
155
- warnings: metafile.warnings,
156
- };
157
- }
158
- finally {
159
- rmSync(outDir, { recursive: true, force: true });
160
- }
87
+ const bin = resolveEsbuild();
88
+ const outDir = mkdtempSync(join(tmpdir(), "neon-fn-bundle-"));
89
+ const outfile = join(outDir, "index.mjs");
90
+ const metafilePath = join(outDir, "meta.json");
91
+ try {
92
+ const { code, stderr } = await runEsbuild(bin, [
93
+ source,
94
+ "--bundle",
95
+ `--outfile=${outfile}`,
96
+ "--minify",
97
+ "--format=esm",
98
+ "--platform=node",
99
+ `--banner:js=${ESM_CJS_INTEROP_BANNER}`,
100
+ ...externalPackages.map((pkg) => `--external:${pkg}`),
101
+ `--metafile=${metafilePath}`,
102
+ "--log-level=error"
103
+ ]);
104
+ if (code !== 0) throw new Error(`Failed to bundle function from ${source}. ${stderr.trim()}`.trim());
105
+ const metafile = readMetafile(metafilePath);
106
+ return {
107
+ files: { "index.mjs": new Uint8Array(readFileSync(outfile)) },
108
+ ...metafile.metafile ? { metafile: metafile.metafile } : {},
109
+ warnings: metafile.warnings
110
+ };
111
+ } finally {
112
+ rmSync(outDir, {
113
+ recursive: true,
114
+ force: true
115
+ });
116
+ }
161
117
  };
162
118
  /**
163
- * Read the metafile the binary path asked esbuild to write.
164
- *
165
- * We always pass `--metafile`, so an unreadable one means esbuild did not do what it was
166
- * told. That is worth saying rather than swallowing — but not worth failing a deploy over,
167
- * because the metafile only powers an advisory report. Reported and skipped.
168
- */
119
+ * Read the metafile the binary path asked esbuild to write.
120
+ *
121
+ * We always pass `--metafile`, so an unreadable one means esbuild did not do what it was
122
+ * told. That is worth saying rather than swallowing — but not worth failing a deploy over,
123
+ * because the metafile only powers an advisory report. Reported and skipped.
124
+ */
169
125
  const readMetafile = (path) => {
170
- let parsed;
171
- try {
172
- parsed = JSON.parse(readFileSync(path, "utf8"));
173
- }
174
- catch (cause) {
175
- return {
176
- warnings: [
177
- `esbuild was asked for a metafile but none could be read (${message(cause)}). ` +
178
- `The bundle is unaffected; this deploy cannot check for an undeclared ` +
179
- `native dependency.`,
180
- ],
181
- };
182
- }
183
- if (typeof parsed !== "object" || parsed === null) {
184
- return {
185
- warnings: [
186
- "esbuild wrote a metafile that is not an object. The bundle is unaffected; " +
187
- "this deploy cannot check for an undeclared native dependency.",
188
- ],
189
- };
190
- }
191
- return { metafile: parsed, warnings: [] };
126
+ let parsed;
127
+ try {
128
+ parsed = JSON.parse(readFileSync(path, "utf8"));
129
+ } catch (cause) {
130
+ return { warnings: [`esbuild was asked for a metafile but none could be read (${message(cause)}). The bundle is unaffected; this deploy cannot check for an undeclared native dependency.`] };
131
+ }
132
+ if (typeof parsed !== "object" || parsed === null) return { warnings: ["esbuild wrote a metafile that is not an object. The bundle is unaffected; this deploy cannot check for an undeclared native dependency."] };
133
+ return {
134
+ metafile: parsed,
135
+ warnings: []
136
+ };
192
137
  };
193
- // Bundle `source` into the files the Functions archive expects, keyed by
194
- // basename. npm installs bundle in-process via the esbuild module; the packaged
195
- // binary (and platforms esbuild can't run on) shell out to an esbuild binary.
196
- export const bundleEntry = async (source, options = {}) => {
197
- const isPackaged = options.isPackaged ?? defaultDeps.isPackaged;
198
- const loadEsbuild = options.loadEsbuild ?? defaultDeps.loadEsbuild;
199
- const external = options.externalPackages ?? [];
200
- if (isPackaged())
201
- return bundleViaBinary(source, external);
202
- try {
203
- return await bundleViaModule(source, loadEsbuild, external);
204
- }
205
- catch (err) {
206
- if (err instanceof ModuleNotAvailable)
207
- return bundleViaBinary(source, external);
208
- throw err;
209
- }
138
+ const bundleEntry = async (source, options = {}) => {
139
+ const isPackaged = options.isPackaged ?? defaultDeps.isPackaged;
140
+ const loadEsbuild = options.loadEsbuild ?? defaultDeps.loadEsbuild;
141
+ const external = options.externalPackages ?? [];
142
+ if (isPackaged()) return bundleViaBinary(source, external);
143
+ try {
144
+ return await bundleViaModule(source, loadEsbuild, external);
145
+ } catch (err) {
146
+ if (err instanceof ModuleNotAvailable) return bundleViaBinary(source, external);
147
+ throw err;
148
+ }
210
149
  };
150
+ //#endregion
151
+ export { bundleEntry };