@sanity/runtime-cli 17.1.0 → 17.2.0
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 +23 -22
- package/dist/actions/blueprints/assets.d.ts +2 -1
- package/dist/actions/blueprints/assets.js +2 -2
- package/dist/actions/blueprints/blueprint.d.ts +1 -1
- package/dist/actions/blueprints/wait-for-operation.js +4 -0
- package/dist/actions/sanity/examples.d.ts +4 -4
- package/dist/baseCommands.d.ts +4 -4
- package/dist/commands/blueprints/add.d.ts +1 -1
- package/dist/commands/blueprints/config.d.ts +1 -1
- package/dist/commands/blueprints/deploy.d.ts +1 -1
- package/dist/commands/blueprints/destroy.d.ts +1 -1
- package/dist/commands/blueprints/doctor.d.ts +0 -1
- package/dist/commands/blueprints/doctor.js +3 -7
- package/dist/commands/blueprints/info.d.ts +1 -1
- package/dist/commands/blueprints/logs.d.ts +1 -1
- package/dist/commands/blueprints/mint-deploy-token.d.ts +1 -1
- package/dist/commands/blueprints/plan.d.ts +1 -1
- package/dist/commands/blueprints/promote.d.ts +1 -1
- package/dist/commands/blueprints/stacks.d.ts +1 -1
- package/dist/commands/functions/add.d.ts +1 -1
- package/dist/commands/functions/build.d.ts +1 -1
- package/dist/commands/functions/dev.d.ts +1 -1
- package/dist/commands/functions/env/add.d.ts +1 -1
- package/dist/commands/functions/env/list.d.ts +1 -1
- package/dist/commands/functions/env/remove.d.ts +1 -1
- package/dist/commands/functions/logs.d.ts +1 -1
- package/dist/commands/functions/test.d.ts +1 -1
- package/dist/cores/blueprints/deploy.js +5 -4
- package/dist/cores/blueprints/doctor.js +15 -12
- package/dist/cores/functions/build.js +3 -2
- package/dist/cores/functions/test.js +4 -2
- package/dist/server/app.js +8 -2
- package/dist/server/static/favicon-dark.svg +1 -0
- package/dist/server/static/favicon.svg +1 -0
- package/dist/server/static/index.html +1 -1
- package/dist/server/static/vendor/vendor.bundle.js +5 -0
- package/dist/utils/functions/find-entry-point.d.ts +1 -1
- package/dist/utils/functions/find-entry-point.js +10 -12
- package/dist/utils/functions/invoke/local.js +1 -1
- package/dist/utils/functions/invoke/prepare.d.ts +1 -1
- package/dist/utils/functions/invoke/prepare.js +19 -8
- package/dist/utils/functions/package-json.d.ts +1 -2
- package/dist/utils/functions/package-json.js +4 -6
- package/dist/utils/functions/prepare-asset.d.ts +2 -2
- package/dist/utils/functions/prepare-asset.js +18 -7
- package/dist/utils/functions/resolve-dependencies.d.ts +4 -1
- package/dist/utils/functions/resolve-dependencies.js +5 -6
- package/dist/utils/functions/resource-to-arc.d.ts +1 -1
- package/dist/utils/functions/resource-to-arc.js +4 -5
- package/dist/utils/functions/should-transpile.d.ts +7 -1
- package/dist/utils/functions/should-transpile.js +10 -10
- package/dist/utils/functions/transpile/function.d.ts +4 -1
- package/dist/utils/functions/transpile/function.js +9 -14
- package/dist/utils/functions/transpile/verify-handler.js +1 -1
- package/dist/utils/logger.d.ts +7 -5
- package/dist/utils/logger.js +33 -1
- package/dist/utils/progress.d.ts +5 -0
- package/dist/utils/progress.js +40 -0
- package/dist/utils/types.d.ts +5 -1
- package/oclif.manifest.json +896 -895
- package/package.json +23 -22
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
3
|
import { cwd } from 'node:process';
|
|
4
4
|
import { testAction } from '../../actions/functions/test.js';
|
|
5
5
|
import config from '../../config.js';
|
|
@@ -50,6 +50,7 @@ export async function functionTestCore(options) {
|
|
|
50
50
|
: undefined,
|
|
51
51
|
logger: log,
|
|
52
52
|
});
|
|
53
|
+
const blueprintFileDir = dirname(blueprint.fileInfo.blueprintFilePath);
|
|
53
54
|
const contextOptions = docFunction || mediaFunction
|
|
54
55
|
? {
|
|
55
56
|
clientOptions: {
|
|
@@ -63,8 +64,9 @@ export async function functionTestCore(options) {
|
|
|
63
64
|
functionResourceType: 'project',
|
|
64
65
|
functionResourceId: projectId || '',
|
|
65
66
|
resources: resolvedResources,
|
|
67
|
+
blueprintFileDir,
|
|
66
68
|
}
|
|
67
|
-
: { clientOptions: {}, resources: resolvedResources };
|
|
69
|
+
: { clientOptions: {}, resources: resolvedResources, blueprintFileDir };
|
|
68
70
|
// If the user sets the flag to use the real token set it in our options
|
|
69
71
|
if (withUserToken) {
|
|
70
72
|
contextOptions.clientOptions.token = config.token || undefined;
|
package/dist/server/app.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, watchFile } from 'node:fs';
|
|
2
2
|
import * as http from 'node:http';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
3
4
|
import { default as mime } from 'mime-types';
|
|
4
5
|
import { WebSocket, WebSocketServer } from 'ws';
|
|
5
6
|
import { findBlueprintFile, loadAndParseBlueprint } from '../actions/blueprints/blueprint.js';
|
|
@@ -68,7 +69,11 @@ const app = (host, port, validateResources, executionOptions) => {
|
|
|
68
69
|
req.on('end', async () => {
|
|
69
70
|
res.setHeader('Content-Type', 'application/json');
|
|
70
71
|
try {
|
|
71
|
-
const
|
|
72
|
+
const fileInfo = findBlueprintFile();
|
|
73
|
+
if (!fileInfo) {
|
|
74
|
+
throw Error('Could not find a Blueprint manifest (sanity.blueprint.ts, .js, or .json). Run `blueprints init` to create one.');
|
|
75
|
+
}
|
|
76
|
+
const { data, func: functionName, metadata, } = parseInvokeRequest(Buffer.concat(body), dirname(fileInfo.blueprintFilePath));
|
|
72
77
|
const { context, event } = data;
|
|
73
78
|
// replace user token if required
|
|
74
79
|
if (isGroqContextOptions(context)) {
|
|
@@ -312,7 +317,7 @@ function buildApiUrl(projectId, dataset, docId, apiUrl) {
|
|
|
312
317
|
function buildAssetUrl(mediaLibraryId, docId, apiUrl) {
|
|
313
318
|
return `${apiUrl}/v2025-03-24/media-libraries/${mediaLibraryId}/doc/${docId}`;
|
|
314
319
|
}
|
|
315
|
-
function parseInvokeRequest(body) {
|
|
320
|
+
function parseInvokeRequest(body, blueprintFileDir) {
|
|
316
321
|
let json;
|
|
317
322
|
try {
|
|
318
323
|
json = JSON.parse(body.toString('utf8'));
|
|
@@ -404,6 +409,7 @@ function parseInvokeRequest(body) {
|
|
|
404
409
|
context: {
|
|
405
410
|
...context,
|
|
406
411
|
clientOptions,
|
|
412
|
+
blueprintFileDir,
|
|
407
413
|
// Provide default values for required properties if not present
|
|
408
414
|
eventResourceType: typeof context.eventResourceType === 'string' ? context.eventResourceType : '',
|
|
409
415
|
eventResourceId: typeof context.eventResourceId === 'string' ? context.eventResourceId : '',
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<filters-component></filters-component>
|
|
34
34
|
<input type="checkbox" id="nav-toggle" class="hidden">
|
|
35
35
|
<nav id="sidebar" class="relative y-scroll max-h-100 pad-t-5 border-right overflow-auto nav-min-width">
|
|
36
|
-
<label for="nav-toggle" id="nav-toggle-label" title="Toggle Functions list" class="z-10 nav-label"></label>
|
|
36
|
+
<label for="nav-toggle" id="nav-toggle-label" aria-label="Toggle Functions list" title="Toggle Functions list" class="z-10 nav-label"></label>
|
|
37
37
|
<h4 class="config-label mar-t-0 mar-b-3 pad-l-3">Functions</h4>
|
|
38
38
|
<function-list></function-list>
|
|
39
39
|
</nav>
|
|
@@ -6203,6 +6203,7 @@ class FacetProvider {
|
|
|
6203
6203
|
}
|
|
6204
6204
|
};
|
|
6205
6205
|
}
|
|
6206
|
+
get extension() { return this; }
|
|
6206
6207
|
}
|
|
6207
6208
|
function compareArray(a, b, compare) {
|
|
6208
6209
|
if (a.length != b.length)
|
|
@@ -6400,6 +6401,7 @@ class PrecExtension {
|
|
|
6400
6401
|
this.inner = inner;
|
|
6401
6402
|
this.prec = prec;
|
|
6402
6403
|
}
|
|
6404
|
+
get extension() { return this; }
|
|
6403
6405
|
}
|
|
6404
6406
|
/**
|
|
6405
6407
|
Extension compartments can be used to make a configuration
|
|
@@ -6434,6 +6436,7 @@ class CompartmentInstance {
|
|
|
6434
6436
|
this.compartment = compartment;
|
|
6435
6437
|
this.inner = inner;
|
|
6436
6438
|
}
|
|
6439
|
+
get extension() { return this; }
|
|
6437
6440
|
}
|
|
6438
6441
|
class Configuration {
|
|
6439
6442
|
constructor(base, compartments, dynamicSlots, address, staticValues, facets) {
|
|
@@ -6543,6 +6546,8 @@ function flatten(extension, compartments, newCompartments) {
|
|
|
6543
6546
|
else {
|
|
6544
6547
|
let content = ext.extension;
|
|
6545
6548
|
if (!content)
|
|
6549
|
+
throw new Error(`Unrecognized extension value in extension set (${ext}).`);
|
|
6550
|
+
if (content == ext)
|
|
6546
6551
|
throw new Error(`Unrecognized extension value in extension set (${ext}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);
|
|
6547
6552
|
inner(content, prec);
|
|
6548
6553
|
}
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
* @returns The absolute path to the entry file.
|
|
9
9
|
* @throws If the entry file cannot be determined.
|
|
10
10
|
*/
|
|
11
|
-
export declare function findFunctionEntryPoint(
|
|
11
|
+
export declare function findFunctionEntryPoint(functionPath: string, displayName?: string): Promise<string>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { readFile, stat } from 'node:fs/promises';
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
|
-
import { cwd } from 'node:process';
|
|
4
3
|
/**
|
|
5
4
|
* Resolves the source path to an executable entry file path.
|
|
6
5
|
*
|
|
@@ -11,27 +10,26 @@ import { cwd } from 'node:process';
|
|
|
11
10
|
* @returns The absolute path to the entry file.
|
|
12
11
|
* @throws If the entry file cannot be determined.
|
|
13
12
|
*/
|
|
14
|
-
export async function findFunctionEntryPoint(
|
|
15
|
-
const absolutePath = resolve(cwd(), srcPath);
|
|
13
|
+
export async function findFunctionEntryPoint(functionPath, displayName) {
|
|
16
14
|
let stats;
|
|
17
15
|
try {
|
|
18
|
-
stats = await stat(
|
|
16
|
+
stats = await stat(functionPath);
|
|
19
17
|
}
|
|
20
18
|
catch (err) {
|
|
21
|
-
throw new Error(`Source path not found or inaccessible: ${
|
|
19
|
+
throw new Error(`Source path not found or inaccessible: ${functionPath}`, { cause: err });
|
|
22
20
|
}
|
|
23
21
|
if (stats.isFile()) {
|
|
24
22
|
// It's already an entry file path
|
|
25
|
-
return
|
|
23
|
+
return functionPath;
|
|
26
24
|
}
|
|
27
25
|
if (stats.isDirectory()) {
|
|
28
26
|
// 1. Check package.json#main
|
|
29
27
|
try {
|
|
30
|
-
const pkgJsonPath = join(
|
|
28
|
+
const pkgJsonPath = join(functionPath, 'package.json');
|
|
31
29
|
const pkgJsonContent = await readFile(pkgJsonPath, 'utf8');
|
|
32
30
|
const pkgJson = JSON.parse(pkgJsonContent);
|
|
33
31
|
if (pkgJson.main) {
|
|
34
|
-
const mainPath = resolve(
|
|
32
|
+
const mainPath = resolve(functionPath, pkgJson.main);
|
|
35
33
|
if (await fileExists(mainPath)) {
|
|
36
34
|
return mainPath;
|
|
37
35
|
}
|
|
@@ -43,20 +41,20 @@ export async function findFunctionEntryPoint(srcPath, displayName) {
|
|
|
43
41
|
// Consider warning the user on invalid JSON though?
|
|
44
42
|
}
|
|
45
43
|
// 2. Check index.ts
|
|
46
|
-
const indexTs = join(
|
|
44
|
+
const indexTs = join(functionPath, 'index.ts');
|
|
47
45
|
if (await fileExists(indexTs)) {
|
|
48
46
|
return indexTs;
|
|
49
47
|
}
|
|
50
48
|
// 3. Check index.js
|
|
51
|
-
const indexJs = join(
|
|
49
|
+
const indexJs = join(functionPath, 'index.js');
|
|
52
50
|
if (await fileExists(indexJs)) {
|
|
53
51
|
return indexJs;
|
|
54
52
|
}
|
|
55
53
|
const nameHint = displayName ? ` for function "${displayName}"` : '';
|
|
56
|
-
throw new Error(`Could not determine entry file${nameHint} in directory: ${
|
|
54
|
+
throw new Error(`Could not determine entry file${nameHint} in directory: ${functionPath}. Looked for package.json#main, index.ts, index.js.`);
|
|
57
55
|
}
|
|
58
56
|
// Should not happen if stat succeeded, but defensively handle
|
|
59
|
-
throw new Error(`Source path is neither a file nor a directory: ${
|
|
57
|
+
throw new Error(`Source path is neither a file nor a directory: ${functionPath}`);
|
|
60
58
|
}
|
|
61
59
|
/**
|
|
62
60
|
* Checks if a file exists and is a file.
|
|
@@ -66,7 +66,7 @@ export default async function invoke(resource, payload, context, options) {
|
|
|
66
66
|
// Acquire a shared, reference-counted build. Concurrent invokes of the same
|
|
67
67
|
// function reuse one transpile + temp package.json instead of racing on the
|
|
68
68
|
// per-function build paths; the build is torn down once every invoke releases.
|
|
69
|
-
const build = acquireFunctionBuild(resource);
|
|
69
|
+
const build = acquireFunctionBuild(resource, context.blueprintFileDir);
|
|
70
70
|
let functionPath;
|
|
71
71
|
let bundleTimings;
|
|
72
72
|
try {
|
|
@@ -17,4 +17,4 @@ export interface FunctionBuild {
|
|
|
17
17
|
* caller MUST call `release()` exactly once when its child has exited, so the
|
|
18
18
|
* shared artifacts are torn down only after the last in-flight invoke finishes.
|
|
19
19
|
*/
|
|
20
|
-
export declare function acquireFunctionBuild(resource: FunctionResource): FunctionBuild;
|
|
20
|
+
export declare function acquireFunctionBuild(resource: FunctionResource, blueprintFileDir: string): FunctionBuild;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import { findFunctionEntryPoint } from '../find-entry-point.js';
|
|
2
3
|
import { cleanupTempPackageJson, createTempPackageJson, doesPackageJsonExists, } from '../package-json.js';
|
|
3
4
|
import { resolveResourceDependencies } from '../resolve-dependencies.js';
|
|
@@ -22,34 +23,44 @@ function buildKey(resource) {
|
|
|
22
23
|
* caller MUST call `release()` exactly once when its child has exited, so the
|
|
23
24
|
* shared artifacts are torn down only after the last in-flight invoke finishes.
|
|
24
25
|
*/
|
|
25
|
-
export function acquireFunctionBuild(resource) {
|
|
26
|
+
export function acquireFunctionBuild(resource, blueprintFileDir) {
|
|
26
27
|
const key = buildKey(resource);
|
|
27
28
|
let entry = builds.get(key);
|
|
28
29
|
if (!entry) {
|
|
29
30
|
let cleanupBundle = async () => { };
|
|
30
|
-
|
|
31
|
+
const resolvedFunctionPath = path.resolve(blueprintFileDir, resource.src);
|
|
32
|
+
let functionPath = resolvedFunctionPath;
|
|
31
33
|
let createdTempPackageJson = false;
|
|
32
34
|
// If no package.json exists we create a temporary one to avoid the
|
|
33
35
|
// "module type" warning from node.
|
|
34
|
-
const existingPackageJson = doesPackageJsonExists(
|
|
36
|
+
const existingPackageJson = doesPackageJsonExists(functionPath);
|
|
35
37
|
const ready = (async () => {
|
|
36
38
|
if (!resource.src) {
|
|
37
39
|
throw new Error(`Function resource "${resource.name}" is missing the 'src' property.`);
|
|
38
40
|
}
|
|
39
41
|
let bundleTimings;
|
|
40
|
-
const shouldTranspile = await shouldTranspileFunction(resource);
|
|
41
|
-
if (shouldTranspile) {
|
|
42
|
-
const transpileResult = await transpileFunction(
|
|
42
|
+
const shouldTranspile = await shouldTranspileFunction(resource, functionPath);
|
|
43
|
+
if (shouldTranspile.transpile) {
|
|
44
|
+
const transpileResult = await transpileFunction({
|
|
45
|
+
resource,
|
|
46
|
+
functionPath,
|
|
47
|
+
entryPoint: shouldTranspile.entryPoint,
|
|
48
|
+
});
|
|
43
49
|
functionPath = await findFunctionEntryPoint(transpileResult.outputDir);
|
|
44
50
|
bundleTimings = transpileResult.timings;
|
|
45
51
|
cleanupBundle = transpileResult.cleanup;
|
|
46
52
|
}
|
|
47
53
|
else {
|
|
48
|
-
functionPath = await findFunctionEntryPoint(
|
|
54
|
+
functionPath = await findFunctionEntryPoint(functionPath, resource.displayName ?? resource.name);
|
|
49
55
|
}
|
|
50
56
|
const shouldResolveDependencies = await shouldAutoResolveDependencies(resource);
|
|
51
57
|
if (shouldResolveDependencies && existingPackageJson) {
|
|
52
|
-
await resolveResourceDependencies(
|
|
58
|
+
await resolveResourceDependencies({
|
|
59
|
+
resource,
|
|
60
|
+
functionPath: resolvedFunctionPath,
|
|
61
|
+
blueprintFileDir,
|
|
62
|
+
transpiled: shouldTranspile.transpile,
|
|
63
|
+
});
|
|
53
64
|
}
|
|
54
65
|
if (!existingPackageJson) {
|
|
55
66
|
createTempPackageJson(functionPath);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function doesPackageJsonExists(resource: FunctionResource): boolean;
|
|
1
|
+
export declare function doesPackageJsonExists(functionPath: string): boolean;
|
|
3
2
|
export declare function createTempPackageJson(functionPath: string): boolean;
|
|
4
3
|
export declare function cleanupTempPackageJson(functionPath: string): boolean;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { existsSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { dirname, join
|
|
3
|
-
import { cwd } from 'node:process';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
4
3
|
function getPackageJsonPath(functionPath) {
|
|
5
4
|
const functionDir = dirname(functionPath);
|
|
6
5
|
return join(functionDir, 'package.json');
|
|
7
6
|
}
|
|
8
|
-
export function doesPackageJsonExists(
|
|
9
|
-
if (!
|
|
7
|
+
export function doesPackageJsonExists(functionPath) {
|
|
8
|
+
if (!functionPath) {
|
|
10
9
|
// Cannot determine without a source path
|
|
11
10
|
return false;
|
|
12
11
|
}
|
|
13
|
-
const
|
|
14
|
-
const packageJsonPath = join(absolutePath, 'package.json');
|
|
12
|
+
const packageJsonPath = join(functionPath, 'package.json');
|
|
15
13
|
return existsSync(packageJsonPath);
|
|
16
14
|
}
|
|
17
15
|
export function createTempPackageJson(functionPath) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AssetPrepResult, FunctionResource, InstallerType } from '../types.js';
|
|
2
|
-
export declare function prepareAsset({ resource, }: {
|
|
2
|
+
export declare function prepareAsset({ blueprintFileDir, resource, installer, }: {
|
|
3
|
+
blueprintFileDir: string;
|
|
3
4
|
resource: FunctionResource;
|
|
4
|
-
}, { installer }?: {
|
|
5
5
|
installer?: InstallerType;
|
|
6
6
|
}): Promise<AssetPrepResult>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { rm, stat } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { cwd } from 'node:process';
|
|
5
4
|
import { MAX_ASSET_SIZE } from '../../constants.js';
|
|
6
5
|
import { detectNativeModules, errorMessage } from './detect-native-modules.js';
|
|
7
6
|
import { getFolderSize } from './get-folder-size.js';
|
|
@@ -9,16 +8,22 @@ import { resolveResourceDependencies } from './resolve-dependencies.js';
|
|
|
9
8
|
import { shouldAutoResolveDependencies } from './should-auto-resolve-deps.js';
|
|
10
9
|
import { shouldTranspileFunction } from './should-transpile.js';
|
|
11
10
|
import { transpileFunction } from './transpile/function.js';
|
|
12
|
-
export async function prepareAsset({
|
|
11
|
+
export async function prepareAsset({ blueprintFileDir, resource, installer, }) {
|
|
13
12
|
if (!resource.src)
|
|
14
13
|
throw new Error('Resource src is required');
|
|
15
|
-
|
|
14
|
+
const resolvedFunctionPath = path.resolve(blueprintFileDir, resource.src);
|
|
15
|
+
let functionPath = resolvedFunctionPath;
|
|
16
16
|
let cleanup = async () => { };
|
|
17
17
|
let wasBundled = false;
|
|
18
|
-
const shouldTranspile = await shouldTranspileFunction(resource);
|
|
19
|
-
if (shouldTranspile) {
|
|
18
|
+
const shouldTranspile = await shouldTranspileFunction(resource, functionPath);
|
|
19
|
+
if (shouldTranspile.transpile) {
|
|
20
20
|
try {
|
|
21
|
-
const result = await transpileFunction(
|
|
21
|
+
const result = await transpileFunction({
|
|
22
|
+
resource,
|
|
23
|
+
functionPath,
|
|
24
|
+
entryPoint: shouldTranspile.entryPoint,
|
|
25
|
+
installer,
|
|
26
|
+
});
|
|
22
27
|
functionPath = result.outputDir;
|
|
23
28
|
cleanup = result.cleanup;
|
|
24
29
|
wasBundled = result.bundled;
|
|
@@ -29,7 +34,13 @@ export async function prepareAsset({ resource, }, { installer } = {}) {
|
|
|
29
34
|
}
|
|
30
35
|
const shouldResolveDependencies = await shouldAutoResolveDependencies(resource);
|
|
31
36
|
if (shouldResolveDependencies && !wasBundled) {
|
|
32
|
-
await resolveResourceDependencies(
|
|
37
|
+
await resolveResourceDependencies({
|
|
38
|
+
resource,
|
|
39
|
+
functionPath: resolvedFunctionPath,
|
|
40
|
+
blueprintFileDir,
|
|
41
|
+
transpiled: shouldTranspile.transpile,
|
|
42
|
+
installer,
|
|
43
|
+
});
|
|
33
44
|
await removeArcAutoInstallPackageJson(functionPath);
|
|
34
45
|
}
|
|
35
46
|
if (existsSync(path.join(functionPath, 'node_modules'))) {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { FunctionResource, InstallerType } from '../types.js';
|
|
2
|
-
export declare function resolveResourceDependencies(resource
|
|
2
|
+
export declare function resolveResourceDependencies({ resource, transpiled, blueprintFileDir, functionPath, installer, }: {
|
|
3
|
+
resource: FunctionResource;
|
|
4
|
+
blueprintFileDir: string;
|
|
5
|
+
functionPath: string;
|
|
3
6
|
transpiled: boolean;
|
|
4
7
|
installer?: InstallerType;
|
|
5
8
|
}): Promise<void>;
|
|
@@ -3,18 +3,17 @@ import { join } from 'node:path';
|
|
|
3
3
|
import hydrate from '@architect/hydrate';
|
|
4
4
|
import inventory from '@architect/inventory';
|
|
5
5
|
import { convertResourceToArcFormat } from './resource-to-arc.js';
|
|
6
|
-
export async function resolveResourceDependencies(resource,
|
|
7
|
-
const rawArc = await convertResourceToArcFormat(resource, transpiled);
|
|
8
|
-
const inv = await inventory({ rawArc });
|
|
9
|
-
const cwd = inv.inv._project.cwd;
|
|
6
|
+
export async function resolveResourceDependencies({ resource, transpiled, blueprintFileDir, functionPath, installer, }) {
|
|
7
|
+
const rawArc = await convertResourceToArcFormat(resource, functionPath, transpiled);
|
|
8
|
+
const inv = await inventory({ rawArc, cwd: blueprintFileDir });
|
|
10
9
|
let installType = 'npm';
|
|
11
10
|
if (installer) {
|
|
12
11
|
installType = installer;
|
|
13
12
|
}
|
|
14
|
-
else if (existsSync(join(
|
|
13
|
+
else if (existsSync(join(blueprintFileDir, 'pnpm-lock.yaml'))) {
|
|
15
14
|
installType = 'pnpm';
|
|
16
15
|
}
|
|
17
|
-
else if (existsSync(join(
|
|
16
|
+
else if (existsSync(join(blueprintFileDir, 'yarn.lock'))) {
|
|
18
17
|
installType = 'yarn';
|
|
19
18
|
}
|
|
20
19
|
try {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { FunctionResource } from '../types.js';
|
|
2
|
-
export declare function convertResourceToArcFormat(resource: FunctionResource, transpiled: boolean): Promise<string>;
|
|
2
|
+
export declare function convertResourceToArcFormat(resource: FunctionResource, functionPath: string, transpiled: boolean): Promise<string>;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { stat } from 'node:fs/promises';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export async function convertResourceToArcFormat(resource, transpiled) {
|
|
2
|
+
import { sep } from 'node:path';
|
|
3
|
+
export async function convertResourceToArcFormat(resource, functionPath, transpiled) {
|
|
5
4
|
if (!resource.src) {
|
|
6
5
|
throw Error('Missing `resource.src` property');
|
|
7
6
|
}
|
|
8
7
|
// Get stats from file
|
|
9
|
-
const stats = await stat(
|
|
8
|
+
const stats = await stat(functionPath);
|
|
10
9
|
// Convert resource.src to arc file path format
|
|
11
10
|
const srcPath = resource.src?.split(sep).join('/');
|
|
12
11
|
const entryDir = stats.isFile() ? srcPath.substring(0, srcPath.lastIndexOf('/')) : srcPath;
|
|
13
|
-
|
|
12
|
+
functionPath = transpiled ? `${entryDir}/.build/function-${resource.name}` : entryDir;
|
|
14
13
|
return `@app
|
|
15
14
|
hydrate-function
|
|
16
15
|
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import type { FunctionResource } from '../types.js';
|
|
2
|
-
export
|
|
2
|
+
export type ShouldTranspileResult = {
|
|
3
|
+
transpile: true;
|
|
4
|
+
entryPoint: string;
|
|
5
|
+
} | {
|
|
6
|
+
transpile: false;
|
|
7
|
+
};
|
|
8
|
+
export declare function shouldTranspileFunction(resource: FunctionResource, functionPath: string): Promise<ShouldTranspileResult>;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { findFunctionEntryPoint } from './find-entry-point.js';
|
|
2
|
-
export async function shouldTranspileFunction(resource) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!resource.src) {
|
|
7
|
-
// Cannot determine without a source path
|
|
8
|
-
return false;
|
|
2
|
+
export async function shouldTranspileFunction(resource, functionPath) {
|
|
3
|
+
const hasTranspile = 'transpile' in resource && typeof resource.transpile === 'boolean';
|
|
4
|
+
if (!functionPath || (hasTranspile && resource.transpile === false)) {
|
|
5
|
+
return { transpile: false };
|
|
9
6
|
}
|
|
10
7
|
try {
|
|
11
8
|
// 2. Find the actual entry point
|
|
12
|
-
const entryPoint = await findFunctionEntryPoint(
|
|
9
|
+
const entryPoint = await findFunctionEntryPoint(functionPath, resource.displayName ?? resource.name);
|
|
13
10
|
// 3. Check if the resolved entry point is a TypeScript file
|
|
14
|
-
return
|
|
11
|
+
return {
|
|
12
|
+
entryPoint,
|
|
13
|
+
transpile: hasTranspile ? resource.transpile === true : entryPoint.endsWith('.ts'),
|
|
14
|
+
};
|
|
15
15
|
}
|
|
16
16
|
catch (err) {
|
|
17
17
|
// If we cannot find the entry point, we cannot determine if it's TS.
|
|
18
18
|
// Log a warning and default to false (don't bundle).
|
|
19
19
|
console.warn(`[warn] Could not determine entry point for function "${resource.displayName ?? resource.name}" while checking if transpiling is needed: ${err instanceof Error ? err.message : err}`);
|
|
20
|
-
return false;
|
|
20
|
+
return { transpile: false };
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { FunctionResource, InstallerType } from '../../types.js';
|
|
2
2
|
export declare const resolveViteRoot: (entry: string) => string;
|
|
3
|
-
export declare function transpileFunction(resource
|
|
3
|
+
export declare function transpileFunction({ resource, functionPath, entryPoint, installer, }: {
|
|
4
|
+
resource: FunctionResource;
|
|
5
|
+
functionPath: string;
|
|
6
|
+
entryPoint: string;
|
|
4
7
|
installer?: InstallerType;
|
|
5
8
|
}): Promise<{
|
|
6
9
|
type: string;
|
|
@@ -3,9 +3,9 @@ import path from 'node:path';
|
|
|
3
3
|
import { performance } from 'node:perf_hooks';
|
|
4
4
|
import { cwd } from 'node:process';
|
|
5
5
|
import * as find from 'empathic/find';
|
|
6
|
+
import stripAnsi from 'strip-ansi';
|
|
6
7
|
import { build as viteBuild } from 'vite';
|
|
7
8
|
import { detectNativeModulesPlugin } from '../detect-native-modules.js';
|
|
8
|
-
import { findFunctionEntryPoint } from '../find-entry-point.js';
|
|
9
9
|
import { cleanupSourceMaps } from './cleanup-source-maps.js';
|
|
10
10
|
import { createPnpmRequire } from './pnpm.js';
|
|
11
11
|
import { verifyHandler } from './verify-handler.js';
|
|
@@ -13,23 +13,18 @@ export const resolveViteRoot = (entry) => {
|
|
|
13
13
|
const nodeModulesDir = find.dir('node_modules', { cwd: entry });
|
|
14
14
|
return nodeModulesDir ? path.dirname(nodeModulesDir) : entry;
|
|
15
15
|
};
|
|
16
|
-
export async function transpileFunction(resource,
|
|
16
|
+
export async function transpileFunction({ resource, functionPath, entryPoint, installer, }) {
|
|
17
17
|
if (!resource.src)
|
|
18
18
|
throw new Error('Resource src is required');
|
|
19
19
|
if (!resource.name)
|
|
20
20
|
throw new Error('Resource name is required');
|
|
21
21
|
const timings = {};
|
|
22
22
|
const transpileStart = performance.now();
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const fnDisplayName = resource.displayName ?? resource.name;
|
|
26
|
-
const findEntryStart = performance.now();
|
|
27
|
-
const entry = await findFunctionEntryPoint(sourcePath, fnDisplayName);
|
|
28
|
-
timings['transpile:findEntry'] = performance.now() - findEntryStart;
|
|
29
|
-
const entryDir = stats.isFile() ? path.dirname(sourcePath) : sourcePath;
|
|
23
|
+
const stats = await stat(functionPath);
|
|
24
|
+
const entryDir = stats.isFile() ? path.dirname(functionPath) : functionPath;
|
|
30
25
|
const outputPathStart = performance.now();
|
|
31
26
|
const outputDir = await getTranspileOutputPath(entryDir, resource.name);
|
|
32
|
-
const outputFile = path.join(outputDir, getOutputFilename(
|
|
27
|
+
const outputFile = path.join(outputDir, getOutputFilename(entryPoint));
|
|
33
28
|
const fnRootDir = resolveViteRoot(entryDir);
|
|
34
29
|
timings['transpile:setupOutput'] = performance.now() - outputPathStart;
|
|
35
30
|
async function cleanupTmpDir() {
|
|
@@ -51,10 +46,10 @@ export async function transpileFunction(resource, { installer } = {}) {
|
|
|
51
46
|
sourcemap: true,
|
|
52
47
|
ssr: true,
|
|
53
48
|
rolldownOptions: {
|
|
54
|
-
input:
|
|
49
|
+
input: entryPoint,
|
|
55
50
|
output: {
|
|
56
51
|
format: 'esm',
|
|
57
|
-
entryFileNames: getOutputFilename(
|
|
52
|
+
entryFileNames: getOutputFilename(entryPoint),
|
|
58
53
|
...(bundle
|
|
59
54
|
? {}
|
|
60
55
|
: {
|
|
@@ -86,7 +81,7 @@ export async function transpileFunction(resource, { installer } = {}) {
|
|
|
86
81
|
await writeTranspiledPackageJson(entryDir, outputFile);
|
|
87
82
|
timings['transpile:writePackage'] = performance.now() - pkgStart;
|
|
88
83
|
const cleanupStart = performance.now();
|
|
89
|
-
await cleanupSourceMaps(
|
|
84
|
+
await cleanupSourceMaps(functionPath, outputDir);
|
|
90
85
|
timings['transpile:cleanupMaps'] = performance.now() - cleanupStart;
|
|
91
86
|
timings.bundle = performance.now() - transpileStart;
|
|
92
87
|
return {
|
|
@@ -100,7 +95,7 @@ export async function transpileFunction(resource, { installer } = {}) {
|
|
|
100
95
|
}
|
|
101
96
|
catch (err) {
|
|
102
97
|
await cleanupTmpDir();
|
|
103
|
-
throw new Error(`Transpiling of function failed: ${formatBuildError(err)}`, {
|
|
98
|
+
throw new Error(`Transpiling of function failed: ${stripAnsi(formatBuildError(err))}`, {
|
|
104
99
|
cause: err,
|
|
105
100
|
});
|
|
106
101
|
}
|
|
@@ -4,7 +4,7 @@ export async function verifyHandler(result) {
|
|
|
4
4
|
}
|
|
5
5
|
const outputs = (Array.isArray(result) ? result : [result]).flatMap(({ output }) => output);
|
|
6
6
|
const bundledIndex = outputs.find((output) => output.type === 'chunk' && output.isEntry && output.fileName === 'index.js');
|
|
7
|
-
if (
|
|
7
|
+
if (bundledIndex?.type !== 'chunk') {
|
|
8
8
|
throw new Error('Unexpected build output, no bundled index found');
|
|
9
9
|
}
|
|
10
10
|
if (!bundledIndex.exports.includes('handler')) {
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -6,11 +6,13 @@ export declare function Logger(log: (msg: string) => void, flags?: {
|
|
|
6
6
|
}): {
|
|
7
7
|
(msg: string): void;
|
|
8
8
|
isTraceEnabled: boolean;
|
|
9
|
-
trace(formatter: unknown, ...args: unknown[])
|
|
10
|
-
verbose(formatter: unknown, ...args: unknown[])
|
|
11
|
-
info(formatter: unknown, ...args: unknown[])
|
|
12
|
-
warn(formatter: unknown, ...args: unknown[])
|
|
13
|
-
error(formatter: unknown, ...args: unknown[])
|
|
9
|
+
trace: (formatter: unknown, ...args: unknown[]) => void | false;
|
|
10
|
+
verbose: (formatter: unknown, ...args: unknown[]) => void | false;
|
|
11
|
+
info: (formatter: unknown, ...args: unknown[]) => void | false;
|
|
12
|
+
warn: (formatter: unknown, ...args: unknown[]) => void | false;
|
|
13
|
+
error: (formatter: unknown, ...args: unknown[]) => void | false;
|
|
14
|
+
showProgress: (percent?: number) => void;
|
|
15
|
+
clearProgress: () => void;
|
|
14
16
|
ora: typeof ora;
|
|
15
17
|
};
|
|
16
18
|
export type Logger = ReturnType<typeof Logger>;
|
package/dist/utils/logger.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { format } from 'node:util';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
+
import { clearProgress, showBusy, showError, showProgress } from './progress.js';
|
|
3
4
|
var LogLevel;
|
|
4
5
|
(function (LogLevel) {
|
|
5
6
|
LogLevel[LogLevel["TRACE"] = 0] = "TRACE";
|
|
@@ -19,16 +20,47 @@ export function Logger(log, flags = {}) {
|
|
|
19
20
|
logger.info = (formatter, ...args) => level <= LogLevel.INFO && logger(format(formatter, ...args));
|
|
20
21
|
logger.warn = (formatter, ...args) => level <= LogLevel.WARN && logger(format(formatter, ...args));
|
|
21
22
|
logger.error = (formatter, ...args) => level <= LogLevel.ERROR && logger(format(formatter, ...args));
|
|
23
|
+
logger.showProgress = (percent) => {
|
|
24
|
+
if (flags.json)
|
|
25
|
+
return;
|
|
26
|
+
if (percent === undefined)
|
|
27
|
+
showBusy();
|
|
28
|
+
else
|
|
29
|
+
showProgress(percent);
|
|
30
|
+
};
|
|
31
|
+
logger.clearProgress = () => {
|
|
32
|
+
if (flags.json)
|
|
33
|
+
return;
|
|
34
|
+
clearProgress();
|
|
35
|
+
};
|
|
22
36
|
const oraWrapper = (opts) => {
|
|
23
37
|
if (flags.json)
|
|
24
38
|
return createOraLineLoggingWrapper(opts, logger);
|
|
25
39
|
if (level >= LogLevel.INFO)
|
|
26
|
-
return ora(opts);
|
|
40
|
+
return withTerminalProgress(ora(opts));
|
|
27
41
|
return createOraLineLoggingWrapper(opts, logger);
|
|
28
42
|
};
|
|
29
43
|
logger.ora = oraWrapper;
|
|
30
44
|
return logger;
|
|
31
45
|
}
|
|
46
|
+
function withTerminalProgress(spinner) {
|
|
47
|
+
const wrap = (name, effect) => {
|
|
48
|
+
if (typeof spinner[name] !== 'function')
|
|
49
|
+
return;
|
|
50
|
+
const original = spinner[name].bind(spinner);
|
|
51
|
+
spinner[name] = (...args) => {
|
|
52
|
+
const result = original(...args);
|
|
53
|
+
effect();
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
wrap('start', showBusy);
|
|
58
|
+
wrap('fail', showError);
|
|
59
|
+
for (const name of ['stop', 'succeed', 'warn', 'info', 'stopAndPersist']) {
|
|
60
|
+
wrap(name, clearProgress);
|
|
61
|
+
}
|
|
62
|
+
return spinner;
|
|
63
|
+
}
|
|
32
64
|
/**
|
|
33
65
|
* An ora-like wrapper that uses standard line output logging instead of rendering a spinner; used in verbose and trace modes.
|
|
34
66
|
*/
|