@hs-x/cli 0.3.6 → 0.4.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 +126 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +58 -59
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/kit.d.ts.map +1 -1
- package/dist/cli/kit.js +1 -1
- package/dist/cli/kit.js.map +1 -1
- package/dist/cloudflare-auth.d.ts +19 -0
- package/dist/cloudflare-auth.d.ts.map +1 -1
- package/dist/cloudflare-auth.js +83 -2
- package/dist/cloudflare-auth.js.map +1 -1
- package/dist/cloudflare-oauth.d.ts.map +1 -1
- package/dist/cloudflare-oauth.js +18 -19
- package/dist/cloudflare-oauth.js.map +1 -1
- package/dist/cloudflare-scoped-resource.d.ts +41 -0
- package/dist/cloudflare-scoped-resource.d.ts.map +1 -0
- package/dist/cloudflare-scoped-resource.js +74 -0
- package/dist/cloudflare-scoped-resource.js.map +1 -0
- package/dist/command-catalog.d.ts +13 -0
- package/dist/command-catalog.d.ts.map +1 -0
- package/dist/command-catalog.js +50 -0
- package/dist/command-catalog.js.map +1 -0
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +287 -47
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +274 -38
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/control-plane-read.d.ts +31 -3
- package/dist/commands/control-plane-read.d.ts.map +1 -1
- package/dist/commands/control-plane-read.js +136 -37
- package/dist/commands/control-plane-read.js.map +1 -1
- package/dist/commands/deploy-retry.d.ts +20 -0
- package/dist/commands/deploy-retry.d.ts.map +1 -0
- package/dist/commands/deploy-retry.js +106 -0
- package/dist/commands/deploy-retry.js.map +1 -0
- package/dist/commands/deploy.d.ts +16 -8
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +1027 -373
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +19 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +1378 -88
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +27 -10
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/flags.d.ts +9 -4
- package/dist/commands/flags.d.ts.map +1 -1
- package/dist/commands/flags.js +208 -80
- package/dist/commands/flags.js.map +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +177 -86
- package/dist/commands/help-command.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +5 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link.d.ts.map +1 -1
- package/dist/commands/link.js +74 -15
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/project.d.ts +107 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +586 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/secrets.d.ts +2 -2
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +15 -5
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/validate.d.ts +19 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +26 -7
- package/dist/commands/validate.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/control-plane-tenant-provisioning.d.ts +24 -0
- package/dist/control-plane-tenant-provisioning.d.ts.map +1 -0
- package/dist/control-plane-tenant-provisioning.js +85 -0
- package/dist/control-plane-tenant-provisioning.js.map +1 -0
- package/dist/deploy-targets.d.ts +24 -0
- package/dist/deploy-targets.d.ts.map +1 -0
- package/dist/deploy-targets.js +38 -0
- package/dist/deploy-targets.js.map +1 -0
- package/dist/dev/account-selection.d.ts +16 -0
- package/dist/dev/account-selection.d.ts.map +1 -0
- package/dist/dev/account-selection.js +22 -0
- package/dist/dev/account-selection.js.map +1 -0
- package/dist/dev/browser-log-bridge.d.ts +32 -0
- package/dist/dev/browser-log-bridge.d.ts.map +1 -0
- package/dist/dev/browser-log-bridge.js +156 -0
- package/dist/dev/browser-log-bridge.js.map +1 -0
- package/dist/dev/compat-shim.d.ts +3 -3
- package/dist/dev/compat-shim.d.ts.map +1 -1
- package/dist/dev/compat-shim.js +29 -4
- package/dist/dev/compat-shim.js.map +1 -1
- package/dist/dev/component-selection.d.ts +25 -0
- package/dist/dev/component-selection.d.ts.map +1 -0
- package/dist/dev/component-selection.js +79 -0
- package/dist/dev/component-selection.js.map +1 -0
- package/dist/dev/console-capture.d.ts +18 -0
- package/dist/dev/console-capture.d.ts.map +1 -0
- package/dist/dev/console-capture.js +57 -0
- package/dist/dev/console-capture.js.map +1 -0
- package/dist/dev/event-bus.d.ts +1 -1
- package/dist/dev/event-bus.js +1 -1
- package/dist/dev/frontend-log-relay.d.ts +27 -0
- package/dist/dev/frontend-log-relay.d.ts.map +1 -0
- package/dist/dev/frontend-log-relay.js +102 -0
- package/dist/dev/frontend-log-relay.js.map +1 -0
- package/dist/dev/invoke.d.ts +3 -4
- package/dist/dev/invoke.d.ts.map +1 -1
- package/dist/dev/invoke.js +9 -4
- package/dist/dev/invoke.js.map +1 -1
- package/dist/dev/keyboard.d.ts +1 -0
- package/dist/dev/keyboard.d.ts.map +1 -1
- package/dist/dev/keyboard.js +9 -3
- package/dist/dev/keyboard.js.map +1 -1
- package/dist/dev/log-server.js +3 -0
- package/dist/dev/log-server.js.map +1 -1
- package/dist/dev/loopback-http-listener.d.ts +18 -0
- package/dist/dev/loopback-http-listener.d.ts.map +1 -0
- package/dist/dev/loopback-http-listener.js +91 -0
- package/dist/dev/loopback-http-listener.js.map +1 -0
- package/dist/dev/managed-session.d.ts +124 -0
- package/dist/dev/managed-session.d.ts.map +1 -0
- package/dist/dev/managed-session.js +597 -0
- package/dist/dev/managed-session.js.map +1 -0
- package/dist/dev/port-process.d.ts +21 -0
- package/dist/dev/port-process.d.ts.map +1 -0
- package/dist/dev/port-process.js +145 -0
- package/dist/dev/port-process.js.map +1 -0
- package/dist/dev/session-manager.d.ts +11 -1
- package/dist/dev/session-manager.d.ts.map +1 -1
- package/dist/dev/session-manager.js +65 -14
- package/dist/dev/session-manager.js.map +1 -1
- package/dist/dev/stream-event-format.d.ts +14 -0
- package/dist/dev/stream-event-format.d.ts.map +1 -0
- package/dist/dev/stream-event-format.js +262 -0
- package/dist/dev/stream-event-format.js.map +1 -0
- package/dist/dev/stream-filter.d.ts.map +1 -1
- package/dist/dev/stream-filter.js +16 -1
- package/dist/dev/stream-filter.js.map +1 -1
- package/dist/dev/stream-renderer.d.ts +4 -2
- package/dist/dev/stream-renderer.d.ts.map +1 -1
- package/dist/dev/stream-renderer.js +224 -84
- package/dist/dev/stream-renderer.js.map +1 -1
- package/dist/errors-registry.d.ts.map +1 -1
- package/dist/errors-registry.js +246 -0
- package/dist/errors-registry.js.map +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +20 -3
- package/dist/help.js.map +1 -1
- package/dist/hubspot-app-logs.d.ts +38 -5
- package/dist/hubspot-app-logs.d.ts.map +1 -1
- package/dist/hubspot-app-logs.js +88 -17
- package/dist/hubspot-app-logs.js.map +1 -1
- package/dist/hubspot-auth.d.ts +19 -1
- package/dist/hubspot-auth.d.ts.map +1 -1
- package/dist/hubspot-auth.js +228 -83
- package/dist/hubspot-auth.js.map +1 -1
- package/dist/hubspot-developer-client.d.ts +87 -0
- package/dist/hubspot-developer-client.d.ts.map +1 -1
- package/dist/hubspot-developer-client.js +232 -1
- package/dist/hubspot-developer-client.js.map +1 -1
- package/dist/hubspot-project-archive.d.ts +21 -0
- package/dist/hubspot-project-archive.d.ts.map +1 -0
- package/dist/hubspot-project-archive.js +281 -0
- package/dist/hubspot-project-archive.js.map +1 -0
- package/dist/hubspot-project.d.ts +32 -0
- package/dist/hubspot-project.d.ts.map +1 -0
- package/dist/hubspot-project.js +269 -0
- package/dist/hubspot-project.js.map +1 -0
- package/dist/local-project-picker.js +1 -1
- package/dist/local-project-picker.js.map +1 -1
- package/dist/machine-artifact.d.ts +16 -0
- package/dist/machine-artifact.d.ts.map +1 -0
- package/dist/machine-artifact.js +18 -0
- package/dist/machine-artifact.js.map +1 -0
- package/dist/machine-id.d.ts +15 -0
- package/dist/machine-id.d.ts.map +1 -1
- package/dist/machine-id.js +53 -0
- package/dist/machine-id.js.map +1 -1
- package/dist/mutation-consent.d.ts +20 -0
- package/dist/mutation-consent.d.ts.map +1 -0
- package/dist/mutation-consent.js +9 -0
- package/dist/mutation-consent.js.map +1 -0
- package/dist/output-context.d.ts +3 -0
- package/dist/output-context.d.ts.map +1 -1
- package/dist/output-context.js +7 -1
- package/dist/output-context.js.map +1 -1
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +123 -48
- package/dist/prompt.js.map +1 -1
- package/dist/reporter/index.js +1 -1
- package/dist/reporter/index.js.map +1 -1
- package/dist/reporter/style.d.ts.map +1 -1
- package/dist/reporter/style.js +5 -0
- package/dist/reporter/style.js.map +1 -1
- package/dist/services/hubspot-dev-client.js +3 -0
- package/dist/services/hubspot-dev-client.js.map +1 -1
- package/dist/services/telemetry.d.ts +1 -2
- package/dist/services/telemetry.d.ts.map +1 -1
- package/dist/services/telemetry.js +1 -10
- package/dist/services/telemetry.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +1 -7
- package/dist/telemetry.js.map +1 -1
- package/dist/tenant-data-plane-provisioning.d.ts +35 -0
- package/dist/tenant-data-plane-provisioning.d.ts.map +1 -0
- package/dist/tenant-data-plane-provisioning.js +38 -0
- package/dist/tenant-data-plane-provisioning.js.map +1 -0
- package/package.json +14 -12
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as Command from '@effect/cli/Command';
|
|
2
2
|
import * as Options from '@effect/cli/Options';
|
|
3
3
|
import { HttpClientRequest, Schema, schemas } from '@hs-x/types';
|
|
4
|
+
import { fnv1a32 } from '@hs-x/types/fnv1a';
|
|
4
5
|
import { Config, Effect, Option } from 'effect';
|
|
5
6
|
import { isLinked } from '../account-store.js';
|
|
6
7
|
import { auditExplorer, filterAuditRows, promptAuditTimeRange, renderAuditDetail, } from '../audit-interactive.js';
|
|
@@ -9,7 +10,9 @@ import { CliError, cliError, exitWith } from '../cli-error.js';
|
|
|
9
10
|
import { accountIdOption, controlPlaneUrlOption, jsonOption, projectIdOption, runHandler, userIdOption, } from '../cli/kit.js';
|
|
10
11
|
import { DEFAULT_CONTROL_PLANE_URL } from '../config.js';
|
|
11
12
|
import { executeCliHttpEffect } from '../effect-http.js';
|
|
12
|
-
import { fetchHubSpotLogsPayload, mergeLogRows, parseHubSpotLogSystemTypes, resolveHubSpotLogsSource, } from '../hubspot-app-logs.js';
|
|
13
|
+
import { fetchHubSpotLogsPayload, mergeLogRows, parseHubSpotLogSystemTypes, resolveDirectHubSpotLogsContext, resolveHubSpotLogsSource, } from '../hubspot-app-logs.js';
|
|
14
|
+
import { DirectHubSpotAccountResolutionError, } from '../hubspot-developer-client.js';
|
|
15
|
+
import { detectLocalProjectMode } from '../hubspot-project.js';
|
|
13
16
|
import { promptInteractiveLogsSelection } from '../logs-interactive.js';
|
|
14
17
|
import { readProjectBinding } from '../project-binding.js';
|
|
15
18
|
import { ProjectPickerCancelled, discoverProjects, resolveProjectSelection, } from '../project-picker.js';
|
|
@@ -203,21 +206,13 @@ function stableLogRowKey(row) {
|
|
|
203
206
|
function orderLogRowsAscending(rows) {
|
|
204
207
|
return [...rows].sort((a, b) => (readString(a, 'timestamp') ?? '').localeCompare(readString(b, 'timestamp') ?? ''));
|
|
205
208
|
}
|
|
206
|
-
function hashString(value) {
|
|
207
|
-
let hash = 2166136261;
|
|
208
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
209
|
-
hash ^= value.charCodeAt(index);
|
|
210
|
-
hash = Math.imul(hash, 16777619);
|
|
211
|
-
}
|
|
212
|
-
return hash >>> 0;
|
|
213
|
-
}
|
|
214
209
|
function applyLogFilters(rows, filters, sampleRate) {
|
|
215
210
|
return rows.filter((row) => {
|
|
216
211
|
if (!filters.every((filter) => compareLogFilter(row, filter)))
|
|
217
212
|
return false;
|
|
218
213
|
if (sampleRate === undefined || sampleRate >= 1)
|
|
219
214
|
return true;
|
|
220
|
-
return
|
|
215
|
+
return fnv1a32(stableLogRowKey(row)) / 0xffffffff <= sampleRate;
|
|
221
216
|
});
|
|
222
217
|
}
|
|
223
218
|
function asLogsPayload(body) {
|
|
@@ -1075,6 +1070,15 @@ const logsOptions = {
|
|
|
1075
1070
|
appId: Options.text('app-id').pipe(Options.optional),
|
|
1076
1071
|
type: Options.text('type').pipe(Options.repeated),
|
|
1077
1072
|
errorsOnly: Options.boolean('errors-only').pipe(Options.withDefault(false)),
|
|
1073
|
+
functionName: Options.text('function').pipe(Options.optional),
|
|
1074
|
+
latest: Options.boolean('latest').pipe(Options.withAlias('l'), Options.withDefault(false)),
|
|
1075
|
+
compact: Options.boolean('compact').pipe(Options.withDefault(false)),
|
|
1076
|
+
};
|
|
1077
|
+
const projectLogsOptions = {
|
|
1078
|
+
...logsOptions,
|
|
1079
|
+
account: Options.text('account').pipe(Options.withAlias('a'), Options.optional),
|
|
1080
|
+
config: Options.text('config').pipe(Options.withAlias('c'), Options.optional),
|
|
1081
|
+
useEnv: Options.boolean('use-env').pipe(Options.withDefault(false)),
|
|
1078
1082
|
};
|
|
1079
1083
|
const LOG_SELECTOR_FLAGS = [
|
|
1080
1084
|
'--source',
|
|
@@ -1092,6 +1096,10 @@ const LOG_SELECTOR_FLAGS = [
|
|
|
1092
1096
|
'--follow',
|
|
1093
1097
|
'--tail',
|
|
1094
1098
|
'--errors-only',
|
|
1099
|
+
'--function',
|
|
1100
|
+
'--latest',
|
|
1101
|
+
'-l',
|
|
1102
|
+
'--compact',
|
|
1095
1103
|
];
|
|
1096
1104
|
function hasExplicitLogSelector(argv = process.argv.slice(2)) {
|
|
1097
1105
|
return argv.some((arg) => LOG_SELECTOR_FLAGS.some((flag) => arg === flag || arg.startsWith(`${flag}=`)));
|
|
@@ -1117,6 +1125,55 @@ function parseLogSource(value) {
|
|
|
1117
1125
|
return { ok: false, message: `Invalid --source "${value}". Use all, workers, or hubspot.` };
|
|
1118
1126
|
}
|
|
1119
1127
|
export const logsCmd = Command.make('logs', logsOptions, (opts) => runHandler('logs', { json: opts.json }, logsBody(opts)));
|
|
1128
|
+
export const projectLogsCmd = Command.make('logs', projectLogsOptions, (opts) => runHandler('project logs', { json: opts.json }, logsBody(opts, {
|
|
1129
|
+
commandName: 'project logs',
|
|
1130
|
+
directHubSpotArgv: projectLogsAccountArgv(opts),
|
|
1131
|
+
})));
|
|
1132
|
+
function projectLogsAccountArgv(opts) {
|
|
1133
|
+
const argv = ['project', 'logs'];
|
|
1134
|
+
const account = Option.getOrUndefined(opts.account);
|
|
1135
|
+
const config = Option.getOrUndefined(opts.config);
|
|
1136
|
+
if (account)
|
|
1137
|
+
argv.push('--account', account);
|
|
1138
|
+
if (config)
|
|
1139
|
+
argv.push('--config', config);
|
|
1140
|
+
if (opts.useEnv)
|
|
1141
|
+
argv.push('--use-env');
|
|
1142
|
+
return argv;
|
|
1143
|
+
}
|
|
1144
|
+
function directHubSpotLogsError(cause) {
|
|
1145
|
+
if (cause instanceof CliError)
|
|
1146
|
+
return cause;
|
|
1147
|
+
if (cause instanceof DirectHubSpotAccountResolutionError) {
|
|
1148
|
+
return new CliError({
|
|
1149
|
+
code: cause.code,
|
|
1150
|
+
message: cause.message,
|
|
1151
|
+
context: { hint: cause.hint },
|
|
1152
|
+
exitCode: 1,
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
return new CliError({
|
|
1156
|
+
code: 'HSX_E_LOGS_UNAVAILABLE',
|
|
1157
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
1158
|
+
exitCode: 1,
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
function directHubSpotAccountRows(account) {
|
|
1162
|
+
const label = account.name ? `${account.name} (${account.id})` : account.id;
|
|
1163
|
+
return [
|
|
1164
|
+
{
|
|
1165
|
+
key: 'hubspot-account',
|
|
1166
|
+
value: label,
|
|
1167
|
+
detail: `source=${account.source} selectedBy=${account.selectedBy} authReady=${String(account.authReady)}`,
|
|
1168
|
+
},
|
|
1169
|
+
...(account.configSource
|
|
1170
|
+
? [{ key: 'hubspot-config', value: account.configSource }]
|
|
1171
|
+
: []),
|
|
1172
|
+
...(account.defaultSource
|
|
1173
|
+
? [{ key: 'hubspot-default', value: account.defaultSource }]
|
|
1174
|
+
: []),
|
|
1175
|
+
];
|
|
1176
|
+
}
|
|
1120
1177
|
function resolveAccountId(opts, localAccountId) {
|
|
1121
1178
|
return Effect.gen(function* () {
|
|
1122
1179
|
const explicit = yield* resolveFromOptionOrEnv(opts.accountId, 'HSX_ACCOUNT_ID');
|
|
@@ -1148,14 +1205,18 @@ function withWorkersErrorHint(error) {
|
|
|
1148
1205
|
}
|
|
1149
1206
|
function logsBody(opts, context = {}) {
|
|
1150
1207
|
return Effect.gen(function* () {
|
|
1208
|
+
const commandName = context.commandName ?? 'logs';
|
|
1151
1209
|
const cwd = yield* Cwd;
|
|
1210
|
+
const projectMode = yield* Effect.promise(() => detectLocalProjectMode(cwd));
|
|
1211
|
+
const directHubSpotProject = projectMode === 'hubspot-direct';
|
|
1152
1212
|
const localProjectBinding = yield* Effect.promise(() => readProjectBinding(cwd));
|
|
1153
|
-
const
|
|
1213
|
+
const requestedSourceValue = Option.getOrUndefined(opts.source) ?? (directHubSpotProject ? 'hubspot' : undefined);
|
|
1214
|
+
const requestedSource = parseLogSource(requestedSourceValue);
|
|
1154
1215
|
const shouldResolveWorkersProject = requestedSource.ok && requestedSource.wantWorkers;
|
|
1155
1216
|
const projectSelection = shouldResolveWorkersProject
|
|
1156
1217
|
? (context.projectSelection ??
|
|
1157
1218
|
(yield* resolveOperationProjectForRead(opts, {
|
|
1158
|
-
command:
|
|
1219
|
+
command: commandName,
|
|
1159
1220
|
message: 'Which project do you want logs for?',
|
|
1160
1221
|
emptyMessage: 'No projects yet. Run `hs-x deploy` from a project to create one.',
|
|
1161
1222
|
})))
|
|
@@ -1163,20 +1224,23 @@ function logsBody(opts, context = {}) {
|
|
|
1163
1224
|
const currentProjectId = projectSelection?.projectId ??
|
|
1164
1225
|
(yield* resolveProjectId(opts)) ??
|
|
1165
1226
|
localProjectBinding?.projectId;
|
|
1166
|
-
const accountId =
|
|
1167
|
-
|
|
1227
|
+
const accountId = directHubSpotProject
|
|
1228
|
+
? undefined
|
|
1229
|
+
: (projectSelection?.accountId ??
|
|
1230
|
+
(yield* resolveAccountId(opts, localProjectBinding?.accountId)));
|
|
1168
1231
|
const controlPlaneUrl = yield* resolveControlPlaneUrl(opts.controlPlaneUrl);
|
|
1169
1232
|
const userId = yield* resolveUserId(opts);
|
|
1170
1233
|
const shouldPrompt = !opts.json &&
|
|
1171
1234
|
isInteractive() &&
|
|
1235
|
+
!directHubSpotProject &&
|
|
1172
1236
|
(context.forceInteractiveSetup === true || !hasExplicitLogSelector());
|
|
1173
1237
|
let interactiveSelection = undefined;
|
|
1174
1238
|
if (shouldPrompt) {
|
|
1175
1239
|
if (!accountId) {
|
|
1176
|
-
return yield* failBespoke(false,
|
|
1240
|
+
return yield* failBespoke(false, commandName, 'Logs require an HS-X account: run `hs-x login`, or pass --account-id / HSX_ACCOUNT_ID.');
|
|
1177
1241
|
}
|
|
1178
1242
|
if (!currentProjectId) {
|
|
1179
|
-
return yield* failBespoke(false,
|
|
1243
|
+
return yield* failBespoke(false, commandName, `Logs need a project: ${PROJECT_ID_HINT}.`);
|
|
1180
1244
|
}
|
|
1181
1245
|
interactiveSelection = yield* Effect.promise(() => promptInteractiveLogsSelection({
|
|
1182
1246
|
projects: projectSelection?.projects ?? [],
|
|
@@ -1190,46 +1254,67 @@ function logsBody(opts, context = {}) {
|
|
|
1190
1254
|
}
|
|
1191
1255
|
}
|
|
1192
1256
|
const projectId = interactiveSelection?.projectId ?? currentProjectId;
|
|
1193
|
-
const
|
|
1257
|
+
const functionName = Option.getOrUndefined(opts.functionName);
|
|
1258
|
+
const parsedFilters = parseLogFilters([
|
|
1259
|
+
...opts.filter,
|
|
1260
|
+
...(functionName ? [`target=${functionName}`] : []),
|
|
1261
|
+
]);
|
|
1194
1262
|
if (!parsedFilters.ok) {
|
|
1195
|
-
return yield* failBespoke(opts.json,
|
|
1263
|
+
return yield* failBespoke(opts.json, commandName, parsedFilters.message);
|
|
1196
1264
|
}
|
|
1197
1265
|
const parsedSample = parseSampleRate(Option.getOrUndefined(opts.sample));
|
|
1198
1266
|
if (!parsedSample.ok) {
|
|
1199
|
-
return yield* failBespoke(opts.json,
|
|
1267
|
+
return yield* failBespoke(opts.json, commandName, parsedSample.message);
|
|
1200
1268
|
}
|
|
1201
1269
|
const follow = interactiveSelection?.follow ?? opts.follow;
|
|
1202
1270
|
const errorsOnly = interactiveSelection?.errorsOnly ?? opts.errorsOnly;
|
|
1271
|
+
const requestedTypes = functionName ? [...opts.type, 'serverless'] : opts.type;
|
|
1203
1272
|
const parsedSystemTypes = interactiveSelection?.systemTypes
|
|
1204
1273
|
? { ok: true, systemTypes: interactiveSelection.systemTypes }
|
|
1205
|
-
: parseHubSpotLogSystemTypes(
|
|
1274
|
+
: parseHubSpotLogSystemTypes(requestedTypes);
|
|
1206
1275
|
if (!parsedSystemTypes.ok) {
|
|
1207
|
-
return yield* failBespoke(opts.json,
|
|
1276
|
+
return yield* failBespoke(opts.json, commandName, parsedSystemTypes.message);
|
|
1208
1277
|
}
|
|
1209
1278
|
if (follow && opts.json) {
|
|
1210
|
-
return yield* failBespoke(opts.json,
|
|
1279
|
+
return yield* failBespoke(opts.json, commandName, '`hs-x logs --follow`/`--tail` streams terminal output. Omit --json for follow mode.');
|
|
1211
1280
|
}
|
|
1212
|
-
const sourceChoice = parseLogSource(interactiveSelection?.source ??
|
|
1281
|
+
const sourceChoice = parseLogSource(interactiveSelection?.source ?? requestedSourceValue);
|
|
1213
1282
|
if (!sourceChoice.ok) {
|
|
1214
|
-
return yield* failBespoke(opts.json,
|
|
1283
|
+
return yield* failBespoke(opts.json, commandName, sourceChoice.message);
|
|
1215
1284
|
}
|
|
1216
1285
|
const { wantWorkers, wantHubspot } = sourceChoice;
|
|
1217
1286
|
// The two sources resolve independently: Workers Logs need an HS-X account
|
|
1218
1287
|
// and project id (the control plane mediates the read); HubSpot app logs
|
|
1219
|
-
// need
|
|
1288
|
+
// need an app identity plus a credential-bound HubSpot developer client.
|
|
1289
|
+
// `project logs` resolves that client and its render-safe account together;
|
|
1290
|
+
// legacy `hs-x logs` keeps its existing local binding/config behavior.
|
|
1220
1291
|
// A missing prerequisite is fatal only when it leaves no source at all.
|
|
1221
1292
|
const explicitAppId = Option.getOrUndefined(opts.appId);
|
|
1222
1293
|
const selectedDifferentProject = projectSelection?.projects !== undefined && localProjectBinding?.projectId !== projectId;
|
|
1294
|
+
const hubspotSelectionBlocked = selectedDifferentProject && explicitAppId === undefined
|
|
1295
|
+
? 'the selected project is not the project in the current directory; pass --app-id to include its HubSpot app logs'
|
|
1296
|
+
: undefined;
|
|
1297
|
+
const directHubSpotLogs = wantHubspot && !hubspotSelectionBlocked && context.directHubSpotArgv
|
|
1298
|
+
? yield* Effect.tryPromise({
|
|
1299
|
+
try: () => resolveDirectHubSpotLogsContext({
|
|
1300
|
+
argv: context.directHubSpotArgv ?? [],
|
|
1301
|
+
cwd,
|
|
1302
|
+
...(explicitAppId !== undefined ? { appId: explicitAppId } : {}),
|
|
1303
|
+
}),
|
|
1304
|
+
catch: directHubSpotLogsError,
|
|
1305
|
+
})
|
|
1306
|
+
: undefined;
|
|
1223
1307
|
const hubspotResolution = wantHubspot
|
|
1224
|
-
?
|
|
1308
|
+
? hubspotSelectionBlocked
|
|
1225
1309
|
? {
|
|
1226
1310
|
ok: false,
|
|
1227
|
-
reason:
|
|
1311
|
+
reason: hubspotSelectionBlocked,
|
|
1228
1312
|
}
|
|
1229
|
-
:
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1313
|
+
: (directHubSpotLogs?.resolution ??
|
|
1314
|
+
(yield* Effect.promise(() => resolveHubSpotLogsSource({
|
|
1315
|
+
cwd,
|
|
1316
|
+
...(explicitAppId !== undefined ? { appId: explicitAppId } : {}),
|
|
1317
|
+
}))))
|
|
1233
1318
|
: undefined;
|
|
1234
1319
|
const hubspotSource = hubspotResolution?.ok
|
|
1235
1320
|
? hubspotResolution.source
|
|
@@ -1245,15 +1330,15 @@ function logsBody(opts, context = {}) {
|
|
|
1245
1330
|
const workersActive = workersReason === undefined;
|
|
1246
1331
|
if (!workersActive && !hubspotSource) {
|
|
1247
1332
|
if (wantWorkers && !accountId) {
|
|
1248
|
-
return yield* failBespoke(opts.json,
|
|
1333
|
+
return yield* failBespoke(opts.json, commandName, 'Logs require an HS-X account: run `hs-x login`, or pass --account-id / HSX_ACCOUNT_ID.');
|
|
1249
1334
|
}
|
|
1250
1335
|
if (wantWorkers && !projectId) {
|
|
1251
|
-
return yield* failBespoke(opts.json,
|
|
1336
|
+
return yield* failBespoke(opts.json, commandName, `Logs need a project: ${PROJECT_ID_HINT}.`);
|
|
1252
1337
|
}
|
|
1253
|
-
return yield* failBespoke(opts.json,
|
|
1338
|
+
return yield* failBespoke(opts.json, commandName, `HubSpot app logs unavailable: ${hubspotReason ?? 'unknown'}.`);
|
|
1254
1339
|
}
|
|
1255
1340
|
const trace = Option.getOrUndefined(opts.trace);
|
|
1256
|
-
const limit = clampInt(opts.limit, 1, 200);
|
|
1341
|
+
const limit = clampInt(opts.latest ? 1 : opts.limit, 1, 200);
|
|
1257
1342
|
const sinceMinutes = clampInt(interactiveSelection?.sinceMinutes ?? opts.sinceMinutes, 1, 7 * 24 * 60);
|
|
1258
1343
|
const intervalSeconds = clampInt(opts.intervalSeconds, 1, 60);
|
|
1259
1344
|
const view = trace ? 'trace' : opts.raw ? 'tail' : 'invocations';
|
|
@@ -1279,7 +1364,7 @@ function logsBody(opts, context = {}) {
|
|
|
1279
1364
|
if (!response.ok) {
|
|
1280
1365
|
const message = responseMessage(body, response.status, 'Control-plane logs read failed');
|
|
1281
1366
|
if (strictWorkers) {
|
|
1282
|
-
yield* failBespoke(opts.json,
|
|
1367
|
+
yield* failBespoke(opts.json, commandName, message);
|
|
1283
1368
|
return { rows: [] };
|
|
1284
1369
|
}
|
|
1285
1370
|
return { rows: [], error: message };
|
|
@@ -1294,6 +1379,7 @@ function logsBody(opts, context = {}) {
|
|
|
1294
1379
|
systemTypes: parsedSystemTypes.systemTypes,
|
|
1295
1380
|
errorsOnly,
|
|
1296
1381
|
...(trace ? { trace } : {}),
|
|
1382
|
+
...(directHubSpotLogs ? { client: directHubSpotLogs.client } : {}),
|
|
1297
1383
|
}).catch((cause) => ({
|
|
1298
1384
|
rows: [],
|
|
1299
1385
|
error: cause instanceof Error ? cause.message : String(cause),
|
|
@@ -1339,10 +1425,11 @@ function logsBody(opts, context = {}) {
|
|
|
1339
1425
|
: 'workers-logs';
|
|
1340
1426
|
const result = {
|
|
1341
1427
|
ok: !payload.fatalError,
|
|
1342
|
-
command:
|
|
1428
|
+
command: commandName,
|
|
1343
1429
|
mode,
|
|
1344
1430
|
view,
|
|
1345
1431
|
...(accountId ? { accountId } : {}),
|
|
1432
|
+
...(directHubSpotLogs ? { account: directHubSpotLogs.account } : {}),
|
|
1346
1433
|
...(projectId ? { projectId } : {}),
|
|
1347
1434
|
sinceMinutes,
|
|
1348
1435
|
limit,
|
|
@@ -1397,6 +1484,9 @@ function logsBody(opts, context = {}) {
|
|
|
1397
1484
|
if (follow) {
|
|
1398
1485
|
const seen = new Set();
|
|
1399
1486
|
yield* reporter.header(trace ? `${headerLabel} invocation ${trace}` : `${headerLabel} live`);
|
|
1487
|
+
if (directHubSpotLogs) {
|
|
1488
|
+
yield* reporter.rows(directHubSpotAccountRows(directHubSpotLogs.account));
|
|
1489
|
+
}
|
|
1400
1490
|
const printNewRows = (rows) => Effect.gen(function* () {
|
|
1401
1491
|
const fresh = orderLogRowsAscending(rows.filter((row) => {
|
|
1402
1492
|
const key = stableLogRowKey(row);
|
|
@@ -1432,6 +1522,9 @@ function logsBody(opts, context = {}) {
|
|
|
1432
1522
|
return;
|
|
1433
1523
|
}
|
|
1434
1524
|
yield* reporter.header(trace ? `${headerLabel} invocation ${trace}` : headerLabel);
|
|
1525
|
+
if (directHubSpotLogs) {
|
|
1526
|
+
yield* reporter.rows(directHubSpotAccountRows(directHubSpotLogs.account));
|
|
1527
|
+
}
|
|
1435
1528
|
yield* emitLogRows(reporter, payload.rows, view, showOrigin);
|
|
1436
1529
|
yield* reportPartialFailures;
|
|
1437
1530
|
if (payload.fatalError) {
|
|
@@ -1474,6 +1567,9 @@ export function logsBodyForCheckpoint(opts, selection, checkpoint, failure) {
|
|
|
1474
1567
|
appId: Option.none(),
|
|
1475
1568
|
type: [],
|
|
1476
1569
|
errorsOnly: true,
|
|
1570
|
+
functionName: Option.none(),
|
|
1571
|
+
latest: false,
|
|
1572
|
+
compact: false,
|
|
1477
1573
|
}, { projectSelection: selection });
|
|
1478
1574
|
}
|
|
1479
1575
|
/** In-process command bodies used by the human status drill-down. */
|
|
@@ -1493,6 +1589,9 @@ export function logsBodyForStatus(opts, selection) {
|
|
|
1493
1589
|
appId: Option.none(),
|
|
1494
1590
|
type: [],
|
|
1495
1591
|
errorsOnly: false,
|
|
1592
|
+
functionName: Option.none(),
|
|
1593
|
+
latest: false,
|
|
1594
|
+
compact: false,
|
|
1496
1595
|
}, { projectSelection: selection, forceInteractiveSetup: true });
|
|
1497
1596
|
}
|
|
1498
1597
|
export function routesBodyForStatus(opts, selection) {
|