netlify-cli 27.11.2 → 27.12.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 (62) hide show
  1. package/dist/commands/base-command.js +2 -2
  2. package/dist/commands/deploy/deploy.js +28 -59
  3. package/dist/commands/dev/dev.js +1 -2
  4. package/dist/commands/env/env-clone.js +1 -1
  5. package/dist/commands/env/env-set.js +1 -1
  6. package/dist/commands/env/env-unset.js +1 -1
  7. package/dist/commands/functions/functions-create.js +3 -93
  8. package/dist/commands/init/index.js +6 -1
  9. package/dist/commands/init/init.d.ts +3 -1
  10. package/dist/commands/init/init.js +22 -2
  11. package/dist/commands/serve/serve.js +1 -2
  12. package/dist/commands/sites/sites-list.js +1 -1
  13. package/dist/commands/unlink/unlink.js +1 -1
  14. package/dist/lib/edge-functions/registry.js +0 -1
  15. package/dist/lib/exec-fetcher.js +1 -1
  16. package/dist/lib/functions/form-submissions-handler.js +2 -1
  17. package/dist/lib/spinner.d.ts +2 -2
  18. package/dist/lib/spinner.js +1 -1
  19. package/dist/recipes/ai-context/context.js +2 -2
  20. package/dist/utils/deploy/deploy-site.d.ts +32 -12
  21. package/dist/utils/deploy/deploy-site.js +18 -40
  22. package/dist/utils/deploy/drop-api.d.ts +7 -1
  23. package/dist/utils/deploy/drop-api.js +3 -4
  24. package/dist/utils/deploy/file.d.ts +4 -2
  25. package/dist/utils/deploy/hash-config.d.ts +5 -6
  26. package/dist/utils/deploy/hash-config.js +1 -4
  27. package/dist/utils/deploy/hash-files.d.ts +9 -8
  28. package/dist/utils/deploy/hash-fns.d.ts +45 -10
  29. package/dist/utils/deploy/hasher-segments.d.ts +10 -6
  30. package/dist/utils/deploy/hasher-segments.js +0 -1
  31. package/dist/utils/deploy/process-files.d.ts +1 -1
  32. package/dist/utils/deploy/process-files.js +1 -0
  33. package/dist/utils/deploy/types.d.ts +17 -0
  34. package/dist/utils/deploy/types.js +2 -0
  35. package/dist/utils/deploy/upload-files.d.ts +8 -3
  36. package/dist/utils/deploy/upload-files.js +4 -3
  37. package/dist/utils/deploy/upload-source-zip.js +4 -7
  38. package/dist/utils/deploy/util.d.ts +6 -3
  39. package/dist/utils/deploy/util.js +4 -16
  40. package/dist/utils/dev.d.ts +0 -1
  41. package/dist/utils/dev.js +1 -27
  42. package/dist/utils/env/index.js +1 -3
  43. package/dist/utils/get-repo-data.js +1 -1
  44. package/dist/utils/init/agent-skills.d.ts +96 -0
  45. package/dist/utils/init/agent-skills.js +653 -0
  46. package/dist/utils/parse-raw-flags.js +1 -1
  47. package/dist/utils/proxy-server.d.ts +1 -2
  48. package/dist/utils/proxy-server.js +1 -2
  49. package/dist/utils/proxy.d.ts +1 -1
  50. package/dist/utils/proxy.js +7 -35
  51. package/dist/utils/types.d.ts +1 -1
  52. package/functions-templates/javascript/scheduled-function/package.json +1 -1
  53. package/functions-templates/typescript/database/package-lock.json +8 -8
  54. package/functions-templates/typescript/database/package.json +1 -1
  55. package/functions-templates/typescript/database-drizzle/package-lock.json +8 -8
  56. package/functions-templates/typescript/database-drizzle/package.json +1 -1
  57. package/functions-templates/typescript/hello-world/package-lock.json +15 -17
  58. package/functions-templates/typescript/hello-world/package.json +1 -1
  59. package/functions-templates/typescript/scheduled-function/package.json +1 -1
  60. package/package.json +10 -11
  61. package/dist/utils/addons/prepare.d.ts +0 -13
  62. package/dist/utils/addons/prepare.js +0 -26
@@ -1,26 +1,46 @@
1
- import BaseCommand from '../../commands/base-command.js';
2
- import { type $TSFixMe } from '../../commands/types.js';
3
- import type { DeployEvent } from './status-cb.js';
1
+ import type { NetlifyAPI } from '@netlify/api';
2
+ import type { Config as FunctionsConfig } from '@netlify/zip-it-and-ship-it';
3
+ import type BaseCommand from '../../commands/base-command.js';
4
+ import type { File } from './file.js';
5
+ import type { DeployEvent, StatusCallback } from './status-cb.js';
6
+ import type { DeployConfig } from './types.js';
4
7
  import type { DeployEnvironmentVariable } from '../env/deploy-env-vars.js';
5
8
  export type { DeployEvent };
