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.
- package/dist/commands/base-command.js +2 -2
- package/dist/commands/deploy/deploy.js +28 -59
- package/dist/commands/dev/dev.js +1 -2
- package/dist/commands/env/env-clone.js +1 -1
- package/dist/commands/env/env-set.js +1 -1
- package/dist/commands/env/env-unset.js +1 -1
- package/dist/commands/functions/functions-create.js +3 -93
- package/dist/commands/init/index.js +6 -1
- package/dist/commands/init/init.d.ts +3 -1
- package/dist/commands/init/init.js +22 -2
- package/dist/commands/serve/serve.js +1 -2
- package/dist/commands/sites/sites-list.js +1 -1
- package/dist/commands/unlink/unlink.js +1 -1
- package/dist/lib/edge-functions/registry.js +0 -1
- package/dist/lib/exec-fetcher.js +1 -1
- package/dist/lib/functions/form-submissions-handler.js +2 -1
- package/dist/lib/spinner.d.ts +2 -2
- package/dist/lib/spinner.js +1 -1
- package/dist/recipes/ai-context/context.js +2 -2
- package/dist/utils/deploy/deploy-site.d.ts +32 -12
- package/dist/utils/deploy/deploy-site.js +18 -40
- package/dist/utils/deploy/drop-api.d.ts +7 -1
- package/dist/utils/deploy/drop-api.js +3 -4
- package/dist/utils/deploy/file.d.ts +4 -2
- package/dist/utils/deploy/hash-config.d.ts +5 -6
- package/dist/utils/deploy/hash-config.js +1 -4
- package/dist/utils/deploy/hash-files.d.ts +9 -8
- package/dist/utils/deploy/hash-fns.d.ts +45 -10
- package/dist/utils/deploy/hasher-segments.d.ts +10 -6
- package/dist/utils/deploy/hasher-segments.js +0 -1
- package/dist/utils/deploy/process-files.d.ts +1 -1
- package/dist/utils/deploy/process-files.js +1 -0
- package/dist/utils/deploy/types.d.ts +17 -0
- package/dist/utils/deploy/types.js +2 -0
- package/dist/utils/deploy/upload-files.d.ts +8 -3
- package/dist/utils/deploy/upload-files.js +4 -3
- package/dist/utils/deploy/upload-source-zip.js +4 -7
- package/dist/utils/deploy/util.d.ts +6 -3
- package/dist/utils/deploy/util.js +4 -16
- package/dist/utils/dev.d.ts +0 -1
- package/dist/utils/dev.js +1 -27
- package/dist/utils/env/index.js +1 -3
- package/dist/utils/get-repo-data.js +1 -1
- package/dist/utils/init/agent-skills.d.ts +96 -0
- package/dist/utils/init/agent-skills.js +653 -0
- package/dist/utils/parse-raw-flags.js +1 -1
- package/dist/utils/proxy-server.d.ts +1 -2
- package/dist/utils/proxy-server.js +1 -2
- package/dist/utils/proxy.d.ts +1 -1
- package/dist/utils/proxy.js +7 -35
- package/dist/utils/types.d.ts +1 -1
- package/functions-templates/javascript/scheduled-function/package.json +1 -1
- package/functions-templates/typescript/database/package-lock.json +8 -8
- package/functions-templates/typescript/database/package.json +1 -1
- package/functions-templates/typescript/database-drizzle/package-lock.json +8 -8
- package/functions-templates/typescript/database-drizzle/package.json +1 -1
- package/functions-templates/typescript/hello-world/package-lock.json +15 -17
- package/functions-templates/typescript/hello-world/package.json +1 -1
- package/functions-templates/typescript/scheduled-function/package.json +1 -1
- package/package.json +10 -11
- package/dist/utils/addons/prepare.d.ts +0 -13
- package/dist/utils/addons/prepare.js +0 -26
|
@@ -1,26 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import type
|
|
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
|
|
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
|
-
|
|
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
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
155
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
3
|
+
export type HashedFile = OriginalFile & {
|
|
4
4
|
hash: string;
|
|
5
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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 {
|
|
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?:
|
|
4
|
-
concurrentHash:
|
|
5
|
-
directories:
|
|
6
|
-
filter:
|
|
4
|
+
assetType?: 'file' | undefined;
|
|
5
|
+
concurrentHash: number;
|
|
6
|
+
directories: string[];
|
|
7
|
+
filter: ((filename: string) => boolean) | undefined;
|
|
7
8
|
hashAlgorithm?: string | undefined;
|
|
8
|
-
normalizer?:
|
|
9
|
-
statusCb:
|
|
9
|
+
normalizer?: (file: File) => File;
|
|
10
|
+
statusCb: StatusCallback;
|
|
10
11
|
}) => Promise<{
|
|
11
12
|
files: Record<string, string>;
|
|
12
|
-
filesShaMap: Record<string,
|
|
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
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
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?:
|
|
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:
|
|
15
|
-
tmpDir
|
|
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:
|
|
23
|
-
shaMap?: Record<string,
|
|
24
|
-
fnShaMap?: Record<string,
|
|
25
|
-
fnConfig?: Record<string,
|
|
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
|
|
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
|
|
6
|
-
hashAlgorithm:
|
|
5
|
+
concurrentHash?: number;
|
|
6
|
+
hashAlgorithm: string;
|
|
7
7
|
}) => Transform;
|
|
8
8
|
export declare const fileNormalizerCtor: ({ assetType, normalizer: normalizeFunction, }: {
|
|
9
|
-
assetType:
|
|
10
|
-
normalizer?: (file:
|
|
9
|
+
assetType: 'file';
|
|
10
|
+
normalizer?: (file: File) => File;
|
|
11
11
|
}) => Transform;
|
|
12
|
-
export declare const manifestCollectorCtor:
|
|
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:
|
|
10
|
+
assetType: 'file';
|
|
11
11
|
normalizedPath: string;
|
|
12
12
|
};
|
|
13
13
|
export declare const getDeployConfigPathIfExists: (workingDir: string) => Promise<string | undefined>;
|
|
@@ -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
|
|
@@ -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?:
|
|
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
|
-
|
|
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 (
|
|
58
|
-
|
|
59
|
-
|
|
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:
|
|
4
|
-
export declare const waitForDeploy: (api:
|
|
5
|
-
export declare const getUploadList: (required:
|
|
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
|
-
|
|
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
|
-
|
|
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
|