@superblocksteam/sdk 2.0.6-next.98 → 2.0.6
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/application-build.mjs +2 -6
- package/dist/application-build.mjs.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.d.ts +2 -5
- package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.js +93 -221
- package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
- package/dist/cli-replacement/dev.d.mts +2 -1
- package/dist/cli-replacement/dev.d.mts.map +1 -1
- package/dist/cli-replacement/dev.mjs +32 -57
- package/dist/cli-replacement/dev.mjs.map +1 -1
- package/dist/client.d.ts +0 -34
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -92
- package/dist/client.js.map +1 -1
- package/dist/dev-utils/dev-logger.d.mts +7 -17
- package/dist/dev-utils/dev-logger.d.mts.map +1 -1
- package/dist/dev-utils/dev-logger.mjs +9 -50
- package/dist/dev-utils/dev-logger.mjs.map +1 -1
- package/dist/dev-utils/dev-server.d.mts.map +1 -1
- package/dist/dev-utils/dev-server.mjs +12 -8
- package/dist/dev-utils/dev-server.mjs.map +1 -1
- package/dist/dev-utils/dev-tracer.d.ts +0 -2
- package/dist/dev-utils/dev-tracer.d.ts.map +1 -1
- package/dist/dev-utils/dev-tracer.js +35 -42
- package/dist/dev-utils/dev-tracer.js.map +1 -1
- package/dist/dev-utils/vite-plugin-sb-cdn.d.mts.map +1 -1
- package/dist/dev-utils/vite-plugin-sb-cdn.mjs +3 -13
- package/dist/dev-utils/vite-plugin-sb-cdn.mjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/vite-plugin-inject-sb-ids-transform.mjs +1 -1
- package/dist/vite-plugin-inject-sb-ids-transform.mjs.map +1 -1
- package/package.json +4 -6
- package/src/application-build.mts +3 -6
- package/src/cli-replacement/automatic-upgrades.ts +113 -278
- package/src/cli-replacement/dev.mts +43 -77
- package/src/client.ts +0 -115
- package/src/dev-utils/dev-logger.mts +20 -94
- package/src/dev-utils/dev-server.mts +12 -10
- package/src/dev-utils/dev-tracer.ts +37 -48
- package/src/dev-utils/vite-plugin-sb-cdn.mts +3 -14
- package/src/index.ts +0 -4
- package/src/vite-plugin-inject-sb-ids-transform.mts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts +0 -10
- package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts.map +0 -1
- package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs +0 -27
- package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs.map +0 -1
- package/dist/vite-plugin-generate-build-manifest.d.mts +0 -21
- package/dist/vite-plugin-generate-build-manifest.d.mts.map +0 -1
- package/dist/vite-plugin-generate-build-manifest.mjs +0 -131
- package/dist/vite-plugin-generate-build-manifest.mjs.map +0 -1
- package/src/dev-utils/vite-plugin-build-manifest-stub.mts +0 -30
- package/src/vite-plugin-generate-build-manifest.mts +0 -193
- package/test/clients.test.mts +0 -120
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "../dev-utils/dev-tracer.js";
|
|
2
2
|
|
|
3
3
|
import * as child_process from "node:child_process";
|
|
4
|
+
import * as fsp from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { promisify } from "node:util";
|
|
6
7
|
import { maskUnixSignals } from "@superblocksteam/util";
|
|
@@ -17,16 +18,15 @@ import fs from "fs-extra";
|
|
|
17
18
|
import { resolveCommand } from "package-manager-detector";
|
|
18
19
|
import { detect } from "package-manager-detector/detect";
|
|
19
20
|
|
|
20
|
-
import {
|
|
21
|
+
import { getLogger } from "../dev-utils/dev-logger.mjs";
|
|
21
22
|
import { createDevServer } from "../dev-utils/dev-server.mjs";
|
|
22
|
-
import tracer
|
|
23
|
+
import tracer from "../dev-utils/dev-tracer.js";
|
|
23
24
|
import { SuperblocksSdk } from "../sdk.js";
|
|
24
25
|
import {
|
|
25
26
|
checkVersionsAndUpgrade,
|
|
26
27
|
getCurrentCliVersion,
|
|
27
28
|
getCurrentLibraryVersionWithoutPM,
|
|
28
29
|
} from "./automatic-upgrades.js";
|
|
29
|
-
import { AUTO_UPGRADE_EXIT_CODE } from "./automatic-upgrades.js";
|
|
30
30
|
import type { DevLogger } from "../dev-utils/dev-logger.mjs";
|
|
31
31
|
import type { ApplicationConfig } from "../types/common.js";
|
|
32
32
|
import type { DraftInterface } from "@superblocksteam/vite-plugin-file-sync/draft-interface";
|
|
@@ -93,6 +93,7 @@ async function installPackages(cwd: string, logger: DevLogger) {
|
|
|
93
93
|
export async function dev(options: {
|
|
94
94
|
/* cwd is required */
|
|
95
95
|
cwd: string;
|
|
96
|
+
pidfilePath?: string;
|
|
96
97
|
devServerPort?: number;
|
|
97
98
|
|
|
98
99
|
/* user control of sync operations */
|
|
@@ -106,7 +107,7 @@ export async function dev(options: {
|
|
|
106
107
|
/* For debugging purposes to get location of the cli */
|
|
107
108
|
superblocksPath?: string;
|
|
108
109
|
/* For redirecting output, like when running outside of the CLI */
|
|
109
|
-
logger?: (
|
|
110
|
+
logger?: (message: string) => void;
|
|
110
111
|
|
|
111
112
|
/* For a child process when restarting the dev server for automatic upgrades */
|
|
112
113
|
skipAutoUpgrade?: boolean;
|
|
@@ -118,6 +119,7 @@ export async function dev(options: {
|
|
|
118
119
|
|
|
119
120
|
const {
|
|
120
121
|
cwd,
|
|
122
|
+
pidfilePath,
|
|
121
123
|
devServerPort,
|
|
122
124
|
downloadFirst,
|
|
123
125
|
uploadFirst,
|
|
@@ -125,7 +127,12 @@ export async function dev(options: {
|
|
|
125
127
|
applicationConfig,
|
|
126
128
|
skipAutoUpgrade,
|
|
127
129
|
} = options;
|
|
128
|
-
|
|
130
|
+
|
|
131
|
+
const cliVersion = await getCurrentCliVersion();
|
|
132
|
+
const libraryVersion = await getCurrentLibraryVersionWithoutPM();
|
|
133
|
+
logger.info(
|
|
134
|
+
`Running command: ${options.superblocksPath} dev${options.uploadFirst ? " --upload-first" : ""}${options.downloadFirst ? " --download-first" : ""} with baseUrl: ${applicationConfig?.superblocksBaseUrl}, cliVersion: ${cliVersion}, libraryVersion: ${libraryVersion?.alias} ${libraryVersion?.version}`,
|
|
135
|
+
);
|
|
129
136
|
|
|
130
137
|
// Add check for node_modules
|
|
131
138
|
if (!fs.existsSync(path.join(cwd, "node_modules"))) {
|
|
@@ -134,13 +141,9 @@ export async function dev(options: {
|
|
|
134
141
|
);
|
|
135
142
|
}
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const libraryVersion = await getCurrentLibraryVersionWithoutPM();
|
|
141
|
-
logger.info(
|
|
142
|
-
`Running command: ${options.superblocksPath} dev${options.uploadFirst ? " --upload-first" : ""}${options.downloadFirst ? " --download-first" : ""} with baseUrl: ${applicationConfig?.superblocksBaseUrl}, cliVersion: ${cliVersion?.alias} ${cliVersion?.version}, libraryVersion: ${libraryVersion?.alias} ${libraryVersion?.version}`,
|
|
143
|
-
);
|
|
144
|
+
if (pidfilePath) {
|
|
145
|
+
await fsp.writeFile(pidfilePath, `${process.pid}\n`);
|
|
146
|
+
}
|
|
144
147
|
|
|
145
148
|
const port = devServerPort ?? 5173;
|
|
146
149
|
|
|
@@ -185,11 +188,17 @@ export async function dev(options: {
|
|
|
185
188
|
if (lockService) {
|
|
186
189
|
try {
|
|
187
190
|
await lockService!.acquireLock();
|
|
191
|
+
|
|
192
|
+
// TODO(code-mode): package naming is preventing upgrade in ephemeral environments
|
|
193
|
+
if (
|
|
194
|
+
!process.env.PACKAGE_SUFFIX ||
|
|
195
|
+
process.env.PACKAGE_SUFFIX === "" ||
|
|
196
|
+
!skipAutoUpgrade
|
|
197
|
+
) {
|
|
198
|
+
await checkVersionsAndUpgrade(lockService, applicationConfig);
|
|
199
|
+
}
|
|
188
200
|
} catch (error) {
|
|
189
|
-
logger.error(
|
|
190
|
-
"Failed to acquire lock on application",
|
|
191
|
-
getErrorMeta(error),
|
|
192
|
-
);
|
|
201
|
+
logger.error("Failed to acquire lock on application", error);
|
|
193
202
|
passErrorToVSCode(
|
|
194
203
|
(error as { context?: { message: string } }).context?.message,
|
|
195
204
|
logger,
|
|
@@ -213,6 +222,7 @@ export async function dev(options: {
|
|
|
213
222
|
appRootDirPath: options.cwd,
|
|
214
223
|
applicationId: applicationConfig.id,
|
|
215
224
|
organizationId: currentUser.organizations[0].id,
|
|
225
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY || "",
|
|
216
226
|
fsOperationQueue,
|
|
217
227
|
draftInterface: syncService! as DraftInterface,
|
|
218
228
|
tracer,
|
|
@@ -221,15 +231,12 @@ export async function dev(options: {
|
|
|
221
231
|
const isSynced = localContents.hash === serverHash;
|
|
222
232
|
|
|
223
233
|
if (isSynced) {
|
|
224
|
-
logger.info(
|
|
225
|
-
|
|
226
|
-
);
|
|
227
|
-
} else {
|
|
228
|
-
logger.info(
|
|
229
|
-
`Local files are out of sync with the server on branch '${applicationConfig.branchName}'`,
|
|
230
|
-
);
|
|
234
|
+
logger.info("Local files are in sync with the server");
|
|
235
|
+
return;
|
|
231
236
|
}
|
|
232
237
|
|
|
238
|
+
logger.info("Local files are out of sync with the server");
|
|
239
|
+
|
|
233
240
|
if (!(downloadFirst || uploadFirst)) {
|
|
234
241
|
throw new Error(
|
|
235
242
|
"You must choose --download-first or --upload-first to use the dev command",
|
|
@@ -239,74 +246,37 @@ export async function dev(options: {
|
|
|
239
246
|
throw new Error("Choose either --download-first or --upload-first");
|
|
240
247
|
}
|
|
241
248
|
|
|
242
|
-
let hasPackageChanged = false;
|
|
243
|
-
|
|
244
249
|
if (downloadFirst) {
|
|
245
250
|
logger.info(
|
|
246
|
-
|
|
251
|
+
"Starting directory sync from server before starting the local server",
|
|
247
252
|
);
|
|
248
253
|
|
|
254
|
+
// Read package.json before download
|
|
249
255
|
const packageJsonBefore = await readPkgJson(cwd);
|
|
256
|
+
|
|
250
257
|
await syncService!.downloadDirectory();
|
|
258
|
+
|
|
259
|
+
// Read package.json after download and compare
|
|
251
260
|
const packageJsonAfter = await readPkgJson(cwd);
|
|
252
261
|
|
|
262
|
+
// Check if package.json changed
|
|
253
263
|
if (packageJsonBefore && packageJsonAfter) {
|
|
254
264
|
const diff = diffJson(packageJsonBefore, packageJsonAfter);
|
|
255
|
-
|
|
256
|
-
} else if (packageJsonAfter) {
|
|
257
|
-
hasPackageChanged = true;
|
|
258
|
-
logger.info("package.json was created, installing packages…");
|
|
259
|
-
}
|
|
260
|
-
}
|
|
265
|
+
const hasChanges = diff.some((part) => part.added || part.removed);
|
|
261
266
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
process.env.PACKAGE_SUFFIX === "" ||
|
|
266
|
-
!skipAutoUpgrade
|
|
267
|
-
) {
|
|
268
|
-
if (lockService) {
|
|
269
|
-
const result = await checkVersionsAndUpgrade(
|
|
270
|
-
lockService,
|
|
271
|
-
applicationConfig,
|
|
272
|
-
);
|
|
273
|
-
if (result?.libraryUpdated) {
|
|
274
|
-
hasPackageChanged = true;
|
|
267
|
+
if (hasChanges) {
|
|
268
|
+
logger.info("package.json has changed, installing packages…");
|
|
269
|
+
await installPackages(cwd, logger);
|
|
275
270
|
}
|
|
276
|
-
hasCliUpdated = result?.cliUpdated ?? false;
|
|
277
|
-
} else {
|
|
278
|
-
logger.warn(
|
|
279
|
-
"Lock service is not available, skipping version check and upgrade",
|
|
280
|
-
);
|
|
281
271
|
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (hasPackageChanged) {
|
|
285
|
-
logger.info("Installing packages…");
|
|
286
|
-
await installPackages(cwd, logger);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (hasPackageChanged || uploadFirst) {
|
|
290
|
-
logger.info(
|
|
291
|
-
`Uploading local files to branch '${applicationConfig.branchName}' on server before starting`,
|
|
292
|
-
);
|
|
272
|
+
} else if (uploadFirst) {
|
|
273
|
+
logger.info("Uploading local files to server before starting");
|
|
293
274
|
await syncService!.uploadDirectory();
|
|
294
|
-
await syncService!.uploadDirectoryNowIfNeeded();
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (hasCliUpdated) {
|
|
298
|
-
logger.info("CLI was updated, restarting the dev server…");
|
|
299
|
-
process.exit(AUTO_UPGRADE_EXIT_CODE);
|
|
300
275
|
}
|
|
301
276
|
});
|
|
302
277
|
} catch (error: any) {
|
|
303
278
|
logger.error(error.message);
|
|
304
|
-
|
|
305
|
-
await lockService?.shutdownAndExit();
|
|
306
|
-
} finally {
|
|
307
|
-
// this is redundant, but it's here to make sure the lock service is shutdown and the process exits
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
279
|
+
process.exit(1);
|
|
310
280
|
}
|
|
311
281
|
} else {
|
|
312
282
|
logger.info("Skipping directory sync");
|
|
@@ -326,10 +296,6 @@ export async function dev(options: {
|
|
|
326
296
|
options.signal?.addEventListener("abort", () => {
|
|
327
297
|
logger.info("Server closed");
|
|
328
298
|
httpServer.close();
|
|
329
|
-
lockService?.shutdownAndExit().catch(() => {
|
|
330
|
-
// this is redundant, but it's here to make sure the lock service is shutdown and the process exits
|
|
331
|
-
process.exit(1);
|
|
332
|
-
});
|
|
333
299
|
});
|
|
334
300
|
|
|
335
301
|
logger.debug(green(`Local server started at port ${port}`));
|
package/src/client.ts
CHANGED
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
NotFoundError,
|
|
12
12
|
BadRequestError,
|
|
13
13
|
unreachable,
|
|
14
|
-
getSuperblocksDevEnvironmentConfigJson,
|
|
15
14
|
} from "@superblocksteam/util";
|
|
16
15
|
import axios, { AxiosError } from "axios";
|
|
17
16
|
import FormData from "form-data";
|
|
@@ -25,10 +24,6 @@ import { signingEnabled } from "./flag.js";
|
|
|
25
24
|
import { connectToISocketRPCServer } from "./socket/index.js";
|
|
26
25
|
import { AgentType } from "./types/index.js";
|
|
27
26
|
import { getAgentUrl } from "./utils.js";
|
|
28
|
-
import {
|
|
29
|
-
DEFAULT_BRANCH,
|
|
30
|
-
getCurrentGitBranchIfGit,
|
|
31
|
-
} from "./version-control.mjs";
|
|
32
27
|
import type { StdISocketRPCClient } from "./socket/index.js";
|
|
33
28
|
import type {
|
|
34
29
|
ApiWithPb,
|
|
@@ -138,116 +133,6 @@ enum ResourceType {
|
|
|
138
133
|
BACKEND = "BACKEND",
|
|
139
134
|
}
|
|
140
135
|
|
|
141
|
-
export enum BranchSource {
|
|
142
|
-
DEV_ENVIRONMENT = "dev environment config file",
|
|
143
|
-
COMMAND_LINE = "command line",
|
|
144
|
-
GIT_REPO = "current git repository",
|
|
145
|
-
DEFAULT = "default",
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export class CurrentBranch {
|
|
149
|
-
public readonly branchName: string;
|
|
150
|
-
public readonly source: BranchSource;
|
|
151
|
-
public readonly sourcePath?: string;
|
|
152
|
-
public readonly userSpecifiedBranch?: string;
|
|
153
|
-
|
|
154
|
-
constructor({
|
|
155
|
-
branchName,
|
|
156
|
-
source,
|
|
157
|
-
sourcePath,
|
|
158
|
-
userSpecifiedBranch,
|
|
159
|
-
}: {
|
|
160
|
-
branchName: string;
|
|
161
|
-
source: BranchSource;
|
|
162
|
-
sourcePath?: string;
|
|
163
|
-
userSpecifiedBranch?: string;
|
|
164
|
-
}) {
|
|
165
|
-
this.branchName = branchName;
|
|
166
|
-
this.source = source;
|
|
167
|
-
this.sourcePath = sourcePath;
|
|
168
|
-
this.userSpecifiedBranch = userSpecifiedBranch;
|
|
169
|
-
}
|
|
170
|
-
isDevEnvironmentWithUserSpecifiedBranch() {
|
|
171
|
-
return (
|
|
172
|
-
this.isDefinedInDevEnvironmentConfig() &&
|
|
173
|
-
this.userSpecifiedBranch !== undefined
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
isDefinedInDevEnvironmentConfig(): boolean {
|
|
177
|
-
return this.source === BranchSource.DEV_ENVIRONMENT;
|
|
178
|
-
}
|
|
179
|
-
isDefaultBranch(): boolean {
|
|
180
|
-
return this.source === BranchSource.DEFAULT;
|
|
181
|
-
}
|
|
182
|
-
isGitBranch(): boolean {
|
|
183
|
-
return this.source === BranchSource.GIT_REPO;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const DEFAULT_BRANCH_INFO = new CurrentBranch({
|
|
188
|
-
branchName: DEFAULT_BRANCH,
|
|
189
|
-
source: BranchSource.DEFAULT,
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// TODO (randall): Remove this and the 'index.ts' export when it is no longer needed in the CLI.
|
|
193
|
-
export function getDefaultBranchInfo(): CurrentBranch {
|
|
194
|
-
return DEFAULT_BRANCH_INFO;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Returns the current branch name, in the following order of precedence:
|
|
199
|
-
* 1. If a branch name is specified in the dev environment config, use that
|
|
200
|
-
* 2. If a branch name is specified, use that
|
|
201
|
-
* 3. If this is in a git repo, use the current branch
|
|
202
|
-
* 4. If this is not in a git repo, use the default branch
|
|
203
|
-
* @param userSpecifiedBranch - The branch name specified by the user
|
|
204
|
-
* @param pathPrefix - The path prefix to use when looking for the dev environment config
|
|
205
|
-
* @returns The current branch information
|
|
206
|
-
*/
|
|
207
|
-
export async function getCurrentBranchInfo(
|
|
208
|
-
userSpecifiedBranch?: string,
|
|
209
|
-
pathPrefix?: string,
|
|
210
|
-
): Promise<CurrentBranch> {
|
|
211
|
-
// First, if there is a dev environment config and a branch name is specified, use that
|
|
212
|
-
try {
|
|
213
|
-
const [devEnvironmentConfig, devEnvConfigPath] =
|
|
214
|
-
await getSuperblocksDevEnvironmentConfigJson(true, pathPrefix);
|
|
215
|
-
if (devEnvironmentConfig.branch) {
|
|
216
|
-
return new CurrentBranch({
|
|
217
|
-
branchName: devEnvironmentConfig.branch,
|
|
218
|
-
source: BranchSource.DEV_ENVIRONMENT,
|
|
219
|
-
sourcePath: devEnvConfigPath,
|
|
220
|
-
userSpecifiedBranch: userSpecifiedBranch,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
} catch {
|
|
224
|
-
// Did not find or could not parse the dev environment config, so continue
|
|
225
|
-
}
|
|
226
|
-
// Second, if the user specified a branch name, use that
|
|
227
|
-
if (userSpecifiedBranch) {
|
|
228
|
-
return new CurrentBranch({
|
|
229
|
-
branchName: userSpecifiedBranch,
|
|
230
|
-
source: BranchSource.COMMAND_LINE,
|
|
231
|
-
userSpecifiedBranch: userSpecifiedBranch,
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
// Third, if this is in a git repo, use the current branch
|
|
235
|
-
const currentGitBranch = await getCurrentGitBranchIfGit();
|
|
236
|
-
if (currentGitBranch) {
|
|
237
|
-
return new CurrentBranch({
|
|
238
|
-
branchName: currentGitBranch,
|
|
239
|
-
source: BranchSource.GIT_REPO,
|
|
240
|
-
userSpecifiedBranch: userSpecifiedBranch,
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
// Fourth, if this is not in a git repo, use the default branch
|
|
244
|
-
return new CurrentBranch({
|
|
245
|
-
branchName: DEFAULT_BRANCH,
|
|
246
|
-
source: BranchSource.DEFAULT,
|
|
247
|
-
userSpecifiedBranch: userSpecifiedBranch,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
|
|
251
136
|
export async function fetchApplication({
|
|
252
137
|
cliVersion,
|
|
253
138
|
applicationId,
|
|
@@ -1,113 +1,39 @@
|
|
|
1
1
|
import { createLogger, format, transports } from "winston";
|
|
2
|
-
import type winston from "winston";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
filename: `/tmp/dev-server.log`,
|
|
11
|
-
level: "info",
|
|
12
|
-
}),
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
activeTransports.push(
|
|
17
|
-
new transports.Console({
|
|
18
|
-
format: format.combine(
|
|
19
|
-
format.colorize(),
|
|
20
|
-
format.timestamp({
|
|
21
|
-
format: "HH:mm:ss.SSS",
|
|
22
|
-
}),
|
|
23
|
-
format.printf((props) => {
|
|
24
|
-
const { message, timestamp, error, level } = props;
|
|
25
|
-
const base =
|
|
26
|
-
process.env.SUPERBLOCKS_IS_CSB === "true"
|
|
27
|
-
? `${timestamp} ${message}`
|
|
28
|
-
: `${message}`;
|
|
29
|
-
if (level === "error") {
|
|
30
|
-
return `${base} ${(error as ErrorMeta["error"]).message} ${(error as ErrorMeta["error"]).stack}`;
|
|
31
|
-
}
|
|
32
|
-
return base;
|
|
33
|
-
}),
|
|
34
|
-
),
|
|
35
|
-
}),
|
|
36
|
-
);
|
|
3
|
+
export type DevLogger = {
|
|
4
|
+
debug: (message: string, ...meta: any[]) => void;
|
|
5
|
+
info: (message: string, ...meta: any[]) => void;
|
|
6
|
+
warn: (message: string, ...meta: any[]) => void;
|
|
7
|
+
error: (message: string, ...meta: any[]) => void;
|
|
8
|
+
};
|
|
37
9
|
|
|
38
10
|
const winstonLogger = createLogger({
|
|
39
|
-
level: "
|
|
11
|
+
level: "info",
|
|
40
12
|
exitOnError: false,
|
|
41
13
|
format: format.json(),
|
|
42
|
-
transports:
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export interface DevLogger {
|
|
54
|
-
log: (...messages: string[]) => void;
|
|
55
|
-
debug: (...messages: string[]) => void;
|
|
56
|
-
info: (...messages: string[]) => void;
|
|
57
|
-
warn: (...messages: string[]) => void;
|
|
58
|
-
error: (message: string, meta?: ErrorMeta) => void;
|
|
59
|
-
}
|
|
60
|
-
const logger: DevLogger = Object.freeze({
|
|
61
|
-
debug: (...messages: string[]) =>
|
|
62
|
-
winstonLogger.debug(
|
|
63
|
-
messages.length > 0 ? messages.join(" ") : (messages[0] as string),
|
|
64
|
-
),
|
|
65
|
-
log: (...messages: string[]) =>
|
|
66
|
-
winstonLogger.info(
|
|
67
|
-
messages.length > 0 ? messages.join(" ") : (messages[0] as string),
|
|
68
|
-
),
|
|
69
|
-
info: (...messages: string[]) =>
|
|
70
|
-
winstonLogger.info(
|
|
71
|
-
messages.length > 0 ? messages.join(" ") : (messages[0] as string),
|
|
72
|
-
),
|
|
73
|
-
warn: (...messages: string[]) =>
|
|
74
|
-
winstonLogger.warn(
|
|
75
|
-
messages.length > 0 ? messages.join(" ") : (messages[0] as string),
|
|
76
|
-
),
|
|
77
|
-
error: (message: string, meta?: ErrorMeta) =>
|
|
78
|
-
winstonLogger.error(message, meta),
|
|
14
|
+
transports: [
|
|
15
|
+
new transports.File({ filename: `/tmp/dev-server.log`, level: "info" }),
|
|
16
|
+
new transports.Console({
|
|
17
|
+
format: format.combine(
|
|
18
|
+
format.printf(({ message }) => `${message}`),
|
|
19
|
+
format.colorize({ message: true }),
|
|
20
|
+
),
|
|
21
|
+
level: "debug",
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
79
24
|
});
|
|
80
25
|
|
|
81
26
|
export function getLogger(
|
|
82
|
-
loggerOverride?: (
|
|
27
|
+
loggerOverride?: (message: string) => void,
|
|
83
28
|
): DevLogger {
|
|
84
29
|
if (!loggerOverride) {
|
|
85
|
-
return
|
|
30
|
+
return winstonLogger;
|
|
86
31
|
}
|
|
87
32
|
|
|
88
33
|
return {
|
|
89
34
|
debug: loggerOverride,
|
|
90
35
|
info: loggerOverride,
|
|
91
36
|
warn: loggerOverride,
|
|
92
|
-
|
|
93
|
-
error: loggerOverride as any,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function getErrorMeta(error: unknown): ErrorMeta {
|
|
98
|
-
if (error instanceof Error) {
|
|
99
|
-
return {
|
|
100
|
-
error: {
|
|
101
|
-
kind: error.name,
|
|
102
|
-
message: error.message,
|
|
103
|
-
stack: error.stack,
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
error: {
|
|
109
|
-
kind: "Unknown Error",
|
|
110
|
-
message: JSON.stringify(error),
|
|
111
|
-
},
|
|
37
|
+
error: loggerOverride,
|
|
112
38
|
};
|
|
113
39
|
}
|
|
@@ -18,8 +18,7 @@ import {
|
|
|
18
18
|
customComponentsPlugin,
|
|
19
19
|
isCustomComponentsEnabled,
|
|
20
20
|
} from "./custom-build.mjs";
|
|
21
|
-
import {
|
|
22
|
-
import { buildManifestStubPlugin } from "./vite-plugin-build-manifest-stub.mjs";
|
|
21
|
+
import { getLogger } from "./dev-logger.mjs";
|
|
23
22
|
import { ddRumPlugin } from "./vite-plugin-dd-rum.mjs";
|
|
24
23
|
import { superblocksCdnPlugin } from "./vite-plugin-sb-cdn.mjs";
|
|
25
24
|
import type { AiService } from "@superblocksteam/vite-plugin-file-sync/ai-service";
|
|
@@ -188,6 +187,13 @@ export async function createDevServer({
|
|
|
188
187
|
}, viteReject);
|
|
189
188
|
});
|
|
190
189
|
|
|
190
|
+
// TODO(code-mode): remove this soon
|
|
191
|
+
app.get("/_sb_disconnect", async (_req, res) => {
|
|
192
|
+
console.log("GET /_sb_disconnect");
|
|
193
|
+
// TODO(code-mode): should this include any validation checks, such as getting a token?
|
|
194
|
+
await gracefulShutdown({ logger, serverInitiated: false });
|
|
195
|
+
res.send("ok");
|
|
196
|
+
});
|
|
191
197
|
app.post("/_sb_disconnect", async (req, res) => {
|
|
192
198
|
const { initiatedByEmail, switchingTo } = req.body;
|
|
193
199
|
// TODO(code-mode): should this include any validation checks, such as getting a token?
|
|
@@ -200,7 +206,7 @@ export async function createDevServer({
|
|
|
200
206
|
});
|
|
201
207
|
res.send("ok");
|
|
202
208
|
} catch (e) {
|
|
203
|
-
|
|
209
|
+
console.error("Error disconnecting from dev server", e);
|
|
204
210
|
res.status(500).send("Error disconnecting from dev server");
|
|
205
211
|
}
|
|
206
212
|
});
|
|
@@ -254,7 +260,7 @@ async function startVite({
|
|
|
254
260
|
}) {
|
|
255
261
|
const viteLogger = createLogger();
|
|
256
262
|
const logger = getLogger(loggerOverride);
|
|
257
|
-
viteLogger.info =
|
|
263
|
+
viteLogger.info = logger.info;
|
|
258
264
|
viteLogger.warn = (msg: string) => {
|
|
259
265
|
logger.warn(yellow(msg));
|
|
260
266
|
};
|
|
@@ -270,8 +276,6 @@ async function startVite({
|
|
|
270
276
|
const isCustomBuildEnabled = await isCustomComponentsEnabled();
|
|
271
277
|
const customFolder = path.join(root, "custom");
|
|
272
278
|
|
|
273
|
-
const draftsFolder = path.join(root, ".superblocks");
|
|
274
|
-
|
|
275
279
|
const cdnUrl = process.env.SUPERBLOCKS_CDN_URL ?? "http://localhost:4040/cdn";
|
|
276
280
|
|
|
277
281
|
const env = loadEnv(mode, root, "");
|
|
@@ -309,7 +313,7 @@ async function startVite({
|
|
|
309
313
|
server: {
|
|
310
314
|
middlewareMode: true,
|
|
311
315
|
watch: {
|
|
312
|
-
ignored: [`${customFolder}
|
|
316
|
+
ignored: [`${customFolder}/**/*`],
|
|
313
317
|
},
|
|
314
318
|
hmr: hmrOptions,
|
|
315
319
|
cors: {
|
|
@@ -338,13 +342,11 @@ async function startVite({
|
|
|
338
342
|
aiService,
|
|
339
343
|
httpServer,
|
|
340
344
|
tracer,
|
|
345
|
+
logger,
|
|
341
346
|
},
|
|
342
347
|
{ isCustomBuildEnabled },
|
|
343
348
|
) as Plugin,
|
|
344
349
|
|
|
345
|
-
// Add a virtual "stub" module for the build manifest
|
|
346
|
-
buildManifestStubPlugin(),
|
|
347
|
-
|
|
348
350
|
// for now, only use the CDN locally
|
|
349
351
|
superblocksCdnPlugin({
|
|
350
352
|
imports: {
|
|
@@ -6,13 +6,8 @@ import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
|
|
6
6
|
import { Resource } from "@opentelemetry/resources";
|
|
7
7
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
8
8
|
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
9
|
-
import {
|
|
10
|
-
OBS_TAG_APPLICATION_ID,
|
|
11
|
-
OBS_TAG_BRANCH,
|
|
12
|
-
} from "@superblocksteam/shared";
|
|
13
9
|
import { getLocalTokenWithUrl } from "@superblocksteam/util";
|
|
14
10
|
import packageJson from "../../package.json" with { type: "json" };
|
|
15
|
-
import type { ApplicationConfig } from "../types/index.js";
|
|
16
11
|
import type { Span } from "@opentelemetry/api";
|
|
17
12
|
|
|
18
13
|
// NOTE: @joeyagreco - this is how the "env" facet is determined in datadog: https://docs.datadoghq.com/opentelemetry/setup/collector_exporter/#3---configure-your-application
|
|
@@ -20,7 +15,6 @@ const ATTR_DEPLOYMENT_ENVIRONMENT = "deployment.environment";
|
|
|
20
15
|
// NOTE: @joeyagreco - this can be used to determine if we are using mock-csb, staging-csb, prod-csb, etc
|
|
21
16
|
const ATTR_SUPERBLOCKS_BASE_URL = "superblocks.base_url";
|
|
22
17
|
const ATTR_SUPERBLOCKS_CLI_TOKEN = "superblocks.cli_token";
|
|
23
|
-
const ATTR_SUPERBLOCKS_IS_CSB = "superblocks.is_csb";
|
|
24
18
|
let superblocksTracesUrl = undefined;
|
|
25
19
|
let superblocksHostname = "unknown";
|
|
26
20
|
let token = "unknown";
|
|
@@ -36,50 +30,45 @@ try {
|
|
|
36
30
|
console.error("[tracing init] could not determine superblocks base url", e);
|
|
37
31
|
}
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
[ATTR_SUPERBLOCKS_CLI_TOKEN]: token,
|
|
48
|
-
[OBS_TAG_APPLICATION_ID]: applicationConfig?.id,
|
|
49
|
-
[OBS_TAG_BRANCH]: applicationConfig?.branchName,
|
|
50
|
-
[ATTR_SUPERBLOCKS_IS_CSB]: process.env.SUPERBLOCKS_IS_CSB,
|
|
51
|
-
}),
|
|
52
|
-
),
|
|
53
|
-
traceExporter: new OTLPTraceExporter({
|
|
54
|
-
url: superblocksTracesUrl, // OTLPTraceExporter defaults to sending traffic to http://localhost:4318/v1/traces
|
|
33
|
+
// Initialize the OpenTelemetry SDK
|
|
34
|
+
const sdk = new NodeSDK({
|
|
35
|
+
resource: Resource.default().merge(
|
|
36
|
+
new Resource({
|
|
37
|
+
[ATTR_SERVICE_NAME]: "sdk-dev-server",
|
|
38
|
+
[ATTR_DEPLOYMENT_ENVIRONMENT]: process.env.SUPERBLOCKS_CLI_ENV,
|
|
39
|
+
[ATTR_SUPERBLOCKS_BASE_URL]: superblocksHostname,
|
|
40
|
+
[ATTR_SUPERBLOCKS_CLI_TOKEN]: token,
|
|
55
41
|
}),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
42
|
+
),
|
|
43
|
+
traceExporter: new OTLPTraceExporter({
|
|
44
|
+
url: superblocksTracesUrl, // OTLPTraceExporter defaults to sending traffic to http://localhost:4318/v1/traces
|
|
45
|
+
}),
|
|
46
|
+
contextManager: new AsyncLocalStorageContextManager(),
|
|
47
|
+
instrumentations: [
|
|
48
|
+
// Configure HTTP instrumentation with custom attributes
|
|
49
|
+
new HttpInstrumentation({
|
|
50
|
+
requestHook: (span: Span, request: any) => {
|
|
51
|
+
let resource = "GET";
|
|
52
|
+
if (request) {
|
|
53
|
+
resource = `${request.method} ${request.url || request.path}`;
|
|
54
|
+
}
|
|
55
|
+
span.setAttributes({
|
|
56
|
+
"resource.name": resource,
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
// Configure Express instrumentation
|
|
61
|
+
new ExpressInstrumentation({
|
|
62
|
+
requestHook: (span: Span, request: any) => {
|
|
63
|
+
span.setAttributes({
|
|
64
|
+
"resource.name": `${request.method} ${request.url}`,
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
});
|
|
80
70
|
|
|
81
|
-
|
|
82
|
-
};
|
|
71
|
+
sdk.start();
|
|
83
72
|
|
|
84
73
|
// Get a tracer instance
|
|
85
74
|
const tracer = trace.getTracer("sdk-dev-server", packageJson.version);
|