6
- export declare const deploySite: (command: BaseCommand, api: $TSFixMe, siteId: any, dir: any, { assetType, branch, concurrentHash, concurrentUpload, config, deployId, deployTimeout, draft, environment, filter, fnDir, functionsConfig, hashAlgorithm, manifestPath, maxRetry, packagePath, serverEnabled, serverManifestPath, siteRoot, skipFunctionsCache, statusCb, syncFileLimit, tmpDir, workingDir, }: {
9
+ export interface DeploySiteOptions {
10
+ assetType?: 'file' | undefined;
11
+ branch?: string;
7
12
  concurrentHash?: number;
8
13
  concurrentUpload?: number;
14
+ /** The site configuration, uploaded as the deploy's `netlify.toml` */
15
+ config: DeployConfig;
16
+ deployId: string;
9
17
  deployTimeout?: number;
10
18
  draft?: boolean;
11
19
  environment?: DeployEnvironmentVariable[];
20
+ filter: (filename: string) => boolean;
21
+ fnDir?: string[];
22
+ functionsConfig?: FunctionsConfig | undefined;
23
+ hashAlgorithm?: string;
24
+ manifestPath?: string | undefined;
12
25
  maxRetry?: number;
13
- packagePath?: string;
26
+ packagePath?: string | undefined;
14
27
  serverEnabled?: boolean;
15
- serverManifestPath?: string;
16
- statusCb?: (status: DeployEvent) => void;
28
+ serverManifestPath?: string | undefined;
29
+ siteRoot?: string | undefined;
30
+ skipFunctionsCache?: boolean | undefined;
31
+ statusCb?: StatusCallback;
17
32
  syncFileLimit?: number;
18
33
  tmpDir?: string;
19
- fnDir?: string[];
20
34
  workingDir: string;
21
- }) => Promise<{
22
- deployId: any;
23
- deploy: any;
24
- uploadList: any[];
35
+ }
36
+ export declare const deploySite: (command: BaseCommand, api: NetlifyAPI, siteId: string, dir: string, { assetType, branch, concurrentHash, concurrentUpload, config, deployId, deployTimeout, draft, environment, filter, fnDir, functionsConfig, hashAlgorithm, manifestPath, maxRetry, packagePath, serverEnabled, serverManifestPath, siteRoot, skipFunctionsCache, statusCb, syncFileLimit, tmpDir, workingDir, }: DeploySiteOptions) => Promise<{
37
+ deployId: string;
38
+ deploy: import("./util.js").ReadyDeploy;
39
+ uploadList: (import("./upload-files.js").EdgeFunctionUploadFile | import("./upload-files.js").ServerUploadFile | File | (import("./upload-files.js").FunctionUploadFile & {
40
+ hash: string;
41
+ relname: string;
42
+ }) | (import("./upload-files.js").InlineUploadFile & {
43
+ hash: string;
44
+ }))[];
25
45
  }>;
26
46
  //# sourceMappingURL=deploy-site.d.ts.map
@@ -18,31 +18,7 @@ const buildStatsString = (possibleParts) => {
18
18
  }
19
19
  return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]}`;
20
20
  };
21
- export const deploySite = async (command, api,
22
- // @ts-expect-error TS(7006) FIXME: Parameter 'siteId' implicitly has an 'any' type.
23
- siteId,
24
- // @ts-expect-error TS(7006) FIXME: Parameter 'dir' implicitly has an 'any' type.
25
- dir, {
26
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
27
- assetType,
28
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
29
- branch, concurrentHash = DEFAULT_CONCURRENT_HASH, concurrentUpload = DEFAULT_CONCURRENT_UPLOAD,
30
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
31
- config,
32
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
33
- deployId, deployTimeout = DEFAULT_DEPLOY_TIMEOUT, draft = false, environment,
34
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
35
- filter, fnDir = [],
36
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
37
- functionsConfig,
38
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
39
- hashAlgorithm,
40
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
41
- manifestPath, maxRetry = DEFAULT_MAX_RETRY, packagePath, serverEnabled, serverManifestPath,
42
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
43
- siteRoot,
44
- // @ts-expect-error TS(2525) FIXME: Initializer provides no value for this binding ele... Remove this comment to see the full error message
45
- skipFunctionsCache, statusCb = () => {
21
+ export const deploySite = async (command, api, siteId, dir, { assetType, branch, concurrentHash = DEFAULT_CONCURRENT_HASH, concurrentUpload = DEFAULT_CONCURRENT_UPLOAD, config, deployId, deployTimeout = DEFAULT_DEPLOY_TIMEOUT, draft = false, environment, filter, fnDir = [], functionsConfig, hashAlgorithm, manifestPath, maxRetry = DEFAULT_MAX_RETRY, packagePath, serverEnabled, serverManifestPath, siteRoot, skipFunctionsCache, statusCb = () => {
46
22
  /* default to noop */
47
23
  }, syncFileLimit = DEFAULT_SYNC_LIMIT, tmpDir = temporaryDirectory(), workingDir, }) => {
48
24
  statusCb({
@@ -57,7 +33,7 @@ skipFunctionsCache, statusCb = () => {
57
33
  hashFiles({
58
34
  assetType,
59
35
  concurrentHash,
60
- directories: [dir, edgeFunctionsDistPath, deployConfigPath, dbMigrationsDistPath].filter(Boolean),
36
+ directories: [dir, edgeFunctionsDistPath, deployConfigPath, dbMigrationsDistPath].filter((d) => Boolean(d)),
61
37
  filter,
62
38
  hashAlgorithm,
63
39
  normalizer: deployFileNormalizer.bind(null, workingDir),
@@ -99,9 +75,7 @@ skipFunctionsCache, statusCb = () => {
99
75
  throw new Error('Nothing to deploy');
100
76
  }
101
77
  if (functionsWithNativeModules.length !== 0) {
102
- const functionsWithNativeModulesMessage = functionsWithNativeModules
103
- .map(({ name }) => `- ${name}`)
104
- .join('\n');
78
+ const functionsWithNativeModulesMessage = functionsWithNativeModules.map(({ name }) => `- ${name}`).join('\n');
105
79
  warn(`Modules with native dependencies\n
