@bedrock-rbx/core 0.1.0-beta.11 → 0.1.0-beta.12

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/cli/run.mjs CHANGED
@@ -1,13 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { T as serializeStateFile, a as buildStatePort, d as resolveStateConfig, f as flattenConfig, h as diff, i as loadConfig, l as validatePlan, n as serializeConfig, o as buildDesired, r as deploy, t as migrateMantleState, u as selectEnvironment } from "../migrate-mantle-state-DjAU-I39.mjs";
3
- import { PermissionError } from "@bedrock-rbx/ocale";
2
+ import { B as renderDeployError, E as serializeStateFile, G as renderStateWriteError, H as renderMigrateParseError, R as createClackProgressAdapter, U as renderMigrationSummary, V as renderMigrateError, W as renderParseError, a as buildStatePort, d as resolveStateConfig, f as flattenConfig, h as diff, i as loadConfig, l as validatePlan, n as serializeConfig, o as buildDesired, r as deploy, t as migrateMantleState, u as selectEnvironment, y as createClackPort, z as renderBuildStatePortError } from "../migrate-mantle-state-Dkk5zGHw.mjs";
3
+ import { isCancel, path, select, text } from "@clack/prompts";
4
4
  import process from "node:process";
5
5
  import { mkdir, readFile, writeFile } from "node:fs/promises";
6
6
  import { dirname, join } from "node:path";
7
7
  import sade from "sade";
8
- import { cancel, intro, isCancel, log, outro, path, select, text } from "@clack/prompts";
9
8
  //#region package.json
10
- var version = "0.1.0-beta.11";
9
+ var version = "0.1.0-beta.12";
11
10
  //#endregion
12
11
  //#region src/cli/credential-environment-overrides.ts
