@go-to-k/cdkd 0.268.1 → 0.268.2

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.
@@ -102,6 +102,24 @@ var SynthesisError = class SynthesisError extends CdkdError {
102
102
  }
103
103
  };
104
104
  /**
105
+ * Control-flow signal: the user declined a pre-provisioning confirmation
106
+ * prompt, so the deploy must unwind WITHOUT being reported as a failure.
107
+ *
108
+ * Raised from `DeployEngineOptions.onCurrentStateLoaded` (the post-lock
109
+ * gate the `--prefix-user-supplied-names` migration check runs in). The
110
+ * engine does not catch it — it propagates out of `deploy()` through the
111
+ * usual `finally`, which releases the lock and stops the renderer — and the
112
+ * deploy CLI catches it and returns quietly instead of logging an error or
113
+ * recording a FAILED run event. Nothing has been provisioned at that point.
114
+ */
115
+ var DeployCancelledError = class DeployCancelledError extends CdkdError {
116
+ constructor(message = "Deployment cancelled by user") {
117
+ super(message, "DEPLOY_CANCELLED");
118
+ this.name = "DeployCancelledError";
119
+ Object.setPrototypeOf(this, DeployCancelledError.prototype);
120
+ }
121
+ };
122
+ /**
105
123
  * Asset errors
106
124
  */
107
125
  var AssetError = class AssetError extends CdkdError {
@@ -8020,6 +8038,30 @@ function describeTypeWithThrottleRetry(resourceType, client) {
8020
8038
  ...describeTypeRetryDelays.sleep ? { sleep: describeTypeRetryDelays.sleep } : {}
8021
8039
  });
8022
8040
  }
8041
+ /**
8042
+ * Resource types that have NO CloudFormation registry schema, so
8043
+ * `DescribeType` can only ever fail for them:
8044
+ *
8045
+ * - `Custom::<Name>` — the two-segment form the `TypeName` parameter
8046
+ * rejects outright at validation time.
8047
+ * - `AWS::CloudFormation::CustomResource` — the generic custom-resource
8048
+ * alias; replacement semantics are handler-driven, not schema-driven.
8049
+ * - `AWS::CDK::Metadata` — the CDK-injected construct-tree marker. It is a
8050
+ * synth-only sentinel that cdkd never provisions (the deploy pre-flight,
8051
+ * the diff, `synth`, `import` and `export` all filter it), yet the
8052
+ * create-only schema PREFETCH iterated the raw template type set and so
8053
+ * issued a guaranteed-to-fail `DescribeType` for it on EVERY deploy —
8054
+ * burning one API call and emitting a "Grant cloudformation:DescribeType"
8055
+ * warning that named a pseudo-resource the user cannot act on.
8056
+ *
8057
+ * Callers must short-circuit on this predicate rather than paying the round
8058
+ * trip plus the misleading warning. Kept next to
8059
+ * {@link describeTypeWithThrottleRetry} so every DescribeType-backed
8060
+ * resolver shares ONE list instead of re-deriving its own inline literal.
8061
+ */
8062
+ function hasNoRegistrySchema(resourceType) {
8063
+ return resourceType === "AWS::CDK::Metadata" || resourceType === "AWS::CloudFormation::CustomResource" || resourceType.startsWith("Custom::");
8064
+ }
8023
8065
 
8024
8066
  //#endregion
8025
8067
  //#region src/provisioning/create-only-properties.ts