106
80
  ${functionsWithNativeModulesMessage}
107
81
 
@@ -120,8 +94,7 @@ For more information, visit https://ntl.fyi/cli-native-modules.`);
120
94
  });
121
95
  const packageFrameworks = command.project.frameworks.get(command.workspacePackage ?? '');
122
96
  const primaryFramework = packageFrameworks?.[0];
123
- // @ts-expect-error TS(2349) This expression is not callable
124
- const cleanedParams = cleanDeep({
97
+ const params = {
125
98
  siteId,
126
99
  deploy_id: deployId,
127
100
  body: {
@@ -138,21 +111,27 @@ For more information, visit https://ntl.fyi/cli-native-modules.`);
138
111
  framework_version: primaryFramework?.detected.package?.version?.toString() ?? 'unknown',
139
112
  build_version: getNetlifyBuildVersion(),
140
113
  },
141
- });
114
+ };
115
+ const cleanedParams =
116
+ // @ts-expect-error FIXME(clean-deep): typings declare an ES `export default` but the package is CommonJS
117
+ cleanDeep(params);
142
118
  // cleanDeep deeply strips keys with empty strings, but empty strings are valid environment
143
119
  // variable values--a user can use an empty string to e.g. unset a variable only for a deploy.
144
120
  // This would result in payloads with a missing `value` key, which the API would reject.
145
121
  const deployParams = environment?.length
146
122
  ? { ...cleanedParams, body: { ...cleanedParams.body, environment } }
147
123
  : cleanedParams;
148
- let deploy = await api.updateSiteDeploy(deployParams);
124
+ // FIXME(@netlify/api): `id` and `required` are optional on the updated deploy
125
+ let deploy = (await api.updateSiteDeploy(
126
+ // @ts-expect-error FIXME(@netlify/api): `functions_config` rejects zip-it-and-ship-it's `BuildData`, route `methods` and `traffic_rules` strings
127
+ deployParams));
149
128
  if (deployParams.body.async)
150
- deploy = await waitForDiff(api, deploy.id, siteId, deployTimeout);
129
+ deploy = (await waitForDiff(api, deploy.id, siteId, deployTimeout));
151
130
  const { required: requiredFiles, required_functions: requiredFns, required_edge_functions: requiredEdgeFns, required_server: requiredServer, } = deploy;
152
131
  const newStats = buildStatsString([
153
132
  requiredFiles.length > 0 && pluralize(requiredFiles.length, 'file'),
154
- (requiredFns?.length ?? 0) > 0 && pluralize(requiredFns.length, 'function'),
155
- (requiredEdgeFns?.length ?? 0) > 0 && pluralize(requiredEdgeFns.length, 'edge function'),
133
+ requiredFns != null && requiredFns.length > 0 && pluralize(requiredFns.length, 'function'),
134
+ requiredEdgeFns != null && requiredEdgeFns.length > 0 && pluralize(requiredEdgeFns.length, 'edge function'),
156
135
  (requiredServer?.length ?? 0) > 0 && 'a server',
157
136
  ]);
158
137
  statusCb({
@@ -171,18 +150,17 @@ For more information, visit https://ntl.fyi/cli-native-modules.`);
171
150
  msg: 'Waiting for deploy to go live...',
172
151
  phase: 'start',
173
152
  });
174
- deploy = await waitForDeploy(api, deployId, siteId, deployTimeout);
153
+ const readyDeploy = await waitForDeploy(api, deployId, siteId, deployTimeout);
175
154
  statusCb({
176
155
  type: 'wait-for-deploy',
177
156
  msg: draft ? 'Draft deploy is live!' : 'Deploy is live!',
178
157
  phase: 'stop',
179
158
  });