13
12
  /**
@@ -117,202 +116,6 @@ function pickString(rawOptions, ...keys) {
117
116
  }
118
117
  }
119
118
  //#endregion
120
- //#region src/cli/render.ts
121
- /**
122
- * Render a `DeployError` to the supplied `ClackPort` as a single error line.
123
- * Each variant produces a distinct, terse diagnostic; wrapped variants
124
- * (`applyFailed`, `buildDesiredFailed`, `configLoadFailed`, `stateReadFailed`,
125
- * `stateWriteFailed`) surface the inner cause's actionable detail (file path,
126
- * resource key, parser message, HTTP failure, validator issue) so the reader
127
- * does not have to inspect the full cause to act.
128
- * @param err - The deploy error to describe.
129
- * @param port - The output port the diagnostic is written to.
130
- */
131
- function renderDeployError(err, port) {
132
- port.logError(deployErrorMessage(err));
133
- }
134
- /**
135
- * Render a `ParseOptionsError` to the supplied `ClackPort` as a single
136
- * error line. Each variant names the offending flag so the diagnostic
137
- * pinpoints what the caller needs to change.
138
- * @param err - The parse error to describe.
139
- * @param port - The output port the diagnostic is written to.
140
- */
141
- function renderParseError(err, port) {
142
- port.logError(parseErrorMessage(err));
143
- }
144
- /**
145
- * Construct a `ClackPort` whose methods delegate to `@clack/prompts`. The
146
- * resulting port writes to `process.stdout` via clack's defaults.
147
- * @returns A port whose six methods each invoke the matching clack helper.
148
- */
149
- function createClackPort() {
150
- return {
151
- cancel: (message) => {
152
- cancel(message);
153
- },
154
- intro: (message) => {
155
- intro(message);
156
- },
157
- logError: (message) => {
158
- log.error(message);
159
- },
160
- logMessage: (message) => {
161
- log.message(message);
162
- },
163
- logSuccess: (message) => {
164
- log.success(message);
165
- },
166
- outro: (message) => {
167
- outro(message);
168
- }
169
- };
170
- }
171
- /**
172
- * Render a `ParseMigrateError` to the supplied `ClackPort`. Reuses
173
- * `parseErrorMessage` for the three flag-shape variants and adds a
174
- * dedicated message for `unknownSource` listing the supported sources.
175
- * @param err - The parse error to describe.
176
- * @param port - The output port the diagnostic is written to.
177
- */
178
- function renderMigrateParseError(err, port) {
179
- port.logError(migrateParseErrorMessage(err));
180
- }
181
- /**
182
- * Render a `MigrateError` to the supplied `ClackPort` as a single error
183
- * line. Each variant points at the offending Mantle state file path,
184
- * primary-environment input, or wrapped `ConfigError` so the reader can
185
- * act without inspecting the raw error object.
186
- * @param err - The migrate error to describe.
187
- * @param port - The output port the diagnostic is written to.
188
- */
189
- function renderMigrateError(err, port) {
190
- port.logError(migrateErrorMessage(err));
191
- }
192
- /**
193
- * Render a `MissingCredentialError` or `UnsupportedBackendError`
194
- * surfaced when the migrate command tried to default-construct the
195
- * configured `StatePort` and was missing its inputs.
196
- * @param err - The error returned by `buildStatePort`.
197
- * @param port - The output port the diagnostic is written to.
198
- */
199
- function renderBuildStatePortError(err, port) {
200
- port.logError(buildStatePortErrorMessage(err));
201
- }
202
- /**
203
- * Render the post-migrate review prompt to the supplied `ClackPort`.
204
- * Three outcomes:
205
- *
206
- * - Any `ambiguous` warnings exist: emit a single error line directing
207
- * the user to the report. The migration ran but there are decisions
208
- * the user still needs to make before deploy will be meaningful.
209
- * - No `ambiguous` warnings but non-zero `blocked` / `deferred` /
210
- * `interpretive`: emit a single success line pointing at the report
211
- * for auditing.
212
- * - All counts zero: silent. The closing `outro("migrate succeeded")`
213
- * already speaks for the run.
214
- * @param input - Counts plus the path of the Markdown report.
215
- * @param port - The output port the line is written to.
216
- */
217
- function renderMigrationSummary(input, port) {
218
- const { ambiguousCount, blockedCount, deferredCount, interpretiveCount } = input.summary;
219
- if (ambiguousCount > 0) {
220
- port.logError(`action required: ${String(ambiguousCount)} fields need your input. See ${input.reportPath}`);
221
- return;
222
- }
223
- const reviewable = blockedCount + deferredCount + interpretiveCount;
224
- if (reviewable > 0) port.logSuccess(`migration complete; see ${input.reportPath} for ${String(reviewable)} auto-mapped or skipped fields`);
225
- }
226
- /**
227
- * Render a `StateError` produced when the migrator wrote a per-environment
228
- * state through the `StatePort`. Names the environment alongside the
229
- * adapter's failure reason so the reader knows which write failed.
230
- * @param input - Environment + state-error to describe.
231
- * @param port - The output port the diagnostic is written to.
232
- */
233
- function renderStateWriteError(input, port) {
234
- port.logError(`state write failed for '${input.environment}' (${input.err.file}): ${input.err.reason}`);
235
- }
236
- function permissionDetail(err) {
237
- const isPlural = err.requiredScopes.length > 1;
238
- const label = isPlural ? "scopes" : "scope";
239
- const pronoun = isPlural ? "them" : "it";
240
- const scopeList = err.requiredScopes.map((scope) => `'${scope}'`).join(", ");
241
- return `${err.message} on ${err.operationKey}: missing required ${label} ${scopeList}. Grant ${pronoun} on the API key at https://create.roblox.com/credentials`;
242
- }
243
- function applyCauseDetail(cause) {
244
- switch (cause.kind) {
245
- case "driverFailure":
246
- if (cause.cause instanceof PermissionError) return permissionDetail(cause.cause);
247
- return cause.cause.message;
248
- case "updateUnsupported": return "update not supported";
249
- }
250
- }
251
- function buildDesiredDetail(cause) {
252
- switch (cause.kind) {
253
- case "fileReadFailed": return `(${cause.filePath}): ${cause.reason}`;
254
- case "iconRemovalRejected": return `: ${cause.message}`;
255
- }
256
- }
257
- function configErrorDetail(err) {
258
- switch (err.kind) {
259
- case "configFunctionFailed": return `${err.sourceFile}: config function threw: ${err.message}`;
260
- case "fileNotFound": return `no bedrock config under ${err.searchedFrom}`;
261
- case "luauRuntimeMissing": return `${err.sourceFile}: ${err.hint}`;
262
- case "parseFailed": return `${err.sourceFile}: ${err.message}`;
263
- case "validationFailed": {
264
- const first = err.issues[0];
265
- return first === void 0 ? `${err.sourceFile}: invalid` : `${err.sourceFile}: ${first.path.join(".")} ${first.message}`;
266
- }
267
- }
268
- }
269
- function stateErrorDetail(cause) {
270
- return `(${cause.file}): ${cause.reason}`;
271
- }
272
- function deployErrorMessage(err) {
273
- switch (err.kind) {
274
- case "applyFailed": return `apply failed for '${err.cause.key}': ${applyCauseDetail(err.cause)}`;
275
- case "buildDesiredFailed": return `build desired state failed for '${err.cause.key}' ${buildDesiredDetail(err.cause)}`;
276
- case "configLoadFailed": return `config load failed: ${configErrorDetail(err.cause)}`;
277
- case "incompletePlaceEntry": return `place '${err.key}' is missing '${err.missingField}' under environment '${err.environment}'`;
278
- case "incompleteUniverseEntry": return `universe is missing '${err.missingField}' under environment '${err.environment}'`;
279
- case "missingCredential": return `missing credential: environment variable ${err.variable} is not set`;
280
- case "registryConfigMissing": return `registry config missing '${err.missing}' (${err.hint})`;
281
- case "stateNotConfigured": return `state not configured for environment '${err.environment}'`;
282
- case "stateReadFailed": return `state read failed ${stateErrorDetail(err.cause)}`;
283
- case "stateWriteFailed": return `state write failed ${stateErrorDetail(err.cause)}`;
284
- case "unknownEnvironment": return `unknown environment '${err.environment}' (declared: ${err.declared.join(", ")})`;
285
- case "unsupportedBackend": return `unsupported state backend '${err.backend}' (${err.hint})`;
286
- }
287
- }
288
- function parseErrorMessage(err) {
289
- switch (err.kind) {
290
- case "invalidValue": return `invalid value for flag '--${err.flag}' (expected a string)`;
291
- case "missingRequired": return `missing required flag --${err.flag}`;
292
- case "unknownFlag": return `unknown flag '--${err.flag}'`;
293
- }
294
- }
295
- function migrateParseErrorMessage(err) {
296
- if (err.kind === "unknownSource") return `unknown migration source '${err.received}' (supported: ${err.supported.join(", ")})`;
297
- return parseErrorMessage(err);
298
- }
299
- function migrateErrorMessage(err) {
300
- switch (err.kind) {
301
- case "internalError": return `migrate internal error: ${err.reason} (${configErrorDetail(err.cause)})`;
302
- case "primaryEnvironmentNotFound": return `primary environment '${err.primary}' not found (available: ${err.available.join(", ")})`;
303
- case "primaryEnvironmentRequired": return `primary environment required (available: ${err.available.join(", ")})`;
304
- case "stateFileNotFound": return `Mantle state file not found at '${err.path}'`;
305
- case "stateParseFailed": return `Mantle state file at '${err.path}' could not be parsed: ${err.reason}`;
306
- case "unsupportedMantleStateVersion": return `unsupported Mantle state version '${err.found}' (supported: ${err.supported.join(", ")})`;
307
- }
308
- }
309
- function buildStatePortErrorMessage(err) {
310
- switch (err.kind) {
311
- case "missingCredential": return `missing credential: environment variable ${err.variable} is not set`;
312
- case "unsupportedBackend": return `unsupported state backend '${err.backend}' (${err.hint})`;
313
- }
314
- }
315
- //#endregion
316
119
  //#region src/cli/commands/deploy.ts
