deepline 0.2.49 → 0.2.51
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/bundling-sources/sdk/src/client.ts +15 -5
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +19 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +6 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +61 -0
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +35 -7
- package/dist/bundling-sources/shared_libs/plays/enrich-compat-adapter.ts +21 -0
- package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +1555 -0
- package/dist/bundling-sources/shared_libs/plays/user-code-safety.ts +61 -0
- package/dist/cli/index.js +111 -15
- package/dist/cli/index.mjs +114 -16
- package/dist/{compiler-manifest-BPA3r-VG.d.mts → compiler-manifest-Cj3--4ZJ.d.mts} +14 -0
- package/dist/{compiler-manifest-BPA3r-VG.d.ts → compiler-manifest-Cj3--4ZJ.d.ts} +14 -0
- package/dist/index.d.mts +24 -4
- package/dist/index.d.ts +24 -4
- package/dist/index.js +3 -2
- package/dist/index.mjs +3 -2
- package/dist/install-integrity.json +5 -2
- package/dist/plays/bundle-play-file.d.mts +4 -2
- package/dist/plays/bundle-play-file.d.ts +4 -2
- package/dist/plays/bundle-play-file.mjs +32 -6
- package/package.json +1 -1
|
@@ -711,6 +711,7 @@ export type MonitorListEntry = {
|
|
|
711
711
|
webhook_state?: string;
|
|
712
712
|
last_received_event?: string | null;
|
|
713
713
|
bound_plays?: Array<Record<string, unknown>>;
|
|
714
|
+
consumer_health_truncated?: boolean;
|
|
714
715
|
[key: string]: unknown;
|
|
715
716
|
};
|
|
716
717
|
|
|
@@ -726,6 +727,8 @@ export type MonitorsListResult = {
|
|
|
726
727
|
is_truncated?: boolean;
|
|
727
728
|
next_cursor?: string | null;
|
|
728
729
|
status_filter_applied?: string;
|
|
730
|
+
status_summary?: Array<{ status: string; count: number }>;
|
|
731
|
+
include_consumers?: boolean;
|
|
729
732
|
[key: string]: unknown;
|
|
730
733
|
};
|
|
731
734
|
|
|
@@ -737,6 +740,8 @@ export type MonitorsListOptions = {
|
|
|
737
740
|
/** Page past a truncated result using a prior response's `next_cursor`. */
|
|
738
741
|
cursor?: string;
|
|
739
742
|
compact?: boolean;
|
|
743
|
+
/** Include bounded current SQL-listener delivery/run health (requires limit <= 20). */
|
|
744
|
+
includeConsumers?: boolean;
|
|
740
745
|
};
|
|
741
746
|
|
|
742
747
|
/**
|
|
@@ -814,9 +819,9 @@ export type MonitorsNamespace = {
|
|
|
814
819
|
definition: MonitorDefinition,
|
|
815
820
|
options?: { dryRun?: boolean },
|
|
816
821
|
) => Promise<MonitorDeployResult>;
|
|
817
|
-
/** List deployed monitors (active by default). */
|
|
822
|
+
/** List deployed monitors (active by default). `includeConsumers` requires limit <= 20. */
|
|
818
823
|
list: (options?: MonitorsListOptions) => Promise<MonitorsListResult>;
|
|
819
|
-
/** Fetch one deployed monitor by public key
|
|
824
|
+
/** Fetch one deployed monitor by public key with bounded current listener health. */
|
|
820
825
|
get: (key: string) => Promise<MonitorDetail>;
|
|
821
826
|
/**
|
|
822
827
|
* Test a deployed monitor. `validationOnly` safely verifies the callback
|
|
@@ -825,7 +830,7 @@ export type MonitorsNamespace = {
|
|
|
825
830
|
test: (
|
|
826
831
|
key: string,
|
|
827
832
|
payload: Record<string, unknown>,
|
|
828
|
-
options?: { validationOnly?: boolean },
|
|
833
|
+
options?: { validationOnly?: boolean; dispatch?: boolean },
|
|
829
834
|
) => Promise<MonitorTestResult>;
|
|
830
835
|
validate: (key: string) => Promise<MonitorValidateResult>;
|
|
831
836
|
/** List the published plays depending on one monitor's output streams. */
|
|
@@ -4531,6 +4536,7 @@ export class DeeplineClient {
|
|
|
4531
4536
|
params.set('limit', String(options.limit));
|
|
4532
4537
|
if (options?.cursor) params.set('cursor', options.cursor);
|
|
4533
4538
|
if (options?.compact) params.set('compact', 'true');
|
|
4539
|
+
if (options?.includeConsumers) params.set('include_consumers', 'true');
|
|
4534
4540
|
const query = params.toString();
|
|
4535
4541
|
// Single interpolation only — see availableMonitors: a nested template in
|
|
4536
4542
|
// the path confuses the SDK/API contract path extractor.
|
|
@@ -4552,7 +4558,7 @@ export class DeeplineClient {
|
|
|
4552
4558
|
async testMonitorWebhook(
|
|
4553
4559
|
key: string,
|
|
4554
4560
|
payload: Record<string, unknown>,
|
|
4555
|
-
options?: { validationOnly?: boolean },
|
|
4561
|
+
options?: { validationOnly?: boolean; dispatch?: boolean },
|
|
4556
4562
|
): Promise<MonitorTestResult> {
|
|
4557
4563
|
return this.http.request<MonitorTestResult>(
|
|
4558
4564
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/test`,
|
|
@@ -4560,7 +4566,11 @@ export class DeeplineClient {
|
|
|
4560
4566
|
method: 'POST',
|
|
4561
4567
|
body: {
|
|
4562
4568
|
payload,
|
|
4563
|
-
...(options?.validationOnly
|
|
4569
|
+
...(options?.validationOnly
|
|
4570
|
+
? { mode: 'validation_only' }
|
|
4571
|
+
: options?.dispatch
|
|
4572
|
+
? { mode: 'dispatch' }
|
|
4573
|
+
: {}),
|
|
4564
4574
|
},
|
|
4565
4575
|
},
|
|
4566
4576
|
);
|
|
@@ -160,7 +160,7 @@ export const SDK_RELEASE = {
|
|
|
160
160
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
161
161
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
162
162
|
// release keeps lazy paging semantics independent of row residency.
|
|
163
|
-
version: '0.2.
|
|
163
|
+
version: '0.2.51',
|
|
164
164
|
contracts: {
|
|
165
165
|
api: {
|
|
166
166
|
name: 'sdk-http-api',
|
|
@@ -1343,12 +1343,31 @@ export interface PlayCheckSqlListenerTrigger {
|
|
|
1343
1343
|
};
|
|
1344
1344
|
}
|
|
1345
1345
|
|
|
1346
|
+
/**
|
|
1347
|
+
* The input delivered to a SQL-listener Play invocation. One changed Customer
|
|
1348
|
+
* DB row starts one run with this top-level event object; it is not an events
|
|
1349
|
+
* array or a polling batch.
|
|
1350
|
+
*/
|
|
1351
|
+
export interface PlayCheckSqlListenerEventSummary {
|
|
1352
|
+
delivery: 'one_event_per_matched_row';
|
|
1353
|
+
fields: Array<
|
|
1354
|
+
| 'tool'
|
|
1355
|
+
| 'stream'
|
|
1356
|
+
| 'operation'
|
|
1357
|
+
| 'before'
|
|
1358
|
+
| 'after'
|
|
1359
|
+
| 'changedAt'
|
|
1360
|
+
| 'metadata'
|
|
1361
|
+
>;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1346
1364
|
/**
|
|
1347
1365
|
* Concise summary of the trigger bindings the server recognized for a play.
|
|
1348
1366
|
* Only present triggers are populated.
|
|
1349
1367
|
*/
|
|
1350
1368
|
export interface PlayCheckTriggersSummary {
|
|
1351
1369
|
sqlListeners?: PlayCheckSqlListenerTrigger[];
|
|
1370
|
+
sqlListenerEvent?: PlayCheckSqlListenerEventSummary;
|
|
1352
1371
|
cron?: { schedule: string; timezone?: string };
|
|
1353
1372
|
webhook?: true;
|
|
1354
1373
|
}
|
|
@@ -157,6 +157,7 @@ import {
|
|
|
157
157
|
validatePlayAuthoringField,
|
|
158
158
|
type PlayAuthoringContractEdition,
|
|
159
159
|
type PlaySqlQuery,
|
|
160
|
+
type PlayAuthoringRunScope,
|
|
160
161
|
type PlayAuthoringRuntimeContext,
|
|
161
162
|
} from '../plays/authoring-contract';
|
|
162
163
|
import {
|
|
@@ -1338,6 +1339,7 @@ type ScalarPlayAuthoringRuntimeContext = Pick<
|
|
|
1338
1339
|
PlayAuthoringRuntimeContext,
|
|
1339
1340
|
| 'tools'
|
|
1340
1341
|
| 'customerDb'
|
|
1342
|
+
| 'run'
|
|
1341
1343
|
| 'tool'
|
|
1342
1344
|
| 'step'
|
|
1343
1345
|
| 'fetch'
|
|
@@ -3332,6 +3334,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
3332
3334
|
return this.currentExecutionScope.logical.runId;
|
|
3333
3335
|
}
|
|
3334
3336
|
|
|
3337
|
+
get run(): PlayAuthoringRunScope {
|
|
3338
|
+
return { id: this.currentRunId };
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3335
3341
|
private get currentReceiptOwnerRunId(): string {
|
|
3336
3342
|
return this.currentExecutionScope.receipt.ownerRunId;
|
|
3337
3343
|
}
|
|
@@ -68,6 +68,7 @@ export const PLAY_AUTHORING_CONTRACT_ISSUE_CODES = [
|
|
|
68
68
|
'play_authoring_dynamic_identity_unvalidated',
|
|
69
69
|
'play_authoring_fetch_secret_requires_tls',
|
|
70
70
|
'play_authoring_fetch_idempotency_required',
|
|
71
|
+
'play_authoring_fetch_key_reused_in_loop',
|
|
71
72
|
'play_authoring_binding_invalid',
|
|
72
73
|
'play_authoring_input_schema_unresolved',
|
|
73
74
|
] as const;
|
|
@@ -215,8 +216,23 @@ export type PlayTriggerSqlListenerSummary = {
|
|
|
215
216
|
operations: string[];
|
|
216
217
|
where?: PlaySqlListenerWhere;
|
|
217
218
|
};
|
|
219
|
+
/** Author-facing shape of one SQL-listener invocation. */
|
|
220
|
+
export type PlayTriggerSqlListenerEventSummary = {
|
|
221
|
+
delivery: 'one_event_per_matched_row';
|
|
222
|
+
fields: Array<
|
|
223
|
+
| 'tool'
|
|
224
|
+
| 'stream'
|
|
225
|
+
| 'operation'
|
|
226
|
+
| 'before'
|
|
227
|
+
| 'after'
|
|
228
|
+
| 'changedAt'
|
|
229
|
+
| 'metadata'
|
|
230
|
+
>;
|
|
231
|
+
};
|
|
218
232
|
export type PlayTriggersSummary = {
|
|
219
233
|
sqlListeners?: PlayTriggerSqlListenerSummary[];
|
|
234
|
+
/** Present when the play has at least one sqlListener trigger. */
|
|
235
|
+
sqlListenerEvent?: PlayTriggerSqlListenerEventSummary;
|
|
220
236
|
cron?: { schedule: string; timezone?: string };
|
|
221
237
|
webhook?: true;
|
|
222
238
|
};
|
|
@@ -237,6 +253,18 @@ export function derivePlayTriggersSummary(
|
|
|
237
253
|
? { where: listener.where as PlaySqlListenerWhere }
|
|
238
254
|
: {}),
|
|
239
255
|
}));
|
|
256
|
+
summary.sqlListenerEvent = {
|
|
257
|
+
delivery: 'one_event_per_matched_row',
|
|
258
|
+
fields: [
|
|
259
|
+
'tool',
|
|
260
|
+
'stream',
|
|
261
|
+
'operation',
|
|
262
|
+
'before',
|
|
263
|
+
'after',
|
|
264
|
+
'changedAt',
|
|
265
|
+
'metadata',
|
|
266
|
+
],
|
|
267
|
+
};
|
|
240
268
|
}
|
|
241
269
|
if (bindings.cron?.schedule) {
|
|
242
270
|
summary.cron = bindings.cron.timezone
|
|
@@ -652,6 +680,7 @@ export const PLAY_AUTHORING_RUNTIME_CONTEXT_MEMBERS = [
|
|
|
652
680
|
'dataset',
|
|
653
681
|
'fetch',
|
|
654
682
|
'log',
|
|
683
|
+
'run',
|
|
655
684
|
'runPlay',
|
|
656
685
|
'runSteps',
|
|
657
686
|
'secrets',
|
|
@@ -743,6 +772,31 @@ export type PlayAuthoringRunStepsOptions = {
|
|
|
743
772
|
description?: string;
|
|
744
773
|
};
|
|
745
774
|
|
|
775
|
+
/**
|
|
776
|
+
* Stable identity of the currently executing Play invocation.
|
|
777
|
+
*
|
|
778
|
+
* The id is unchanged while Deepline resumes or retries the same durable run.
|
|
779
|
+
* A separately submitted run intentionally receives a new id.
|
|
780
|
+
*/
|
|
781
|
+
export type PlayAuthoringRunScope = {
|
|
782
|
+
readonly id: string;
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
/** Factual authoring guidance rendered into SDK and offline-agent references. */
|
|
786
|
+
export const PLAY_AUTHORING_DOCUMENTATION = {
|
|
787
|
+
fetchBatching: {
|
|
788
|
+
warning:
|
|
789
|
+
'A static ctx.fetch key inside a loop is a warning because every iteration must still have distinct method, URL, body, or safe headers. One durable receipt must never stand in for every request.',
|
|
790
|
+
guidance:
|
|
791
|
+
'Keep the static fetch label. For a mutating batch, make the body distinct and use a replay-stable external Idempotency-Key such as `${ctx.run.id}:signals:${batchIndex}`.',
|
|
792
|
+
},
|
|
793
|
+
runId: {
|
|
794
|
+
semantics:
|
|
795
|
+
'ctx.run.id is stable while Deepline retries or resumes one durable run. A separately submitted run receives a new id.',
|
|
796
|
+
use: 'Use it when deriving an external idempotency key for a sequence of batches.',
|
|
797
|
+
},
|
|
798
|
+
} as const;
|
|
799
|
+
|
|
746
800
|
/** The complete customer-authored `ctx` Interface shared by every Adapter. */
|
|
747
801
|
export interface PlayAuthoringRuntimeContext {
|
|
748
802
|
/**
|
|
@@ -776,6 +830,12 @@ export interface PlayAuthoringRuntimeContext {
|
|
|
776
830
|
>,
|
|
777
831
|
): never;
|
|
778
832
|
|
|
833
|
+
/**
|
|
834
|
+
* Identity for this durable run. Use this to build a replay-stable external
|
|
835
|
+
* idempotency key, for example when posting a sequence of batches.
|
|
836
|
+
*/
|
|
837
|
+
readonly run: PlayAuthoringRunScope;
|
|
838
|
+
|
|
779
839
|
tools: {
|
|
780
840
|
/**
|
|
781
841
|
* Execute a provider tool through the durable receipt contract.
|
|
@@ -2294,6 +2354,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
2294
2354
|
' csv<T = Record<string, unknown>>(path: string | CsvInput<T & object>, options?: CsvOptions): Promise<PlayDataset<T>>;',
|
|
2295
2355
|
' dataset<TSource extends PlayDatasetInput<object>>(key: string, items: TSource): DatasetBuilder<PlayDatasetRow<TSource> & object, PlayDatasetRow<TSource> & object>;',
|
|
2296
2356
|
' map<TSource extends PlayDatasetInput<object>>(key: string, items: TSource, options?: DatasetDefinitionOptions<PlayDatasetRow<TSource> & object>): never;',
|
|
2357
|
+
' readonly run: { readonly id: string };',
|
|
2297
2358
|
` runSteps<TInput extends Record<string, unknown>, TOutput>(program: RunnableStepProgram<TInput, TOutput>, input: TInput, options?: { description?: ${cloudReferenceType('ctx.runSteps.options.description')} }): Promise<TOutput>;`,
|
|
2298
2359
|
' tools: { execute<K extends string>(request: ToolExecutionRequest<K>): Promise<ToolExecutionOutput<K>> };',
|
|
2299
2360
|
` customerDb: { query<TRow extends Record<string, unknown> = Record<string, unknown>>(statement: SqlQuery, options?: { maxRows?: ${cloudReferenceType('ctx.customerDb.query.options.maxRows')}; timeoutMs?: ${cloudReferenceType('ctx.customerDb.query.options.timeoutMs')} }): Promise<TRow[]> };`,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
join,
|
|
11
11
|
relative,
|
|
12
12
|
resolve,
|
|
13
|
+
sep,
|
|
13
14
|
} from 'node:path';
|
|
14
15
|
import { builtinModules } from 'node:module';
|
|
15
16
|
import { Parser } from 'acorn';
|
|
@@ -94,6 +95,8 @@ export type PlayLocalFileDiscoveryResult = {
|
|
|
94
95
|
|
|
95
96
|
export type PlayBundlingAdapter = {
|
|
96
97
|
projectRoot: string;
|
|
98
|
+
/** Optional root used only to make source-graph identity independent of temporary absolute paths. */
|
|
99
|
+
sourceIdentityRoot?: string;
|
|
97
100
|
nodeModulesDir: string;
|
|
98
101
|
cacheDir?: string;
|
|
99
102
|
sdkSourceRoot: string;
|
|
@@ -179,6 +182,24 @@ function sha256(value: string): string {
|
|
|
179
182
|
return createHash('sha256').update(value).digest('hex');
|
|
180
183
|
}
|
|
181
184
|
|
|
185
|
+
function sourceIdentityPath(
|
|
186
|
+
filePath: string,
|
|
187
|
+
adapter: PlayBundlingAdapter,
|
|
188
|
+
): string {
|
|
189
|
+
if (!adapter.sourceIdentityRoot) return filePath;
|
|
190
|
+
const identityRoot = resolve(adapter.sourceIdentityRoot);
|
|
191
|
+
const logicalPath = relative(identityRoot, resolve(filePath));
|
|
192
|
+
if (
|
|
193
|
+
!logicalPath ||
|
|
194
|
+
logicalPath === '..' ||
|
|
195
|
+
logicalPath.startsWith(`..${sep}`) ||
|
|
196
|
+
isAbsolute(logicalPath)
|
|
197
|
+
) {
|
|
198
|
+
return filePath;
|
|
199
|
+
}
|
|
200
|
+
return logicalPath.split(/[\\/]+/).join('/');
|
|
201
|
+
}
|
|
202
|
+
|
|
182
203
|
function formatEsbuildMessage(message: Message): string {
|
|
183
204
|
const location = message.location
|
|
184
205
|
? `${message.location.file}:${message.location.line}:${message.location.column}`
|
|
@@ -1598,9 +1619,12 @@ async function analyzeSourceGraph(
|
|
|
1598
1619
|
const sourceHash = sha256(sourceCode);
|
|
1599
1620
|
const graphHash = sha256(
|
|
1600
1621
|
JSON.stringify({
|
|
1601
|
-
entryFile: absoluteEntryFile,
|
|
1622
|
+
entryFile: sourceIdentityPath(absoluteEntryFile, adapter),
|
|
1602
1623
|
localFiles: [...localFiles.entries()]
|
|
1603
|
-
.map(([filePath, contents]) => ({
|
|
1624
|
+
.map(([filePath, contents]) => ({
|
|
1625
|
+
filePath: sourceIdentityPath(filePath, adapter),
|
|
1626
|
+
hash: sha256(contents),
|
|
1627
|
+
}))
|
|
1604
1628
|
.sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
1605
1629
|
nodeBuiltins: [...nodeBuiltins].sort(),
|
|
1606
1630
|
packages: [...packages.entries()]
|
|
@@ -1608,7 +1632,7 @@ async function analyzeSourceGraph(
|
|
|
1608
1632
|
.sort((left, right) => left.name.localeCompare(right.name)),
|
|
1609
1633
|
importedPlayDependencies: [...importedPlayDependencies.values()]
|
|
1610
1634
|
.map((dependency) => ({
|
|
1611
|
-
filePath: dependency.filePath,
|
|
1635
|
+
filePath: sourceIdentityPath(dependency.filePath, adapter),
|
|
1612
1636
|
playName: dependency.playName,
|
|
1613
1637
|
}))
|
|
1614
1638
|
.sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
@@ -1660,7 +1684,7 @@ function artifactCachePath(
|
|
|
1660
1684
|
adapter: PlayBundlingAdapter,
|
|
1661
1685
|
): string {
|
|
1662
1686
|
return join(
|
|
1663
|
-
adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
|
|
1687
|
+
/* turbopackIgnore: true */ adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
|
|
1664
1688
|
`${graphHash}.${artifactKind}.json`,
|
|
1665
1689
|
);
|
|
1666
1690
|
}
|
|
@@ -1672,7 +1696,11 @@ async function readArtifactCache(
|
|
|
1672
1696
|
): Promise<PlayBundleArtifact | null> {
|
|
1673
1697
|
try {
|
|
1674
1698
|
const serialized = await readFile(
|
|
1675
|
-
artifactCachePath(
|
|
1699
|
+
/* turbopackIgnore: true */ artifactCachePath(
|
|
1700
|
+
graphHash,
|
|
1701
|
+
artifactKind,
|
|
1702
|
+
adapter,
|
|
1703
|
+
),
|
|
1676
1704
|
'utf-8',
|
|
1677
1705
|
);
|
|
1678
1706
|
return JSON.parse(serialized) as PlayBundleArtifact;
|
|
@@ -1686,9 +1714,9 @@ async function writeArtifactCache(
|
|
|
1686
1714
|
adapter: PlayBundlingAdapter,
|
|
1687
1715
|
): Promise<void> {
|
|
1688
1716
|
const cacheDir = adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR;
|
|
1689
|
-
await mkdir(cacheDir, { recursive: true });
|
|
1717
|
+
await mkdir(/* turbopackIgnore: true */ cacheDir, { recursive: true });
|
|
1690
1718
|
await writeFile(
|
|
1691
|
-
artifactCachePath(
|
|
1719
|
+
/* turbopackIgnore: true */ artifactCachePath(
|
|
1692
1720
|
artifact.graphHash,
|
|
1693
1721
|
artifact.artifactKind ?? PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
1694
1722
|
adapter,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const ENRICH_COMPAT_DEFAULT_PLAY_NAME = 'deepline-enrich-v1-compat';
|
|
2
|
+
export const ENRICH_COMPAT_DEFAULT_MAP_NAME = 'deepline_enrich_rows';
|
|
3
|
+
|
|
4
|
+
export type EnrichCompatibilityOptions = {
|
|
5
|
+
playName?: string;
|
|
6
|
+
mapName?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type EnrichCompatibilityPlan = {
|
|
10
|
+
playName: string;
|
|
11
|
+
mapName: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function buildEnrichCompatibilityPlan(
|
|
15
|
+
options: EnrichCompatibilityOptions = {},
|
|
16
|
+
): EnrichCompatibilityPlan {
|
|
17
|
+
return {
|
|
18
|
+
playName: options.playName?.trim() || ENRICH_COMPAT_DEFAULT_PLAY_NAME,
|
|
19
|
+
mapName: options.mapName?.trim() || ENRICH_COMPAT_DEFAULT_MAP_NAME,
|
|
20
|
+
};
|
|
21
|
+
}
|