@@ -8083,7 +8125,7 @@ const createOnlyPropertiesCache = /* @__PURE__ */ new Map();
8083
8125
  * (a transient throttle must not poison the deploy's replacement detection).
8084
8126
  */
8085
8127
  function getCreateOnlyPropertyPaths(resourceType) {
8086
- if (isCustomResourceType(resourceType)) return Promise.resolve([]);
8128
+ if (hasNoRegistrySchema(resourceType)) return Promise.resolve([]);
8087
8129
  const cached = createOnlyPropertiesCache.get(resourceType);
8088
8130
  if (cached) return cached;
8089
8131
  const entry = fetchCreateOnlyPropertyPaths(resourceType).catch((error) => {
@@ -8096,15 +8138,6 @@ function getCreateOnlyPropertyPaths(resourceType) {
8096
8138
  return entry;
8097
8139
  }
8098
8140
  /**
8099
- * True for the two custom-resource type shapes CloudFormation accepts:
8100
- * `AWS::CloudFormation::CustomResource` and anything under the `Custom::`
8101
- * prefix. Neither has a registry schema, so schema-driven lookups
8102
- * (DescribeType) must be skipped for them.
8103
- */
8104
- function isCustomResourceType(resourceType) {
8105
- return resourceType === "AWS::CloudFormation::CustomResource" || resourceType.startsWith("Custom::");
8106
- }
8107
- /**
8108
8141
  * Decide whether a change to top-level property `topLevelKey` requires
8109
8142
  * replacement per the schema's createOnly paths.
8110
8143
  *
@@ -11340,6 +11373,7 @@ const writeOnlyPropertiesCache = /* @__PURE__ */ new Map();
11340
11373
  * DescribeType (a transient throttle must not poison the deploy).
11341
11374
  */
11342
11375
  function getTopLevelWriteOnlyProperties(resourceType) {
11376
+ if (hasNoRegistrySchema(resourceType)) return Promise.resolve(/* @__PURE__ */ new Set());
11343
11377
  const cached = writeOnlyPropertiesCache.get(resourceType);
11344
11378
  if (cached) return cached;
11345
11379
  const entry = fetchTopLevelWriteOnlyProperties(resourceType).catch((error) => {
@@ -11905,7 +11939,7 @@ var CloudControlProvider = class {
11905
11939
  this.logger.debug(`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`);
11906
11940
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
11907
11941
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
11908
- const { ASGProvider } = await import("./asg-provider-_vnp1pfL.js").then((n) => n.n);
11942
+ const { ASGProvider } = await import("./asg-provider-gaXfXSH0.js").then((n) => n.n);
11909
11943
  await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
11910
11944
  return;
11911
11945
  }
@@ -17617,7 +17651,7 @@ const FLUSH_INTERVAL_MS = 2e3;
17617
17651
  const FLUSH_EVENT_THRESHOLD = 50;
17618
17652
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
17619
17653
  function getCdkdVersion() {
17620
- return "0.268.1";
17654
+ return "0.268.2";
17621
17655
  }
17622
17656
  /**
17623
17657
  * Generate a time-sortable unique run id, e.g.
@@ -17721,11 +17755,33 @@ var DeploymentEventsStore = class {
17721
17755
  }
17722
17756
  if (this.events.length === 0) return;
17723
17757
  await this.enqueueWrite(async () => {
17758
+ const indexRead = this.readIndexRuns();
17759
+ indexRead.catch(() => {});
17724
17760
  await this.doFlush();
17725
- const keptRunIds = await this.updateIndex(result);
17726
- await this.pruneSupersededRunFiles(keptRunIds);
17761
+ await this.writeIndexAndPrune(result, await indexRead);
17727
17762
  });
17728
17763
  }
17764
+ /**
17765
+ * Second half of {@link finalize}'s write: build + PUT the index, then
17766
+ * delete the run streams that fell out of the retained window.
17767
+ *
17768
+ * The prune's LIST is issued concurrently with the index PUT — the cutoff
17769
+ * is derived from `runs` (already known before the PUT), the LIST is
17770
+ * read-only, and the DELETE still happens strictly AFTER the PUT resolves.
17771
+ * So the on-S3 ordering is unchanged (a stream is only deleted once the
17772
+ * index that dropped it is durable); only the round trip is overlapped.
17773
+ */
17774
+ async writeIndexAndPrune(result, existingRuns) {
17775
+ const { key, file, runs } = this.buildIndexUpdate(result, existingRuns);
17776
+ const keptRunIds = runs.map((r) => r.runId);
17777
+ const willPrune = keptRunIds.length >= 20;
17778
+ const dirPrefix = deploymentsDirPrefix(this.backend.prefix, this.stackName, this.region);
17779
+ const staleKeysRead = willPrune ? this.backend.listRawKeys(dirPrefix) : void 0;
17780
+ staleKeysRead?.catch(() => {});
17781
+ await this.backend.putRawObject(key, JSON.stringify(file, null, 2));
17782
+ if (!staleKeysRead) return;
17783
+ await this.pruneSupersededRunFiles(keptRunIds, dirPrefix, await staleKeysRead);
17784
+ }
17729
17785
  /** Await any in-flight async flushes (used by tests). */
17730
17786
  async drain() {
17731
17787
  await this.writeChain;
@@ -17756,27 +17812,40 @@ var DeploymentEventsStore = class {
17756
17812
  this.persistedCount = snapshotCount;
17757
17813
  }
17758
17814
  /**
17759
- * Prepend this run's summary to `deployments/index.json`, truncated to
17760
- * the last {@link DEPLOYMENT_EVENTS_MAX_INDEX_RUNS} runs. Read-modify-
17761
- * write WITHOUT optimistic locking last-writer-wins (documented
17762
- * trade-off; the per-run `.jsonl` files are the source of truth).
17815
+ * READ half of the index read-modify-write. Returns the currently indexed
17816
+ * run summaries, or an empty list when the index is absent / corrupt /
17817
+ * unreadable (in which case the write half rebuilds from this run alone —
17818
+ * the .jsonl files remain readable directly via `cdkd events --run`).
17763
17819
  *
17764
- * Returns the run ids retained in the index (newest-first), which the
17765
- * caller feeds to {@link pruneSupersededRunFiles} so the `.jsonl` files
17766
- * stay bounded to the same window as the index.
17820
+ * Split out of the former single `updateIndex` so {@link finalize} can
17821
+ * issue it CONCURRENTLY with the event-stream flush: the two touch
17822
+ * different objects and the read does not depend on the flush.
17767
17823
  */
17768
- async updateIndex(result) {
17824
+ async readIndexRuns() {
17769
17825
  const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
17770
- let existingRuns = [];
17771
17826
  try {
17772
17827
  const raw = await this.backend.getRawObject(key);
17773
17828
  if (raw !== null) {
17774
17829
  const parsed = JSON.parse(raw);
17775
- if (Array.isArray(parsed.runs)) existingRuns = parsed.runs;
17830
+ if (Array.isArray(parsed.runs)) return parsed.runs;
17776
17831
  }
17777
17832
  } catch (err) {
17778
17833
  this.logger.debug(`Deployment-events index unreadable, rewriting: ${err instanceof Error ? err.message : String(err)}`);
17779
17834
  }
17835
+ return [];
17836
+ }
17837
+ /**
17838
+ * MODIFY half of the index read-modify-write (pure): prepend this run's
17839
+ * summary to `existingRuns`, truncated to the last
17840
+ * {@link DEPLOYMENT_EVENTS_MAX_INDEX_RUNS} runs. No optimistic locking —
17841
+ * last-writer-wins (documented trade-off; the per-run `.jsonl` files are
17842
+ * the source of truth).
17843
+ *
17844
+ * `runs` (newest-first) doubles as the retained-run window that
17845
+ * {@link pruneSupersededRunFiles} bounds the `.jsonl` files to.
17846
+ */
17847
+ buildIndexUpdate(result, existingRuns) {
17848
+ const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
17780
17849
  const runs = [{
17781
17850
  runId: this.runId,
17782
17851
  command: this.command,
@@ -17786,15 +17855,17 @@ var DeploymentEventsStore = class {
17786
17855
  result,
17787
17856
  eventCount: this.persistedCount
17788
17857
  }, ...existingRuns.filter((r) => r.runId !== this.runId)].slice(0, 20);
17789
- const file = {
17790
- indexVersion: 1,
17791
- stackName: this.stackName,
17792
- region: this.region,
17793
- runs,
17794
- lastModified: Date.now()
17858
+ return {
17859
+ key,
17860
+ file: {
17861
+ indexVersion: 1,
17862
+ stackName: this.stackName,
17863
+ region: this.region,
17864
+ runs,
17865
+ lastModified: Date.now()
17866
+ },
17867
+ runs
17795
17868
  };
17796
- await this.backend.putRawObject(key, JSON.stringify(file, null, 2));
17797
- return runs.map((r) => r.runId);
17798
17869
  }
17799
17870
  /**
17800
17871
  * Self-bounding prune (issue #885): delete `{runId}.jsonl` streams that
@@ -17811,12 +17882,15 @@ var DeploymentEventsStore = class {
17811
17882
  * runs finalized while it ran — an extreme edge that self-heals anyway,
17812
17883
  * since the whole JSONL body is re-PUT on that run's next flush / finalize
17813
17884
  * (S3 has no append; each flush rewrites the full stream).
17885
+ *
17886
+ * `dirPrefix` + `keys` are supplied by the caller so the LIST can be
17887
+ * overlapped with the index PUT (see {@link writeIndexAndPrune}); the
17888
+ * DELETE this method issues still runs strictly after that PUT.
17814
17889
  */
17815
- async pruneSupersededRunFiles(keptRunIds) {
17890
+ async pruneSupersededRunFiles(keptRunIds, dirPrefix, keys) {
17816
17891
  if (keptRunIds.length < 20) return;
17817
17892
  const cutoff = keptRunIds.reduce((min, id) => id < min ? id : min, keptRunIds[0]);
17818
- const dirPrefix = deploymentsDirPrefix(this.backend.prefix, this.stackName, this.region);
17819
- const stale = (await this.backend.listRawKeys(dirPrefix)).filter((k) => {
17893
+ const stale = keys.filter((k) => {
17820
17894
  const runId = runIdFromJsonlKey(k, dirPrefix);
17821
17895
  return runId !== null && runId < cutoff;
17822
17896
  });
@@ -18426,7 +18500,7 @@ var DeployEngine = class {
18426
18500
  async doDeploy(stackName, template) {
18427
18501
  const startTime = Date.now();
18428
18502
  this.logger.debug(`Starting deployment for stack: ${stackName}`);
18429
- for (const type of new Set(Object.values(template.Resources).map((r) => r.Type))) getCreateOnlyPropertyPaths(type).catch(() => {});
18503
+ for (const type of new Set(Object.values(template.Resources).map((r) => r.Type).filter((type) => !hasNoRegistrySchema(type)))) getCreateOnlyPropertyPaths(type).catch(() => {});
18430
18504
  await this.lockManager.acquireLockWithRetry(stackName, this.stackRegion, void 0, "deploy");
18431
18505
  const renderer = getLiveRenderer();
18432
18506
  renderer.start();
@@ -18453,6 +18527,7 @@ var DeployEngine = class {
18453
18527
  const currentEtag = currentStateData?.etag;
18454
18528
  const migrationPending = currentStateData?.migrationPending ?? false;
18455
18529
  this.logger.debug(`Loaded current state: ${Object.keys(currentState.resources).length} resources`);
18530
+ if (this.options.onCurrentStateLoaded) await this.options.onCurrentStateLoaded(stackName, currentStateData?.state);
18456
18531
  try {
18457
18532
  const journal = await this.stateBackend.loadRollbackJournal(stackName, this.stackRegion);
18458
18533
  if (journal && journal.segments.length > 0) {
@@ -18566,8 +18641,7 @@ var DeployEngine = class {
18566
18641
  await this.drainObservedCaptures(newState.resources);
18567
18642
  const newEtag = await this.stateBackend.saveState(stackName, this.stackRegion, this.withParentInfo(newState));
18568
18643
  this.logger.debug(`State saved (ETag: ${newEtag})`);
18569
- await this.deleteRollbackJournalBestEffort(stackName);
18570
- if (this.exportIndexStore) await this.exportIndexStore.updateForStack(stackName, this.stackRegion, newState.outputs ?? {});
18644
+ await Promise.all([this.deleteRollbackJournalBestEffort(stackName), this.exportIndexStore ? this.exportIndexStore.updateForStack(stackName, this.stackRegion, newState.outputs ?? {}) : Promise.resolve()]);
18571
18645
  const durationMs = Date.now() - startTime;
18572
18646
  const unchangedCount = this.diffCalculator.filterByType(changes, "NO_CHANGE").length + actualCounts.skipped;
18573
18647
  return {
@@ -19622,5 +19696,5 @@ var DeployEngine = class {
19622
19696
  };
19623
19697
 
19624
19698
  //#endregion
19625
- export { WorkGraph as $, MissingCdkCliError as $t, slowCcOperationTimeoutMs as A, warnDeprecatedNoPrefixCliFlag as At, applyRoleArnIfSet as B, resolveBucketRegion as Bt, yellow as C, resolveAutoAssetStorage as Ct, ProviderRegistry as D, resolveStateBucketWithDefaultAndSource as Dt, clearOnUpdateRemoval as E, resolveStateBucketWithDefault as Et, refStateLookupFromResource as F, uploadCfnTemplate as Ft, DagBuilder as G, AssetError as Gt, describeTypeWithThrottleRetry as H, getAwsClients as Ht, WAFv2WebACLProvider as I, expectedOwnerParam as It, S3StateBackend as J, DependencyError as Jt, TemplateParser as K, CdkdError as Kt, normalizeAwsTagsToCfn as L, AssemblyReader as Lt, isTerminationProtectionPropagationError as M, CFN_TEMPLATE_URL_LIMIT as Mt, IntrinsicFunctionResolver as N, MIGRATE_TMP_PREFIX as Nt, findActionableSilentDrops as O, resolveUseCdkBootstrapAssets as Ot, cfnRefValueFromPhysicalId as P, findLargeInlineResources as Pt, stringifyValue as Q, LockError as Qt, resolveExplicitPhysicalId as R, processStackMessages as Rt, red as S, resolveApp as St, collectInlinePolicyNamesManagedBySiblings as T, resolveSkipPrefix as Tt, withRetry as U, resetAwsClients as Ut, DiffCalculator as V, AwsClients as Vt, isRetryableTransientError as W, setAwsClients as Wt, shouldRetainResource as X, LocalMigrateError as Xt, rebuildClientForBucketRegion as Y, LocalInvokeBuildError as Yt, AssetPublisher as Z, LocalStartServiceError as Zt, formatResourceLine as _, getDockerImageBySourceHash as _t, DeploymentEventsStore as a, StackHasActiveImportsError as an, BOOTSTRAP_MARKER_PREFIX as at, gray as b, getDefaultStateBucketName as bt, replayFailedOperations as c, SynthesisError as cn, parseBootstrapMarker as ct, IMPLICIT_DELETE_DEPENDENCIES as d, normalizeAwsError as dn, buildDockerImage as dt, NestedStackChildDirectDestroyError as en, buildAssetRedirectMap as et, computeImplicitDeleteEdges as f, withErrorHandling as fn, formatDockerLoginError as ft, renderStatefulReason as g, AssetManifestLoader as gt, isStatefulRecreateTargetSync as h, runDockerStreaming as ht, DeploymentEventsReader as i, ResourceUpdateNotSupportedError as in, AssetModeResolver as it, disableInstanceApiTermination as j, CFN_TEMPLATE_BODY_LIMIT as jt, CloudControlProvider as k, stateBucketExistenceConfirmed as kt, replayRollback as l, formatError as ln, validateAssetBucketName as lt, MULTI_REGION_RECREATE_BLOCKED_TYPES as m, runDockerForeground as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, ProvisioningError as nn, loadPublishableAssetManifest as nt, planFailedOps as o, StackTerminationProtectionError as on, ensureAssetStorage as ot, extractDeploymentEventError as p, __exportAll as pn, getDockerCmd as pt, LockManager as q, ConfigError as qt, DeployEngine as r, ResourceTimeoutError as rn, rewriteTemplateAssetReferences as rt, planRollback as s, StateError as sn, getBootstrapMarkerKey as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, PartialFailureError as tn, createAssetRedirectResolver as tt, withResourceDeadline as u, isCdkdError as un, validateContainerRepoName as ut, bold as v, Synthesizer as vt, IAMRoleProvider as w, resolveCaptureObservedState as wt, green as x, getLegacyStateBucketName as xt, cyan as y, synthesisStatusMessage as yt, assertRegionMatch as z, clearBucketRegionCache as zt };
19626
- //# sourceMappingURL=deploy-engine-A2CeJkZr.js.map
19699
+ export { WorkGraph as $, LockError as $t, slowCcOperationTimeoutMs as A, warnDeprecatedNoPrefixCliFlag as At, applyRoleArnIfSet as B, resolveBucketRegion as Bt, yellow as C, resolveAutoAssetStorage as Ct, ProviderRegistry as D, resolveStateBucketWithDefaultAndSource as Dt, clearOnUpdateRemoval as E, resolveStateBucketWithDefault as Et, refStateLookupFromResource as F, uploadCfnTemplate as Ft, DagBuilder as G, AssetError as Gt, describeTypeWithThrottleRetry as H, getAwsClients as Ht, WAFv2WebACLProvider as I, expectedOwnerParam as It, S3StateBackend as J, DependencyError as Jt, TemplateParser as K, CdkdError as Kt, normalizeAwsTagsToCfn as L, AssemblyReader as Lt, isTerminationProtectionPropagationError as M, CFN_TEMPLATE_URL_LIMIT as Mt, IntrinsicFunctionResolver as N, MIGRATE_TMP_PREFIX as Nt, findActionableSilentDrops as O, resolveUseCdkBootstrapAssets as Ot, cfnRefValueFromPhysicalId as P, findLargeInlineResources as Pt, stringifyValue as Q, LocalStartServiceError as Qt, resolveExplicitPhysicalId as R, processStackMessages as Rt, red as S, resolveApp as St, collectInlinePolicyNamesManagedBySiblings as T, resolveSkipPrefix as Tt, withRetry as U, resetAwsClients as Ut, DiffCalculator as V, AwsClients as Vt, isRetryableTransientError as W, setAwsClients as Wt, shouldRetainResource as X, LocalInvokeBuildError as Xt, rebuildClientForBucketRegion as Y, DeployCancelledError as Yt, AssetPublisher as Z, LocalMigrateError as Zt, formatResourceLine as _, getDockerImageBySourceHash as _t, DeploymentEventsStore as a, ResourceUpdateNotSupportedError as an, BOOTSTRAP_MARKER_PREFIX as at, gray as b, getDefaultStateBucketName as bt, replayFailedOperations as c, StateError as cn, parseBootstrapMarker as ct, IMPLICIT_DELETE_DEPENDENCIES as d, isCdkdError as dn, buildDockerImage as dt, MissingCdkCliError as en, buildAssetRedirectMap as et, computeImplicitDeleteEdges as f, normalizeAwsError as fn, formatDockerLoginError as ft, renderStatefulReason as g, AssetManifestLoader as gt, isStatefulRecreateTargetSync as h, runDockerStreaming as ht, DeploymentEventsReader as i, ResourceTimeoutError as in, AssetModeResolver as it, disableInstanceApiTermination as j, CFN_TEMPLATE_BODY_LIMIT as jt, CloudControlProvider as k, stateBucketExistenceConfirmed as kt, replayRollback as l, SynthesisError as ln, validateAssetBucketName as lt, MULTI_REGION_RECREATE_BLOCKED_TYPES as m, __exportAll as mn, runDockerForeground as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, PartialFailureError as nn, loadPublishableAssetManifest as nt, planFailedOps as o, StackHasActiveImportsError as on, ensureAssetStorage as ot, extractDeploymentEventError as p, withErrorHandling as pn, getDockerCmd as pt, LockManager as q, ConfigError as qt, DeployEngine as r, ProvisioningError as rn, rewriteTemplateAssetReferences as rt, planRollback as s, StackTerminationProtectionError as sn, getBootstrapMarkerKey as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, NestedStackChildDirectDestroyError as tn, createAssetRedirectResolver as tt, withResourceDeadline as u, formatError as un, validateContainerRepoName as ut, bold as v, Synthesizer as vt, IAMRoleProvider as w, resolveCaptureObservedState as wt, green as x, getLegacyStateBucketName as xt, cyan as y, synthesisStatusMessage as yt, assertRegionMatch as z, clearBucketRegionCache as zt };
19700
+ //# sourceMappingURL=deploy-engine-BEjF-h_6.js.map