317
120
  /**
318
121
  * Build the sade action for `bedrock deploy`. The returned function consumes
@@ -333,11 +136,13 @@ function deployCommand(deps) {
333
136
  };
334
137
  }
335
138
  function resolveDeploy(deps) {
139
+ const clack = deps.clack ?? createClackPort();
336
140
  return {
337
- clack: deps.clack ?? createClackPort(),
141
+ clack,
338
142
  deploy: deps.deploy ?? deploy,
339
143
  exit: deps.exit ?? ((code) => process.exit(code)),
340
- loadConfig: deps.loadConfig ?? loadConfig
144
+ loadConfig: deps.loadConfig ?? loadConfig,
145
+ progress: deps.progress ?? createClackProgressAdapter({ clack })
341
146
  };
342
147
  }
343
148
  function loadOptionsFor$1(parsed) {
@@ -352,9 +157,17 @@ async function dispatchEnvironments$1(inputs) {
352
157
  environment,
353
158
  getEnv
354
159
  });
355
- if (result.success) resolved.clack.logSuccess(`${environment}: ${result.data.resources.length} resources reconciled`);
160
+ if (result.success) resolved.progress.emit({
161
+ environment,
162
+ kind: "deploySuccess",
163
+ resourceCount: result.data.resources.length
164
+ });
356
165
  else {
357
- renderDeployError(result.err, resolved.clack);
166
+ resolved.progress.emit({
167
+ environment,
168
+ error: result.err,
169
+ kind: "deployFailure"
170
+ });
358
171
  failed.push(environment);
359
172
  }
360
173
  }