180
159
  await rm(tmpDir, { force: true, recursive: true });
181
- const deployManifest = {
160
+ return {
182
161
  deployId,
183
- deploy,
162
+ deploy: readyDeploy,
184
163
  uploadList,
185
164
  };
186
- return deployManifest;
187
165
  };
188
166
  //# sourceMappingURL=deploy-site.js.map
@@ -18,7 +18,13 @@ export interface DropApiError extends Error {
18
18
  export declare const getDropToken: ({ apiBase, userAgent }: DropApiOptions) => Promise<string>;
19
19
  export declare const createDropDeploy: ({ apiBase, userAgent }: DropApiOptions, files: Record<string, string>, token: string, createdVia?: string) => Promise<DropDeployInfo>;
20
20
  export declare const uploadDropFile: ({ apiBase, userAgent }: DropApiOptions, deployId: string, filePath: string, body: fs.ReadStream | Buffer, token: string) => Promise<void>;
21
- export declare const waitForDropDeploy: ({ apiBase, userAgent }: DropApiOptions, siteId: string, deployId: string, timeout?: number) => Promise<Record<string, unknown>>;
21
+ interface DropSiteDeploy {
22
+ state?: string;
23
+ error_message?: string;
24
+ ssl_url?: string;
25
+ url?: string;
26
+ }
27
+ export declare const waitForDropDeploy: ({ apiBase, userAgent }: DropApiOptions, siteId: string, deployId: string, timeout?: number) => Promise<DropSiteDeploy>;
22
28
  export declare const claimDropSite: ({ apiBase, userAgent }: DropApiOptions, siteId: string, dropToken: string, authToken: string) => Promise<void>;
23
29
  export interface UploadListItem {
24
30
  normalizedPath: string;
@@ -44,8 +44,6 @@ export const createDropDeploy = async ({ apiBase, userAgent }, files, token, cre
44
44
  };
45
45
  // TODO: Migrate to @netlify/api when Drop endpoints are in the OpenAPI spec.
46
46
  export const uploadDropFile = async ({ apiBase, userAgent }, deployId, filePath, body, token) => {
47
- // Node.js fetch needs `duplex: 'half'` for streaming bodies which isn't in standard RequestInit
48
- /* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */
49
47
  const normalizedFilePath = filePath.startsWith('/') ? filePath : `/${filePath}`;
50
48
  const response = await fetch(`${apiBase}/deploys/${deployId}/files${encodeURI(normalizedFilePath)}`, {
51
49
  method: 'PUT',
@@ -53,10 +51,10 @@ export const uploadDropFile = async ({ apiBase, userAgent }, deployId, filePath,
53
51
  'Content-Type': 'application/octet-stream',
54
52
  Authorization: `Bearer ${token}`,
55
53
  }),
56
- body: body,
54
+ body,
55
+ // Node.js fetch requires this for streaming bodies
57
56
  duplex: 'half',
58
57
  });
59
- /* eslint-enable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */
60
58
  if (!response.ok) {
61
59
  const error = new Error(`Failed to upload file ${filePath}: ${String(response.status)} ${response.statusText}`);
62
60
  error.status = response.status;
@@ -79,6 +77,7 @@ export const waitForDropDeploy = async ({ apiBase, userAgent }, siteId, deployId
79
77
  return true;
80
78
  }
81
79
  if (data.state === 'error') {
80
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- an empty error message falls back to the generic one
82
81
  throw new Error(data.error_message || `Deploy ${deployId} had an error`);
83
82
  }
84
83
  return false;
@@ -1,8 +1,10 @@
1
1
  import walker from 'folder-walker';
2
2
  export type OriginalFile = walker.Entry;
3
- export type File = walker.Entry & {
3
+ export type HashedFile = OriginalFile & {
4
4
  hash: string;
5
- assetType: string;
5
+ };
6
+ export type File = HashedFile & {
7
+ assetType: 'file';
6
8
  normalizedPath: string;
7
9
  };
8
10
  //# sourceMappingURL=file.d.ts.map
@@ -1,10 +1,9 @@
1
+ import type { DeployConfig } from './types.js';
2
+ import type { InlineUploadFile } from './upload-files.js';
1
3
  export declare const hashConfig: ({ config }: {
2
- config: any;
3
- }) => {
4
- assetType: string;
5
- body: string;
4
+ config: DeployConfig | undefined;
5
+ }) => InlineUploadFile & {
6
6
  hash: string;
7
- normalizedPath: string;
8
7
  };
9
- export declare const serializeToml: (object: any) => string;
8
+ export declare const serializeToml: (object: DeployConfig) => string;
10
9
  //# sourceMappingURL=hash-config.d.ts.map
@@ -1,6 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import tomlify from 'tomlify-j0.4';
3
- // @ts-expect-error TS(7031) FIXME: Binding element 'config' implicitly has an 'any' t... Remove this comment to see the full error message
4
3
  export const hashConfig = ({ config }) => {
5
4
  if (!config)
6
5
  throw new Error('Missing config option');
@@ -13,14 +12,12 @@ export const hashConfig = ({ config }) => {
13
12
  normalizedPath: 'netlify.toml',
14
13
  };
15
14
  };
16
- // @ts-expect-error TS(7006) FIXME: Parameter 'object' implicitly has an 'any' type.
17
15
  export const serializeToml = function (object) {
18
16
  return tomlify.toToml(object, { space: 2, replace: replaceTomlValue });
19
17
  };
20
18
  // `tomlify-j0.4` serializes integers as floats, e.g. `200.0`.
21
19
  // This is a problem with `redirects[*].status`.
22
- // @ts-expect-error TS(7006) FIXME: Parameter 'key' implicitly has an 'any' type.
23
- const replaceTomlValue = function (key, value) {
20
+ const replaceTomlValue = function (_key, value) {
24
21
  return Number.isInteger(value) ? String(value) : false;
25
22
  };
26
23
  //# sourceMappingURL=hash-config.js.map
@@ -1,15 +1,16 @@
1
- import { $TSFixMe } from '../../commands/types.js';
1
+ import type { File } from './file.js';
2
+ import type { StatusCallback } from './status-cb.js';
2
3
  declare const hashFiles: ({ assetType, concurrentHash, directories, filter, hashAlgorithm, normalizer, statusCb, }: {
3
- assetType?: string | undefined;
4
- concurrentHash: $TSFixMe;
5
- directories: $TSFixMe;
6
- filter: $TSFixMe;
4
+ assetType?: 'file' | undefined;
5
+ concurrentHash: number;
6
+ directories: string[];
7
+ filter: ((filename: string) => boolean) | undefined;
7
8
  hashAlgorithm?: string | undefined;
8
- normalizer?: $TSFixMe;
9
- statusCb: $TSFixMe;
9
+ normalizer?: (file: File) => File;
10
+ statusCb: StatusCallback;
10
11
  }) => Promise<{
11
12
  files: Record<string, string>;
12
- filesShaMap: Record<string, $TSFixMe[]>;
13
+ filesShaMap: Record<string, File[]>;
13
14
  }>;
14
15
  export default hashFiles;
15
16
  //# sourceMappingURL=hash-files.d.ts.map
@@ -1,9 +1,44 @@
1
- import BaseCommand from '../../commands/base-command.js';
2
- import { $TSFixMe } from '../../commands/types.js';
3
- import type { ServerUploadFile } from './upload-files.js';
1
+ import { type Config as FunctionsConfig, type FunctionResult, type TrafficRules } from '@netlify/zip-it-and-ship-it';
2
+ import type BaseCommand from '../../commands/base-command.js';
3
+ import type { StatusCallback } from './status-cb.js';
4
+ import type { FunctionUploadFile, ServerUploadFile } from './upload-files.js';
5
+ type HashedFunctionFile = FunctionUploadFile & {
6
+ hash: string;
7
+ relname: string;
8
+ };
9
+ declare const trafficRulesConfig: (trafficRules?: TrafficRules) => {
10
+ action: {
11
+ type: string;
12
+ config: {
13
+ rate_limit_config: {
14
+ algorithm: string;
15
+ window_size: number;
16
+ window_limit: number;
17
+ };
18
+ aggregate: {
19
+ keys: {
20
+ type: string;
21
+ }[];
22
+ };
23
+ to: string | undefined;
24
+ };
25
+ };
26
+ } | undefined;
27
+ interface FunctionConfigPayload {
28
+ display_name: FunctionResult['displayName'];
29
+ excluded_routes: FunctionResult['excludedRoutes'];
30
+ generator: FunctionResult['generator'];
31
+ memory: FunctionResult['memory'];
32
+ region: FunctionResult['region'];
33
+ routes: FunctionResult['routes'];
34
+ build_data: FunctionResult['buildData'];
35
+ priority: FunctionResult['priority'];
36
+ traffic_rules: ReturnType<typeof trafficRulesConfig>;
37
+ vcpu: FunctionResult['vcpu'];
38
+ }
4
39
  declare const hashFns: (command: BaseCommand, directories: string[], { concurrentHash, functionsConfig, hashAlgorithm, manifestPath, packagePath, rootDir, serverEnabled, serverManifestPath, skipFunctionsCache, statusCb, tmpDir, }: {
5
40
  concurrentHash?: number;
6
- functionsConfig?: $TSFixMe;
41
+ functionsConfig?: FunctionsConfig | undefined;
7
42
  hashAlgorithm?: string | undefined;
8
43
  manifestPath?: string | undefined;
9
44
  packagePath?: string | undefined;
@@ -11,18 +46,18 @@ declare const hashFns: (command: BaseCommand, directories: string[], { concurren
11
46
  serverEnabled?: boolean | undefined;
12
47
  serverManifestPath?: string | undefined;
13
48
  skipFunctionsCache?: boolean | undefined;
14
- statusCb: $TSFixMe;
15
- tmpDir: $TSFixMe;
49
+ statusCb: StatusCallback;
50
+ tmpDir?: string | undefined;
16
51
  }) => Promise<{
17
52
  functionSchedules?: {
18
53
  name: string;
19
54
  cron: string;
20
55
  }[] | undefined;
21
56
  functions: Record<string, string>;
22
- functionsWithNativeModules: $TSFixMe[];
23
- shaMap?: Record<string, $TSFixMe> | undefined;
24
- fnShaMap?: Record<string, $TSFixMe[]> | undefined;
25
- fnConfig?: Record<string, $TSFixMe> | undefined;
57
+ functionsWithNativeModules: FunctionResult[];
58
+ shaMap?: Record<string, never> | undefined;
59
+ fnShaMap?: Record<string, HashedFunctionFile[]> | undefined;
60
+ fnConfig?: Record<string, FunctionConfigPayload> | undefined;
26
61
  server?: {
27
62
  sha: string;
28
63
  region?: string;
@@ -1,15 +1,19 @@
1
1
  import { Transform, Writable } from 'node:stream';
2
- import type { File, OriginalFile } from './file.js';
2
+ import type { File } from './file.js';
3
3
  import type { StatusCallback } from './status-cb.js';
4
4
  export declare const hasherCtor: ({ concurrentHash, hashAlgorithm }: {
5
- concurrentHash: any;
6
- hashAlgorithm: any;
5
+ concurrentHash?: number;
6
+ hashAlgorithm: string;
7
7
  }) => Transform;
8
8
  export declare const fileNormalizerCtor: ({ assetType, normalizer: normalizeFunction, }: {
9
- assetType: string;
10
- normalizer?: (file: OriginalFile) => File;
9
+ assetType: 'file';
10
+ normalizer?: (file: File) => File;
11
11
  }) => Transform;
12
- export declare const manifestCollectorCtor: (filesObj: Record<string, unknown>, shaMap: Record<string, unknown[]>, { statusCb }: {
12
+ export declare const manifestCollectorCtor: <T extends {
13
+ hash: string;
14
+ normalizedPath: string;
15
+ relname: string;
16
+ }>(filesObj: Record<string, string>, shaMap: Record<string, T[]>, { statusCb }: {
13
17
  statusCb: StatusCallback;
14
18
  }) => Writable;
15
19
  export declare const fileFilterCtor: () => Transform;
@@ -11,7 +11,6 @@ const hashFile = async (filePath, algorithm) => {
11
11
  };
12
12
  // a parallel transform stream segment ctor that hashes fileObj's created by folder-walker
13
13
  // TODO: use promises instead of callbacks
14
- // @ts-expect-error TS(7031) FIXME: Binding element 'concurrentHash' implicitly has an... Remove this comment to see the full error message
15
14
  export const hasherCtor = ({ concurrentHash, hashAlgorithm }) => {
16
15
  if (!concurrentHash)
17
16
  throw new Error('Missing required opts');
@@ -7,7 +7,7 @@ export declare const deployFileNormalizer: (workingDir: string, file: File) => {
7
7
  stat: import("fs").Stats;
8
8
  type: "file" | "directory";
9
9
  hash: string;
10
- assetType: string;
10
+ assetType: 'file';
11
11
  normalizedPath: string;
12
12
  };
13
13
  export declare const getDeployConfigPathIfExists: (workingDir: string) => Promise<string | undefined>;
@@ -39,6 +39,7 @@ const getDirectoryIfExists = async (directoryPath) => {
39
39
  catch {
40
40
  // no-op
41
41
  }
42
+ return undefined;
42
43
  };
43
44
  export const isEdgeFunctionFile = (filePath) => filePath.startsWith(`${PUBLIC_URL_PATH}/`);
44
45
  //# sourceMappingURL=process-files.js.map
@@ -0,0 +1,17 @@
1
+ import type { NetlifyConfig } from '@netlify/build';
2
+ import type { MinimalHeader } from '@netlify/headers-parser';
3
+ /**
4
+ * The parts of the resolved configuration a deploy reads and uploads. Satisfied both by the CLI's cached config and
5
+ * by the `NetlifyConfig` that `@netlify/build` hands to the deploy handler.
6
+ */
7
+ export interface DeployConfig {
8
+ build: {
9
+ base: string;
10
+ publish?: string;
11
+ };
12
+ functions?: NetlifyConfig['functions'];
13
+ functionsDirectory?: string;
14
+ headers?: NetlifyConfig['headers'] | MinimalHeader[];
15
+ redirects?: unknown[];
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -1,15 +1,20 @@
1
- import fs from 'fs';
2
1
  import type { NetlifyAPI } from '@netlify/api';
3
2
  import type { StatusCallback } from './status-cb.js';
4
3
  export type UploadApi = Pick<NetlifyAPI, 'uploadDeployFile' | 'uploadDeployFunction' | 'uploadDeployEdgeFunction' | 'uploadDeployServer'>;
5
4
  interface UploadFileBase {
6
5
  filepath: string;
7
6
  normalizedPath: string;
8
- body?: fs.ReadStream;
7
+ body?: undefined;
9
8
  }
10
9
  export interface StaticUploadFile extends UploadFileBase {
11
10
  assetType: 'file';
12
11
  }
12
+ export interface InlineUploadFile {
13
+ assetType: 'file';
14
+ body: string;
15
+ filepath?: undefined;
16
+ normalizedPath: string;
17
+ }
13
18
  export interface FunctionUploadFile extends UploadFileBase {
14
19
  assetType: 'function';
15
20
  runtime?: string;
@@ -24,7 +29,7 @@ export interface ServerUploadFile extends UploadFileBase {
24
29
  assetType: 'server';
25
30
  hash: string;
26
31
  }
27
- export type UploadFile = StaticUploadFile | FunctionUploadFile | EdgeFunctionUploadFile | ServerUploadFile;
32
+ export type UploadFile = StaticUploadFile | InlineUploadFile | FunctionUploadFile | EdgeFunctionUploadFile | ServerUploadFile;
28
33
  interface UploadFilesOptions {
29
34
  concurrentUpload: number;
30
35
  maxRetry: number;
@@ -23,7 +23,8 @@ const uploadFiles = async (api, deployId, uploadList, { concurrentUpload, maxRet
23
23
  });
24
24
  const uploadFile = async (fileObj, index) => {
25
25
  const { body, filepath, normalizedPath } = fileObj;
26
- const readStreamCtor = () => body ?? fs.createReadStream(filepath);
26
+ // FIXME(@netlify/api): octet-stream `body` is typed as `ReadStream` only, but an inline string body works too
27
+ const readStreamCtor = () => (body ?? fs.createReadStream(filepath));
27
28
  statusCb({
28
29
  type: 'upload',
29
30
  msg: `(${index}/${uploadList.length}) Uploading ${normalizedPath}...`,
@@ -131,12 +132,12 @@ const retryUpload = (uploadFn, maxRetry) => new Promise((resolve, reject) => {
131
132
  // Do something when backoff starts, e.g. show to the
132
133
  // user the delay before next reconnection attempt.
133
134
  });
134
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
135
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises -- FIXME: the listener's promise is discarded
135
136
  fibonacciBackoff.on('ready', tryUpload);
136
137
  fibonacciBackoff.on('fail', () => {
137
138
  reject(lastError);
138
139
  });
139
- tryUpload();
140
+ void tryUpload();
140
141
  });
141
142
  export default uploadFiles;
142
143
  //# sourceMappingURL=upload-files.js.map
@@ -27,6 +27,7 @@ const DEFAULT_IGNORE_PATTERNS = [
27
27
  '.tmp*',
28
28
  '.temp*',
29
29
  ];
30
+ const isExecaError = (error) => error instanceof Error && 'command' in error;
30
31
  const createSourceZip = async ({ sourceDir, filename, statusCb, }) => {
31
32
  // Check for Windows - this feature is not supported on Windows
32
33
  if (platform() === 'win32') {
@@ -54,13 +55,9 @@ const createSourceZip = async ({ sourceDir, filename, statusCb, }) => {
54
55
  stdio: ['ignore', 'pipe', 'pipe'],
55
56
  });
56
57
  }
57
- catch (_baseErr) {
58
- let message = 'zip command failed';
59
- if (_baseErr instanceof Error && 'command' in _baseErr) {
60
- const baseErr = _baseErr;
61
- message = `${baseErr.shortMessage}\n\n${baseErr.all ?? ''}`;
62
- }
63
- throw new Error(message, { cause: _baseErr });
58
+ catch (error) {
59
+ const message = isExecaError(error) ? `${error.shortMessage}\n\n${error.all ?? ''}` : 'zip command failed';
60
+ throw new Error(message, { cause: error });
64
61
  }
65
62
  return zipPath;
66
63
  };
@@ -1,6 +1,9 @@
1
+ import type { NetlifyAPI } from '@netlify/api';
1
2
  export declare const pluralize: (amount: number, noun: string) => string;
3
+ export type Deploy = Awaited<ReturnType<NetlifyAPI['getSiteDeploy']>>;
4
+ export type ReadyDeploy = Deploy & Required<Pick<Deploy, 'id' | 'site_id' | 'name' | 'admin_url' | 'url' | 'ssl_url' | 'deploy_url' | 'deploy_ssl_url'>>;
2
5
  export declare const normalizePath: (relname: string) => string;
3
- export declare const waitForDiff: (api: any, deployId: any, siteId: any, timeout: any) => Promise<undefined>;
4
- export declare const waitForDeploy: (api: any, deployId: any, siteId: any, timeout: any) => Promise<undefined>;
5
- export declare const getUploadList: (required: any, shaMap: any) => any;
6
+ export declare const waitForDiff: (api: Pick<NetlifyAPI, 'getSiteDeploy'>, deployId: string, siteId: string, timeout: number) => Promise<Deploy>;
7
+ export declare const waitForDeploy: (api: Pick<NetlifyAPI, 'getSiteDeploy'>, deployId: string, siteId: string, timeout: number) => Promise<ReadyDeploy>;
8
+ export declare const getUploadList: <T>(required: string[] | undefined, shaMap: Record<string, T[]> | undefined) => T[];
6
9
  //# sourceMappingURL=util.d.ts.map
@@ -10,17 +10,13 @@ export const normalizePath = (relname) => {
10
10
  return relname.split(sep).join('/');
11
11
  };
12
12
  // poll an async deployId until its done diffing
13
- // @ts-expect-error TS(7006) FIXME: Parameter 'api' implicitly has an 'any' type.
14
13
  export const waitForDiff = async (api, deployId, siteId, timeout) => {
15
- // capture ready deploy during poll
16
- let deploy;
17
14
  const loadDeploy = async () => {
18
15
  const siteDeploy = await api.getSiteDeploy({ siteId, deployId });
19
16
  switch (siteDeploy.state) {
20
17
  // https://github.com/netlify/bitballoon/blob/master/app/models/deploy.rb#L21-L33
21
18
  case 'error': {
22
19
  const deployError = new Error(siteDeploy.error_message || `Deploy ${deployId} had an error`);
23
- // @ts-expect-error TS(2339) FIXME: Property 'deploy' does not exist on type 'Error'.
24
20
  deployError.deploy = siteDeploy;
25
21
  throw deployError;
26
22
  }
@@ -28,8 +24,7 @@ export const waitForDiff = async (api, deployId, siteId, timeout) => {
28
24
  case 'uploading':
29
25
  case 'uploaded':
30
26
  case 'ready': {
31
- deploy = siteDeploy;
32
- return true;
27
+ return pWaitFor.resolveWith(siteDeploy);
33
28
  }
34
29
  case 'preparing':
35
30
  default: {
@@ -37,7 +32,7 @@ export const waitForDiff = async (api, deployId, siteId, timeout) => {
37
32
  }
38
33
  }
39
34
  };
40
- await pWaitFor(loadDeploy, {
35
+ const deploy = await pWaitFor(loadDeploy, {
41
36
  interval: DEPLOY_POLL,
42
37
  timeout: {
43
38
  milliseconds: timeout,
@@ -47,23 +42,18 @@ export const waitForDiff = async (api, deployId, siteId, timeout) => {
47
42
  return deploy;
48
43
  };
49
44
  // Poll a deployId until its ready
50
- // @ts-expect-error TS(7006) FIXME: Parameter 'api' implicitly has an 'any' type.
51
45
  export const waitForDeploy = async (api, deployId, siteId, timeout) => {
52
- // capture ready deploy during poll
53
- let deploy;
54
46
  const loadDeploy = async () => {
55
47
  const siteDeploy = await api.getSiteDeploy({ siteId, deployId });
56
48
  switch (siteDeploy.state) {
57
49
  // https://github.com/netlify/bitballoon/blob/master/app/models/deploy.rb#L21-L33
58
50
  case 'error': {
59
51
  const deployError = new Error(siteDeploy.error_message || `Deploy ${deployId} had an error`);
60
- // @ts-expect-error TS(2339) FIXME: Property 'deploy' does not exist on type 'Error'.
61
52
  deployError.deploy = siteDeploy;
62
53
  throw deployError;
63
54
  }
64
55
  case 'ready': {
65
- deploy = siteDeploy;
66
- return true;
56
+ return pWaitFor.resolveWith(siteDeploy);
67
57
  }
68
58
  case 'preparing':
69
59
  case 'prepared':
@@ -74,7 +64,7 @@ export const waitForDeploy = async (api, deployId, siteId, timeout) => {
74
64
  }
75
65
  }
76
66
  };
77
- await pWaitFor(loadDeploy, {
67
+ const deploy = await pWaitFor(loadDeploy, {
78
68
  interval: DEPLOY_POLL,
79
69
  timeout: {
80
70
  milliseconds: timeout,
@@ -84,11 +74,9 @@ export const waitForDeploy = async (api, deployId, siteId, timeout) => {
84
74
  return deploy;
85
75
  };
86
76
  // Transform the fileShaMap and fnShaMap into a generic shaMap that file-uploader.js can use
87
- // @ts-expect-error TS(7006) FIXME: Parameter 'required' implicitly has an 'any' type.
88
77
  export const getUploadList = (required, shaMap) => {
89
78
  if (!required || !shaMap)
90
79
  return [];
91
- // @ts-expect-error TS(7006) FIXME: Parameter 'sha' implicitly has an 'any' type.
92
80
  return required.flatMap((sha) => shaMap[sha]);
93
81
  };
94
82
  //# sourceMappingURL=util.js.map