@sanity/runtime-cli 17.12.0 → 17.13.0-next.g06897b0
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/README.md +21 -21
- package/dist/actions/blueprints/assets.d.ts +23 -20
- package/dist/actions/blueprints/assets.js +18 -87
- package/dist/actions/blueprints/logs-polling.d.ts +3 -5
- package/dist/actions/blueprints/logs-polling.js +4 -9
- package/dist/actions/blueprints/logs.d.ts +1 -2
- package/dist/actions/blueprints/logs.js +1 -3
- package/dist/actions/blueprints/operations-state.d.ts +10 -0
- package/dist/actions/blueprints/operations-state.js +42 -0
- package/dist/actions/blueprints/operations.d.ts +2 -9
- package/dist/actions/blueprints/operations.js +1 -15
- package/dist/actions/blueprints/pre-deploy.d.ts +19 -11
- package/dist/actions/blueprints/pre-deploy.js +95 -27
- package/dist/actions/blueprints/process-assets.d.ts +13 -11
- package/dist/actions/blueprints/process-assets.js +9 -7
- package/dist/actions/blueprints/stacks.d.ts +4 -4
- package/dist/actions/blueprints/stacks.js +2 -4
- package/dist/actions/blueprints/wait-for-operation.d.ts +1 -10
- package/dist/actions/blueprints/wait-for-operation.js +56 -101
- package/dist/baseCommands.js +6 -1
- package/dist/commands/blueprints/deploy.js +2 -0
- package/dist/commands/functions/dev.js +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +6 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/cores/blueprints/config.js +1 -1
- package/dist/cores/blueprints/deploy.d.ts +2 -0
- package/dist/cores/blueprints/deploy.js +38 -7
- package/dist/cores/blueprints/destroy.js +4 -2
- package/dist/cores/blueprints/doctor.js +2 -2
- package/dist/cores/blueprints/init.js +3 -1
- package/dist/cores/blueprints/logs.js +11 -5
- package/dist/cores/blueprints/mint-deploy-token.js +2 -1
- package/dist/cores/functions/build.js +4 -5
- package/dist/cores/functions/test.js +3 -1
- package/dist/cores/index.js +3 -1
- package/dist/server/app.d.ts +2 -1
- package/dist/server/app.js +4 -1
- package/dist/server/handlers/invoke.js +1 -1
- package/dist/server/static/vendor/vendor.bundle.js +21791 -25197
- package/dist/server/static/web-socket.js +4 -2
- package/dist/utils/blueprints/deploy-metadata.d.ts +10 -0
- package/dist/utils/blueprints/deploy-metadata.js +17 -0
- package/dist/utils/blueprints/resolve-deployed-resources.d.ts +2 -3
- package/dist/utils/blueprints/resolve-deployed-resources.js +2 -2
- package/dist/utils/blueprints/wait-for.d.ts +60 -0
- package/dist/utils/blueprints/wait-for.js +115 -0
- package/dist/utils/display/blueprints-formatting.d.ts +1 -0
- package/dist/utils/display/blueprints-formatting.js +17 -3
- package/dist/utils/display/dates.d.ts +0 -2
- package/dist/utils/display/dates.js +0 -25
- package/dist/utils/display/functions-formatting.js +1 -1
- package/dist/utils/display/prompt.js +5 -2
- package/dist/utils/display/resources-formatting.d.ts +6 -0
- package/dist/utils/display/resources-formatting.js +17 -0
- package/dist/utils/functions/child-runtime/durable.js +2 -2
- package/dist/utils/functions/dependency-info.d.ts +30 -0
- package/dist/utils/functions/dependency-info.js +57 -0
- package/dist/utils/functions/invoke/assert-console.d.ts +5 -0
- package/dist/utils/functions/invoke/assert-console.js +60 -0
- package/dist/utils/functions/invoke/local.js +9 -0
- package/dist/utils/functions/is-folder-larger-than.d.ts +5 -0
- package/dist/utils/functions/is-folder-larger-than.js +38 -0
- package/dist/utils/functions/prepare-asset.d.ts +2 -0
- package/dist/utils/functions/prepare-asset.js +59 -23
- package/dist/utils/studios/prepare-asset.js +36 -9
- package/dist/utils/types.d.ts +35 -4
- package/dist/utils/types.js +0 -3
- package/oclif.manifest.json +2 -2
- package/package.json +17 -19
- package/skills/functions-dev.md +1 -1
- package/dist/utils/functions/get-folder-size.d.ts +0 -5
- package/dist/utils/functions/get-folder-size.js +0 -24
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively validates the total size of a folder, including all nested files and subdirectories.
|
|
5
|
+
*/
|
|
6
|
+
export function isFolderLargerThan(folder, maxBytes) {
|
|
7
|
+
if (!statSync(folder).isDirectory()) {
|
|
8
|
+
throw new Error('Provided path is not a directory');
|
|
9
|
+
}
|
|
10
|
+
function recurse(f, bytesSoFar) {
|
|
11
|
+
let totalBytes = bytesSoFar;
|
|
12
|
+
const fileEntries = readdirSync(f);
|
|
13
|
+
for (const file of fileEntries) {
|
|
14
|
+
const filePath = path.join(f.toString(), file);
|
|
15
|
+
const stats = statSync(filePath);
|
|
16
|
+
if (stats.isFile()) {
|
|
17
|
+
totalBytes += stats.size;
|
|
18
|
+
}
|
|
19
|
+
else if (stats.isDirectory()) {
|
|
20
|
+
const result = recurse(filePath, totalBytes);
|
|
21
|
+
totalBytes = result.totalBytes;
|
|
22
|
+
}
|
|
23
|
+
// return early if we have already exceeded the maximum
|
|
24
|
+
if (totalBytes > maxBytes) {
|
|
25
|
+
return {
|
|
26
|
+
totalBytes,
|
|
27
|
+
exceededMax: true,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
totalBytes,
|
|
33
|
+
exceededMax: false,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const result = recurse(folder, 0);
|
|
37
|
+
return result.exceededMax;
|
|
38
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import AdmZip from 'adm-zip';
|
|
1
2
|
import type { AssetPrepResult, FunctionResource, InstallerType } from '../types.js';
|
|
2
3
|
export declare function prepareAsset({ blueprintFileDir, resource, installer, }: {
|
|
3
4
|
blueprintFileDir: string;
|
|
4
5
|
resource: FunctionResource;
|
|
5
6
|
installer?: InstallerType;
|
|
6
7
|
}): Promise<AssetPrepResult>;
|
|
8
|
+
export declare function pathToZip(path: string): Promise<AdmZip>;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import {
|
|
1
|
+
import fs, { existsSync } from 'node:fs';
|
|
2
|
+
import { stat } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import AdmZip from 'adm-zip';
|
|
5
|
+
import { CONVERT_BYTES_TO_MB, MAX_ASSET_SIZE } from '../../constants.js';
|
|
6
|
+
import { getDependencyInfo, takeAutoInstallManifest, } from './dependency-info.js';
|
|
5
7
|
import { detectNativeModules, errorMessage } from './detect-native-modules.js';
|
|
6
|
-
import {
|
|
8
|
+
import { isFolderLargerThan } from './is-folder-larger-than.js';
|
|
7
9
|
import { resolveResourceDependencies } from './resolve-dependencies.js';
|
|
8
10
|
import { shouldAutoResolveDependencies } from './should-auto-resolve-deps.js';
|
|
9
11
|
import { shouldTranspileFunction } from './should-transpile.js';
|
|
@@ -15,6 +17,8 @@ export async function prepareAsset({ blueprintFileDir, resource, installer, }) {
|
|
|
15
17
|
let functionPath = resolvedFunctionPath;
|
|
16
18
|
let cleanup = async () => { };
|
|
17
19
|
let wasBundled = false;
|
|
20
|
+
let dependenciesInstalled = false;
|
|
21
|
+
let autoInstall;
|
|
18
22
|
const shouldTranspile = await shouldTranspileFunction(resource, functionPath);
|
|
19
23
|
if (shouldTranspile.transpile) {
|
|
20
24
|
try {
|
|
@@ -41,7 +45,8 @@ export async function prepareAsset({ blueprintFileDir, resource, installer, }) {
|
|
|
41
45
|
transpiled: shouldTranspile.transpile,
|
|
42
46
|
installer,
|
|
43
47
|
});
|
|
44
|
-
await
|
|
48
|
+
autoInstall = await takeAutoInstallManifest(functionPath);
|
|
49
|
+
dependenciesInstalled = true;
|
|
45
50
|
}
|
|
46
51
|
if (existsSync(path.join(functionPath, 'node_modules'))) {
|
|
47
52
|
const modulesPath = path.join(functionPath, 'node_modules');
|
|
@@ -51,29 +56,60 @@ export async function prepareAsset({ blueprintFileDir, resource, installer, }) {
|
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
// First check the size before trying to create the zip file
|
|
60
|
+
const result = isFolderLargerThan(functionPath, MAX_ASSET_SIZE);
|
|
61
|
+
if (result) {
|
|
56
62
|
throw new Error('Resource is larger than max asset size of 200 MB.');
|
|
57
63
|
}
|
|
58
|
-
|
|
64
|
+
const zip = await pathToZip(functionPath);
|
|
65
|
+
// Add up the uncompressed sizes of all entries to get a more accurate size of the asset being uploaded
|
|
66
|
+
const zipEntrySize = zip
|
|
67
|
+
.getEntries()
|
|
68
|
+
.map((entry) => entry.header.size)
|
|
69
|
+
.reduce((a, b) => a + b, 0);
|
|
70
|
+
if (zipEntrySize > MAX_ASSET_SIZE) {
|
|
71
|
+
throw new Error(`Asset size of ${(zipEntrySize / CONVERT_BYTES_TO_MB).toFixed(2)} MB exceeds the maximum allowed size of 200 MB.`);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
success: true,
|
|
75
|
+
outputBuffer: await zip.toBufferPromise(),
|
|
76
|
+
fileExtension: 'zip',
|
|
77
|
+
assetParameter: 'src',
|
|
78
|
+
cleanup,
|
|
79
|
+
metadata: {
|
|
80
|
+
transpiled: shouldTranspile.transpile,
|
|
81
|
+
bundled: wasBundled,
|
|
82
|
+
dependenciesInstalled,
|
|
83
|
+
...(await getDependencyInfo({
|
|
84
|
+
sourceDir: resolvedFunctionPath,
|
|
85
|
+
autoInstall,
|
|
86
|
+
bundled: wasBundled,
|
|
87
|
+
})),
|
|
88
|
+
assetBytes: zipEntrySize,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
59
91
|
}
|
|
60
92
|
catch (err) {
|
|
61
93
|
return { success: false, cleanup, error: err instanceof Error ? err.message : `${err}` };
|
|
62
94
|
}
|
|
63
95
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
96
|
+
export async function pathToZip(path) {
|
|
97
|
+
const stats = await stat(path);
|
|
98
|
+
const zip = new AdmZip(undefined, {
|
|
99
|
+
fs: {
|
|
100
|
+
...fs,
|
|
101
|
+
// @ts-expect-error monkey patching to return matching mtime for builds
|
|
102
|
+
statSync(path, options) {
|
|
103
|
+
const s = fs.statSync(path, options);
|
|
104
|
+
if (s)
|
|
105
|
+
s.mtime = new Date(0);
|
|
106
|
+
return s;
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
if (stats.isDirectory())
|
|
111
|
+
zip.addLocalFolder(path);
|
|
112
|
+
else
|
|
113
|
+
zip.addLocalFile(path, '', 'index.js');
|
|
114
|
+
return zip;
|
|
79
115
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { createWriteStream } from 'node:fs';
|
|
2
|
-
import { mkdtemp, rm, stat } from 'node:fs/promises';
|
|
2
|
+
import { mkdtemp, readFile, rm, stat } from 'node:fs/promises';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import path, { basename, dirname, join } from 'node:path';
|
|
5
5
|
import { pipeline } from 'node:stream/promises';
|
|
6
6
|
import { createGzip } from 'node:zlib';
|
|
7
7
|
import { buildStudio, compareDependencyVersions } from '@sanity/cli-build/_internal/build';
|
|
8
|
+
import { getLocalPackageVersion } from '@sanity/cli-core';
|
|
8
9
|
import { pack } from 'tar-fs';
|
|
9
10
|
export async function prepareStudioAsset({ blueprintFileDir, resource, }) {
|
|
10
|
-
// validate resource has an
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
!resource.externalId) {
|
|
11
|
+
// validate resource has an appId
|
|
12
|
+
const appId = getAppId(resource);
|
|
13
|
+
if (!appId) {
|
|
14
14
|
return {
|
|
15
15
|
success: false,
|
|
16
16
|
async cleanup() {
|
|
@@ -23,6 +23,8 @@ export async function prepareStudioAsset({ blueprintFileDir, resource, }) {
|
|
|
23
23
|
// no op
|
|
24
24
|
};
|
|
25
25
|
const studioPath = path.resolve(blueprintFileDir, resource.src);
|
|
26
|
+
// set only when auto-updates is on, because the build compares versions only then
|
|
27
|
+
let mismatchedPackages;
|
|
26
28
|
try {
|
|
27
29
|
const studioPathStat = await stat(studioPath);
|
|
28
30
|
if (!studioPathStat.isDirectory()) {
|
|
@@ -48,14 +50,15 @@ export async function prepareStudioAsset({ blueprintFileDir, resource, }) {
|
|
|
48
50
|
await rm(outDir, { force: true, recursive: true });
|
|
49
51
|
await rm(outFile, { force: true });
|
|
50
52
|
};
|
|
51
|
-
const appId = resource.externalId;
|
|
52
53
|
try {
|
|
53
54
|
await buildStudio({
|
|
54
55
|
appId,
|
|
55
56
|
autoUpdatesEnabled: resource.autoUpdates.enabled,
|
|
56
57
|
checkAppId() { },
|
|
57
58
|
async compareDependencyVersions(packages) {
|
|
58
|
-
|
|
59
|
+
const result = await compareDependencyVersions(packages, studioPath, { appId });
|
|
60
|
+
mismatchedPackages = result.mismatched.map((m) => m.pkg);
|
|
61
|
+
return result;
|
|
59
62
|
},
|
|
60
63
|
determineBasePath() {
|
|
61
64
|
return resource.basePath ?? '/';
|
|
@@ -105,11 +108,18 @@ export async function prepareStudioAsset({ blueprintFileDir, resource, }) {
|
|
|
105
108
|
}
|
|
106
109
|
// tar/gzip/write the built output
|
|
107
110
|
await pipeline(pack(dirname(outDir), { entries: [basename(outDir)] }), createGzip(), createWriteStream(outFile));
|
|
111
|
+
const buffer = await readFile(outFile);
|
|
108
112
|
return {
|
|
109
113
|
success: true,
|
|
110
114
|
cleanup,
|
|
111
|
-
|
|
112
|
-
|
|
115
|
+
outputBuffer: buffer,
|
|
116
|
+
fileExtension: 'tar.gz',
|
|
117
|
+
assetParameter: 'src',
|
|
118
|
+
metadata: {
|
|
119
|
+
sanityVersion: await getInstalledSanityVersion(studioPath),
|
|
120
|
+
mismatchedPackages,
|
|
121
|
+
assetBytes: buffer.length,
|
|
122
|
+
},
|
|
113
123
|
};
|
|
114
124
|
}
|
|
115
125
|
catch (error) {
|
|
@@ -137,3 +147,20 @@ function createSilentOutput() {
|
|
|
137
147
|
},
|
|
138
148
|
};
|
|
139
149
|
}
|
|
150
|
+
async function getInstalledSanityVersion(studioPath) {
|
|
151
|
+
try {
|
|
152
|
+
return (await getLocalPackageVersion('sanity', studioPath)) ?? undefined;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function getAppId(resource) {
|
|
159
|
+
if ('externalId' in resource && typeof resource.externalId === 'string' && resource.externalId) {
|
|
160
|
+
return resource.externalId;
|
|
161
|
+
}
|
|
162
|
+
else if (resource.lifecycle?.ownershipAction?.type === 'attach') {
|
|
163
|
+
return resource.lifecycle.ownershipAction.id;
|
|
164
|
+
}
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -20,8 +20,6 @@ export type FunctionResource = FunctionGroqResource | BlueprintPubSubFunctionRes
|
|
|
20
20
|
export type EventFunctionResource = Exclude<FunctionResource, BlueprintPubSubFunctionResource>;
|
|
21
21
|
/** The `event` of any function resource that declares one */
|
|
22
22
|
export type FunctionResourceEvent = EventFunctionResource['event'];
|
|
23
|
-
/** Resource types that carry a deployable asset (have src: string) */
|
|
24
|
-
export type AssetResource = FunctionResource | BlueprintStudioResource;
|
|
25
23
|
/** @internal */
|
|
26
24
|
export interface AuthParams {
|
|
27
25
|
token: string;
|
|
@@ -52,7 +50,6 @@ export declare function isRoleResource(r: unknown): r is BlueprintRoleResource;
|
|
|
52
50
|
export declare function isDatasetResource(r: unknown): r is BlueprintDatasetResource;
|
|
53
51
|
export declare function isStudioResource(r: BlueprintResource): r is BlueprintStudioResource;
|
|
54
52
|
export declare function isDurableFunctionResource(r: unknown): r is BlueprintDurableFunctionResource;
|
|
55
|
-
export declare function isAssetResource(r: BlueprintResource): r is AssetResource;
|
|
56
53
|
export declare function isWebhookResource(r: unknown): r is BlueprintDocumentWebhookResource;
|
|
57
54
|
interface StackBase {
|
|
58
55
|
id: string;
|
|
@@ -90,7 +87,22 @@ export interface StackMutation {
|
|
|
90
87
|
};
|
|
91
88
|
userMessage?: string;
|
|
92
89
|
preDeploy?: boolean;
|
|
90
|
+
metadata?: DeployMetadata;
|
|
93
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Facts about one deploy, stored with the Blueprint on the server.
|
|
94
|
+
* The API accepts it on stack update and never returns it.
|
|
95
|
+
*/
|
|
96
|
+
export interface DeployMetadata {
|
|
97
|
+
/** The environment that ran the deploy */
|
|
98
|
+
client?: Record<string, unknown>;
|
|
99
|
+
/** One entry per resource that had an asset prepared, plus what was learned while preparing it */
|
|
100
|
+
resources?: ResourceMetadata[];
|
|
101
|
+
}
|
|
102
|
+
export type ResourceMetadata = {
|
|
103
|
+
name: string;
|
|
104
|
+
type: string;
|
|
105
|
+
} & Record<string, unknown>;
|
|
94
106
|
/** @internal */
|
|
95
107
|
export interface BuildPayloadOptions {
|
|
96
108
|
data?: string;
|
|
@@ -301,13 +313,32 @@ export declare const INSTALLER_OPTIONS: readonly ['npm', 'pnpm', 'yarn'];
|
|
|
301
313
|
export type InstallerType = 'npm' | 'pnpm' | 'yarn';
|
|
302
314
|
export type AssetPrepResult = {
|
|
303
315
|
success: true;
|
|
304
|
-
|
|
316
|
+
outputBuffer: Buffer;
|
|
317
|
+
fileExtension: string;
|
|
318
|
+
assetParameter: string;
|
|
305
319
|
cleanup: () => Promise<void>;
|
|
320
|
+
/** Facts learned about the resource while preparing its asset. Sent as deploy metadata. */
|
|
321
|
+
metadata?: Record<string, unknown>;
|
|
306
322
|
} | {
|
|
307
323
|
success: false;
|
|
308
324
|
cleanup: () => Promise<void>;
|
|
309
325
|
error: string;
|
|
310
326
|
};
|
|
327
|
+
export type PrepAssetFn<R extends BlueprintResource> = (options: {
|
|
328
|
+
resource: R;
|
|
329
|
+
blueprintFileDir: string;
|
|
330
|
+
installer?: InstallerType;
|
|
331
|
+
}) => Promise<AssetPrepResult>;
|
|
332
|
+
export type PreDeployConfig = {
|
|
333
|
+
/** The resource type this config applies to or a function that returns true if this config applies to the given type. */
|
|
334
|
+
resourceType: string | ((type: string) => boolean);
|
|
335
|
+
/** Function that takes a resource and returns a buffer to be sent to blueprints. */
|
|
336
|
+
prepareAsset?: PrepAssetFn<BlueprintResource>;
|
|
337
|
+
};
|
|
338
|
+
export type AssetResource<R extends BlueprintResource> = {
|
|
339
|
+
resource: R;
|
|
340
|
+
prepareAsset: PrepAssetFn<R>;
|
|
341
|
+
};
|
|
311
342
|
export type Warning = {
|
|
312
343
|
code: string;
|
|
313
344
|
suggestions: string[];
|
package/dist/utils/types.js
CHANGED
|
@@ -31,9 +31,6 @@ export function isStudioResource(r) {
|
|
|
31
31
|
export function isDurableFunctionResource(r) {
|
|
32
32
|
return validateDurableFunction(r).length === 0;
|
|
33
33
|
}
|
|
34
|
-
export function isAssetResource(r) {
|
|
35
|
-
return isLocalFunctionResource(r) || isStudioResource(r);
|
|
36
|
-
}
|
|
37
34
|
export function isWebhookResource(r) {
|
|
38
35
|
return validateDocumentWebhook(r).length === 0;
|
|
39
36
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -2042,7 +2042,7 @@
|
|
|
2042
2042
|
"functions:dev": {
|
|
2043
2043
|
"aliases": [],
|
|
2044
2044
|
"args": {},
|
|
2045
|
-
"description": "Runs a local, web-based development server to test your functions before deploying.\n\nOpen the emulator in your browser to interactively test your functions with the payload editor.\n\nOptionally, set the host and port with the --host and --port flags.
|
|
2045
|
+
"description": "Runs a local, web-based development server to test your functions before deploying.\n\nOpen the emulator in your browser to interactively test your functions with the payload editor.\n\nOptionally, set the host and port with the --host and --port flags. The live-reload WebSocket server shares this host and port. Function timeout can be configured with the --timeout flag.\n\nTo invoke a function with the CLI, use 'functions test'.",
|
|
2046
2046
|
"examples": [
|
|
2047
2047
|
"<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port 3333",
|
|
2048
2048
|
"<%= config.bin %> <%= command.id %> --timeout 60"
|
|
@@ -3148,5 +3148,5 @@
|
|
|
3148
3148
|
]
|
|
3149
3149
|
}
|
|
3150
3150
|
},
|
|
3151
|
-
"version": "17.
|
|
3151
|
+
"version": "17.13.0-next.g06897b0"
|
|
3152
3152
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/runtime-cli",
|
|
3
3
|
"description": "Sanity's Runtime CLI for Blueprints and Functions",
|
|
4
|
-
"version": "17.
|
|
4
|
+
"version": "17.13.0-next.g06897b0",
|
|
5
5
|
"author": "Sanity Runtime Team",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"sanity-run": "bin/run.js"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
|
-
"build": "npm run build:
|
|
38
|
-
"build:
|
|
37
|
+
"build": "npm run build:vendor && npm run build:ts && npm run build:static && npm run build:oclif",
|
|
38
|
+
"build:vendor": "vite build --config vite.vendor.config.mjs",
|
|
39
39
|
"build:oclif": "oclif manifest && oclif readme",
|
|
40
40
|
"build:ts": "shx rm -rf dist *.tsbuildinfo && tsc -b",
|
|
41
41
|
"build:static": "npm run copy:wrapper && npm run copy:design-tokens && npm run copy:server",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"postpack": "shx rm -f oclif.manifest.json",
|
|
53
53
|
"test": "npm run typecheck && vitest run && npm run test:depmgmt && npm run lint",
|
|
54
54
|
"test:depmgmt": "vitest run --config ./test-depmgmt/vitest.config.ts",
|
|
55
|
-
"test:coverage": "vitest run --coverage --coverage.include \"
|
|
55
|
+
"test:coverage": "vitest run --coverage --coverage.include \"src/**/*\" --coverage.exclude \"src/server/static/**\"",
|
|
56
56
|
"test:scenarios": "vitest run test/scenarios",
|
|
57
57
|
"test:playwright": "playwright install chromium && playwright install-deps chromium && playwright test",
|
|
58
58
|
"test:bp-version-smoke": "node ./test/blueprints-version-smoke.js",
|
|
@@ -64,16 +64,16 @@
|
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@architect/hydrate": "~6.0.2",
|
|
66
66
|
"@architect/inventory": "~6.1.0",
|
|
67
|
-
"@inquirer/prompts": "^8.7.
|
|
67
|
+
"@inquirer/prompts": "^8.7.2",
|
|
68
68
|
"@oclif/core": "^4.14.0",
|
|
69
69
|
"@oclif/plugin-help": "^6.3.0",
|
|
70
70
|
"@sanity-labs/oclif-plugin-skills-flag": "^0.2.1",
|
|
71
71
|
"@sanity/blueprints": "^0.24.0",
|
|
72
72
|
"@sanity/blueprints-parser": "^0.5.0",
|
|
73
|
-
"@sanity/cli-build": "^
|
|
74
|
-
"@sanity/cli-core": "^3.
|
|
75
|
-
"@sanity/client": "^8.
|
|
76
|
-
"adm-zip": "^0.6.
|
|
73
|
+
"@sanity/cli-build": "^6.3.0",
|
|
74
|
+
"@sanity/cli-core": "^3.7.0",
|
|
75
|
+
"@sanity/client": "^8.6.1",
|
|
76
|
+
"adm-zip": "^0.6.1",
|
|
77
77
|
"array-treeify": "^0.2.0",
|
|
78
78
|
"cardinal": "^2.1.1",
|
|
79
79
|
"empathic": "^2.0.1",
|
|
@@ -86,37 +86,35 @@
|
|
|
86
86
|
"strip-ansi": "^7.2.0",
|
|
87
87
|
"tar-fs": "^3.1.3",
|
|
88
88
|
"tar-stream": "^3.2.1",
|
|
89
|
-
"vite": "^8.
|
|
89
|
+
"vite": "^8.3.0",
|
|
90
90
|
"ws": "^8.21.3",
|
|
91
91
|
"xdg-basedir": "^5.1.0"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@biomejs/biome": "2.5.
|
|
94
|
+
"@biomejs/biome": "2.5.13",
|
|
95
95
|
"@codemirror/lang-json": "^6.0.2",
|
|
96
96
|
"@codemirror/language": "^6.12.4",
|
|
97
|
-
"@codemirror/state": "^6.7.
|
|
97
|
+
"@codemirror/state": "^6.7.4",
|
|
98
98
|
"@enhance/store": "^1.0.2",
|
|
99
99
|
"@lezer/highlight": "^1.2.3",
|
|
100
100
|
"@oclif/test": "^4.2.0",
|
|
101
|
-
"@playwright/test": "^1.
|
|
102
|
-
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
101
|
+
"@playwright/test": "^1.63.0",
|
|
103
102
|
"@sanity-labs/design-tokens": "^0.0.2-alpha.2",
|
|
104
|
-
"@sanity/functions": "^1.7.
|
|
103
|
+
"@sanity/functions": "^1.7.2",
|
|
105
104
|
"@types/cardinal": "^2.1.1",
|
|
106
105
|
"@types/mime-types": "^3.0.1",
|
|
107
106
|
"@types/node": "^22",
|
|
108
107
|
"@types/tar-fs": "^2.0.4",
|
|
109
108
|
"@types/ws": "^8.18.1",
|
|
110
|
-
"@vitest/coverage-v8": "
|
|
109
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
111
110
|
"codemirror": "^6.0.2",
|
|
112
111
|
"mentoss": "^0.13.0",
|
|
113
112
|
"oclif": "^4.24.0",
|
|
114
|
-
"pretty-bytes": "^7.1.
|
|
113
|
+
"pretty-bytes": "^7.1.3",
|
|
115
114
|
"pretty-ms": "^9.3.1",
|
|
116
|
-
"rollup": "^4.63.1",
|
|
117
115
|
"shx": "^0.4.0",
|
|
118
116
|
"typescript": "^7.0.2",
|
|
119
|
-
"vitest": "
|
|
117
|
+
"vitest": "5.0.0"
|
|
120
118
|
},
|
|
121
119
|
"oclif": {
|
|
122
120
|
"bin": "sanity-run",
|
package/skills/functions-dev.md
CHANGED
|
@@ -16,6 +16,6 @@ The emulator is available at `http://localhost:8080`. Choose another loopback po
|
|
|
16
16
|
npx @sanity/cli functions dev --host 127.0.0.1 --port 3333 --timeout 60
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The emulator's live-reload WebSocket server shares the same host and port, so no additional port is reserved. `--timeout` sets the execution limit in seconds for every Function, taking precedence over each Function's configured `timeout` (default 10 seconds). Bind to a non-loopback interface only when network access is requested and exposing the development server is acceptable.
|
|
20
20
|
|
|
21
21
|
Run this command in a persistent terminal, report the URL, and stop the process when development is complete. For one bounded invocation without a web server, use `functions test`.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { readdirSync, statSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Recursively calculates the total size of a folder, including all nested files and subdirectories.
|
|
5
|
-
*/
|
|
6
|
-
export const getFolderSize = (folder) => {
|
|
7
|
-
if (!statSync(folder).isDirectory()) {
|
|
8
|
-
throw new Error('Provided path is not a directory');
|
|
9
|
-
}
|
|
10
|
-
let totalSize = 0;
|
|
11
|
-
const fileEntries = readdirSync(folder);
|
|
12
|
-
for (const file of fileEntries) {
|
|
13
|
-
const filePath = path.join(folder.toString(), file);
|
|
14
|
-
const stats = statSync(filePath);
|
|
15
|
-
if (stats.isFile()) {
|
|
16
|
-
totalSize += stats.size;
|
|
17
|
-
}
|
|
18
|
-
else if (stats.isDirectory()) {
|
|
19
|
-
const recursiveSize = getFolderSize(filePath);
|
|
20
|
-
totalSize += recursiveSize;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return totalSize;
|
|
24
|
-
};
|