dataiku-sdk 0.6.0 → 0.6.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.
- package/dist/packages/types/src/index.d.ts +21 -0
- package/dist/packages/types/src/index.js +7 -0
- package/dist/src/cli.js +1416 -112
- package/dist/src/index.d.ts +6 -6
- package/dist/src/index.js +3 -3
- package/dist/src/resources/datasets.d.ts +18 -0
- package/dist/src/resources/datasets.js +61 -0
- package/dist/src/resources/flow-zones.d.ts +1 -1
- package/dist/src/resources/flow-zones.js +3 -1
- package/dist/src/resources/jobs.d.ts +14 -0
- package/dist/src/resources/jobs.js +62 -3
- package/dist/src/resources/recipes.d.ts +27 -0
- package/dist/src/resources/recipes.js +138 -0
- package/dist/src/resources/scenarios.d.ts +38 -2
- package/dist/src/resources/scenarios.js +162 -3
- package/dist/src/schemas.d.ts +2 -2
- package/dist/src/schemas.js +1 -1
- package/dist/src/skill.d.ts +2 -2
- package/dist/src/skill.js +3 -3
- package/package.json +1 -1
- package/packages/types/dist/index.d.ts +21 -0
- package/packages/types/dist/index.js +7 -0
package/dist/src/index.d.ts
CHANGED
|
@@ -6,22 +6,22 @@ export { CodeEnvsResource, } from "./resources/code-envs.js";
|
|
|
6
6
|
export { type ConnectionSchemaListOptions, ConnectionsResource, type ConnectionTableListOptions, } from "./resources/connections.js";
|
|
7
7
|
export { DashboardsResource, } from "./resources/dashboards.js";
|
|
8
8
|
export { DataQualityResource, } from "./resources/data-quality.js";
|
|
9
|
-
export { type DatasetBuildValidationResult, type DatasetSchemaColumnInput, DatasetsResource, } from "./resources/datasets.js";
|
|
9
|
+
export { type DatasetBuildValidationResult, type DatasetCloneOptions, type DatasetCloneResult, type DatasetSchemaColumnInput, DatasetsResource, } from "./resources/datasets.js";
|
|
10
10
|
export { type FlowZoneItemInput, FlowZonesResource, } from "./resources/flow-zones.js";
|
|
11
11
|
export { FoldersResource, } from "./resources/folders.js";
|
|
12
12
|
export { FuturesResource, } from "./resources/futures.js";
|
|
13
13
|
export { InsightsResource, } from "./resources/insights.js";
|
|
14
|
-
export { computeNextPollDelayMs, type JobBuildAndWaitOptions, type JobBuildOptions, type JobBuildTarget, type JobBuildTargetType, type JobLogFilter, type JobLogSummary, JobsResource, } from "./resources/jobs.js";
|
|
14
|
+
export { computeNextPollDelayMs, type JobBuildAndWaitOptions, type JobBuildOptions, type JobBuildTarget, type JobBuildTargetType, type JobLogFilter, type JobLogProgress, type JobLogSummary, JobsResource, parseJobLogProgress, } from "./resources/jobs.js";
|
|
15
15
|
export { NotebooksResource, } from "./resources/notebooks.js";
|
|
16
16
|
export { type FlowMapResult, ProjectsResource, } from "./resources/projects.js";
|
|
17
|
-
export { type RecipeGraphReference, type RecipeGraphValidationResult, type RecipeRunOptions, type RecipeRunOutput, type RecipeRunResult, RecipesResource, } from "./resources/recipes.js";
|
|
18
|
-
export { ScenariosResource, } from "./resources/scenarios.js";
|
|
17
|
+
export { type RecipeCloneOptions, type RecipeCloneResult, type RecipeGraphReference, type RecipeGraphValidationResult, type RecipeRunOptions, type RecipeRunOutput, type RecipeRunResult, RecipesResource, } from "./resources/recipes.js";
|
|
18
|
+
export { normalizeScenarioUpdateData, SCENARIO_CANONICAL_EDITABLE_FIELDS, type ScenarioFieldChange, type ScenarioFieldMismatch, ScenariosResource, type ScenarioUpdateNormalization, type ScenarioUpdatePreview, scenarioUpdatePreview, type ScenarioUpdateResult, } from "./resources/scenarios.js";
|
|
19
19
|
export { SqlResource, } from "./resources/sql.js";
|
|
20
20
|
export { VariablesResource, } from "./resources/variables.js";
|
|
21
21
|
export { WikiResource, } from "./resources/wiki.js";
|
|
22
|
-
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "./schemas.js";
|
|
22
|
+
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "./schemas.js";
|
|
23
23
|
export type { SafeParseResult, } from "./schemas.js";
|
|
24
|
-
export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvWaitOptions, ConnectionSummary, DashboardDetails, DashboardSummary, DataQualityComputeResult, DataQualityProjectStatus, DataQualityRule, DataQualityRuleResult, DataQualityRules, DataQualityStatus, DataQualityStatusByPartition, DataQualityTimeline, DataQualityTimelineEntry, DatasetCreateOptions, DatasetDetails, DatasetSchema, DatasetSummary, FlowMapOptions, FlowZone, FlowZoneCreateOptions, FlowZoneItem, FlowZoneObjectType, FlowZoneUpdateOptions, FolderCreateOptions, FolderDetails, FolderItem, FolderSummary, FutureState, FutureWaitResult, InsightDetails, InsightSummary, JobSummary, JobWaitResult, JupyterCell, JupyterNotebookContent, JupyterNotebookSummary, NotebookSession, ProjectDetails, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, ScenarioDetails, ScenarioStatus, ScenarioSummary, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "./schemas.js";
|
|
24
|
+
export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvWaitOptions, ConnectionSummary, DashboardDetails, DashboardSummary, DataQualityComputeResult, DataQualityProjectStatus, DataQualityRule, DataQualityRuleResult, DataQualityRules, DataQualityStatus, DataQualityStatusByPartition, DataQualityTimeline, DataQualityTimelineEntry, DatasetCreateOptions, DatasetDetails, DatasetSchema, DatasetSummary, FlowMapOptions, FlowZone, FlowZoneCreateOptions, FlowZoneItem, FlowZoneObjectType, FlowZonePosition, FlowZoneUpdateOptions, FolderCreateOptions, FolderDetails, FolderItem, FolderSummary, FutureState, FutureWaitResult, InsightDetails, InsightSummary, JobSummary, JobWaitResult, JupyterCell, JupyterNotebookContent, JupyterNotebookSummary, NotebookSession, ProjectDetails, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, ScenarioDetails, ScenarioStatus, ScenarioSummary, SqlNotebookCell, SqlNotebookContent, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "./schemas.js";
|
|
25
25
|
export { deepMerge, } from "./utils/deep-merge.js";
|
|
26
26
|
export { type NormalizedFlowEdge, type NormalizedFlowMap, type NormalizedFlowNode, normalizeFlowGraph, } from "./utils/flow-map.js";
|
|
27
27
|
export { sanitizeFileName, } from "./utils/sanitize.js";
|
package/dist/src/index.js
CHANGED
|
@@ -15,16 +15,16 @@ export { FlowZonesResource, } from "./resources/flow-zones.js";
|
|
|
15
15
|
export { FoldersResource, } from "./resources/folders.js";
|
|
16
16
|
export { FuturesResource, } from "./resources/futures.js";
|
|
17
17
|
export { InsightsResource, } from "./resources/insights.js";
|
|
18
|
-
export { computeNextPollDelayMs, JobsResource, } from "./resources/jobs.js";
|
|
18
|
+
export { computeNextPollDelayMs, JobsResource, parseJobLogProgress, } from "./resources/jobs.js";
|
|
19
19
|
export { NotebooksResource, } from "./resources/notebooks.js";
|
|
20
20
|
export { ProjectsResource, } from "./resources/projects.js";
|
|
21
21
|
export { RecipesResource, } from "./resources/recipes.js";
|
|
22
|
-
export { ScenariosResource, } from "./resources/scenarios.js";
|
|
22
|
+
export { normalizeScenarioUpdateData, SCENARIO_CANONICAL_EDITABLE_FIELDS, ScenariosResource, scenarioUpdatePreview, } from "./resources/scenarios.js";
|
|
23
23
|
export { SqlResource, } from "./resources/sql.js";
|
|
24
24
|
export { VariablesResource, } from "./resources/variables.js";
|
|
25
25
|
export { WikiResource, } from "./resources/wiki.js";
|
|
26
26
|
// Schemas (TypeBox schema objects for runtime validation)
|
|
27
|
-
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "./schemas.js";
|
|
27
|
+
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvWaitOptionsSchema, ConnectionSummarySchema, DashboardDetailsSchema, DashboardSummaryArraySchema, DashboardSummarySchema, DataQualityComputeResultSchema, DataQualityProjectStatusSchema, DataQualityRuleArraySchema, DataQualityRuleResultArraySchema, DataQualityRuleResultSchema, DataQualityRuleSchema, DataQualityRulesSchema, DataQualityStatusByPartitionSchema, DataQualityStatusSchema, DataQualityTimelineEntrySchema, DataQualityTimelineSchema, DatasetCreateOptionsSchema, DatasetDetailsSchema, DatasetSchemaSchema, DatasetSummaryArraySchema, DatasetSummarySchema, FlowMapOptionsSchema, FlowZoneArraySchema, FlowZoneCreateOptionsSchema, FlowZoneItemSchema, FlowZoneObjectTypeSchema, FlowZonePositionSchema, FlowZoneSchema, FlowZoneUpdateOptionsSchema, FolderCreateOptionsSchema, FolderDetailsSchema, FolderItemArraySchema, FolderItemSchema, FolderSummaryArraySchema, FolderSummarySchema, FutureStateSchema, FutureWaitResultSchema, InsightDetailsSchema, InsightSummaryArraySchema, InsightSummarySchema, JobSummaryArraySchema, JobSummarySchema, JobWaitResultSchema, JupyterCellSchema, JupyterNotebookContentSchema, JupyterNotebookSummaryArraySchema, JupyterNotebookSummarySchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "./schemas.js";
|
|
28
28
|
// Utilities
|
|
29
29
|
export { deepMerge, } from "./utils/deep-merge.js";
|
|
30
30
|
export { normalizeFlowGraph, } from "./utils/flow-map.js";
|
|
@@ -14,6 +14,21 @@ export interface DatasetSchemaColumnInput {
|
|
|
14
14
|
type: string;
|
|
15
15
|
comment?: string;
|
|
16
16
|
}
|
|
17
|
+
export interface DatasetCloneOptions {
|
|
18
|
+
projectKey?: string;
|
|
19
|
+
path?: string;
|
|
20
|
+
table?: string;
|
|
21
|
+
metastoreTableName?: string;
|
|
22
|
+
overrides?: Record<string, unknown>;
|
|
23
|
+
allowSamePath?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface DatasetCloneResult {
|
|
26
|
+
source: string;
|
|
27
|
+
target: string;
|
|
28
|
+
projectKey: string;
|
|
29
|
+
created: Record<string, unknown>;
|
|
30
|
+
settings: Record<string, unknown>;
|
|
31
|
+
}
|
|
17
32
|
/**
|
|
18
33
|
* Compare streamed TSV header columns against a known dataset schema.
|
|
19
34
|
* Returns an array of warning strings (empty if all columns match).
|
|
@@ -21,6 +36,7 @@ export interface DatasetSchemaColumnInput {
|
|
|
21
36
|
export declare function validateStreamColumns(headerRow: string[], expectedColumns: {
|
|
22
37
|
name: string;
|
|
23
38
|
}[]): string[];
|
|
39
|
+
export declare function buildDatasetCloneSettings(source: DatasetDetails, targetName: string, projectKey: string, opts: DatasetCloneOptions): Record<string, unknown>;
|
|
24
40
|
export declare class DatasetsResource extends BaseResource {
|
|
25
41
|
/** List all datasets in a project. */
|
|
26
42
|
list(projectKey?: string): Promise<DatasetSummary[]>;
|
|
@@ -69,6 +85,8 @@ export declare class DatasetsResource extends BaseResource {
|
|
|
69
85
|
create(opts: DatasetCreateOptions): Promise<Record<string, unknown>>;
|
|
70
86
|
/** Validate common build blockers before running a dataset build. */
|
|
71
87
|
validateBuildSettings(datasetName: string, projectKey?: string): Promise<DatasetBuildValidationResult>;
|
|
88
|
+
/** Clone dataset settings, preserving connection/storage, format, and schema fields. */
|
|
89
|
+
clone(sourceName: string, targetName: string, opts?: DatasetCloneOptions): Promise<DatasetCloneResult>;
|
|
72
90
|
/** Update a dataset by deep-merging a patch into the current definition. */
|
|
73
91
|
update(datasetName: string, data: Record<string, unknown>, projectKey?: string): Promise<void>;
|
|
74
92
|
/** Delete a dataset. */
|
|
@@ -306,6 +306,60 @@ function buildDatasetCreateBody(opts) {
|
|
|
306
306
|
managed: opts.managed ?? true,
|
|
307
307
|
};
|
|
308
308
|
}
|
|
309
|
+
const DATASET_CLONE_PARAM_KEYS = [
|
|
310
|
+
"connection",
|
|
311
|
+
"path",
|
|
312
|
+
"table",
|
|
313
|
+
"schema",
|
|
314
|
+
"catalog",
|
|
315
|
+
"folderSmartId",
|
|
316
|
+
"metastoreTableName",
|
|
317
|
+
"mode",
|
|
318
|
+
];
|
|
319
|
+
function cloneDatasetParams(params) {
|
|
320
|
+
const sourceParams = params && typeof params === "object" && !Array.isArray(params)
|
|
321
|
+
? params
|
|
322
|
+
: {};
|
|
323
|
+
const cloned = {};
|
|
324
|
+
for (const key of DATASET_CLONE_PARAM_KEYS) {
|
|
325
|
+
const value = sourceParams[key];
|
|
326
|
+
if (value !== undefined)
|
|
327
|
+
cloned[key] = value;
|
|
328
|
+
}
|
|
329
|
+
return cloned;
|
|
330
|
+
}
|
|
331
|
+
export function buildDatasetCloneSettings(source, targetName, projectKey, opts) {
|
|
332
|
+
const params = {
|
|
333
|
+
...cloneDatasetParams(source.params),
|
|
334
|
+
...(opts.path !== undefined ? { path: opts.path, } : {}),
|
|
335
|
+
...(opts.table !== undefined ? { table: opts.table, mode: "table", } : {}),
|
|
336
|
+
...(opts.metastoreTableName !== undefined
|
|
337
|
+
? { metastoreTableName: opts.metastoreTableName, }
|
|
338
|
+
: {}),
|
|
339
|
+
};
|
|
340
|
+
const cloned = {
|
|
341
|
+
name: targetName,
|
|
342
|
+
projectKey,
|
|
343
|
+
...(source.type !== undefined ? { type: source.type, } : {}),
|
|
344
|
+
...(source.managed !== undefined ? { managed: source.managed, } : {}),
|
|
345
|
+
...(Object.keys(params).length > 0 ? { params, } : {}),
|
|
346
|
+
...(source.formatType !== undefined ? { formatType: source.formatType, } : {}),
|
|
347
|
+
...(source.formatParams !== undefined ? { formatParams: source.formatParams, } : {}),
|
|
348
|
+
...(source.schema !== undefined ? { schema: source.schema, } : {}),
|
|
349
|
+
};
|
|
350
|
+
const settings = opts.overrides ? deepMerge(cloned, opts.overrides) : cloned;
|
|
351
|
+
const settingsParams = settings.params && typeof settings.params === "object" && !Array.isArray(settings.params)
|
|
352
|
+
? settings.params
|
|
353
|
+
: {};
|
|
354
|
+
const sourcePath = typeof source.params?.path === "string" ? source.params.path : undefined;
|
|
355
|
+
if (opts.allowSamePath !== true
|
|
356
|
+
&& source.managed === true
|
|
357
|
+
&& sourcePath !== undefined
|
|
358
|
+
&& settingsParams.path === sourcePath) {
|
|
359
|
+
throw new Error(`Refusing to clone managed dataset "${source.name}" with the same storage path. Pass a new path or allowSamePath: true.`);
|
|
360
|
+
}
|
|
361
|
+
return settings;
|
|
362
|
+
}
|
|
309
363
|
// ---------------------------------------------------------------------------
|
|
310
364
|
// Resource
|
|
311
365
|
// ---------------------------------------------------------------------------
|
|
@@ -485,6 +539,13 @@ export class DatasetsResource extends BaseResource {
|
|
|
485
539
|
warnings,
|
|
486
540
|
};
|
|
487
541
|
}
|
|
542
|
+
/** Clone dataset settings, preserving connection/storage, format, and schema fields. */
|
|
543
|
+
async clone(sourceName, targetName, opts = {}) {
|
|
544
|
+
const pk = this.resolveProjectKey(opts.projectKey);
|
|
545
|
+
const settings = buildDatasetCloneSettings(await this.get(sourceName, pk), targetName, pk, opts);
|
|
546
|
+
const created = await this.client.post(`/public/api/projects/${encodeURIComponent(pk)}/datasets/`, settings);
|
|
547
|
+
return { source: sourceName, target: targetName, projectKey: pk, created, settings, };
|
|
548
|
+
}
|
|
488
549
|
/** Update a dataset by deep-merging a patch into the current definition. */
|
|
489
550
|
async update(datasetName, data, projectKey) {
|
|
490
551
|
const dsEnc = encodeURIComponent(datasetName);
|
|
@@ -12,7 +12,7 @@ export declare class FlowZonesResource extends BaseResource {
|
|
|
12
12
|
get(zoneId: string, projectKey?: string): Promise<FlowZone>;
|
|
13
13
|
/** Create a flow zone. */
|
|
14
14
|
create(opts: FlowZoneCreateOptions): Promise<FlowZone>;
|
|
15
|
-
/** Update flow zone settings such as name and
|
|
15
|
+
/** Update flow zone settings such as name, color, and manual position. */
|
|
16
16
|
update(zoneId: string, opts: FlowZoneUpdateOptions): Promise<FlowZone>;
|
|
17
17
|
/** Delete a flow zone. DSS moves its items back to the default zone. */
|
|
18
18
|
delete(zoneId: string, projectKey?: string): Promise<void>;
|
|
@@ -24,15 +24,17 @@ export class FlowZonesResource extends BaseResource {
|
|
|
24
24
|
const raw = await this.client.post(`/public/api/projects/${this.enc(opts.projectKey)}/flow/zones`, {
|
|
25
25
|
name: opts.name,
|
|
26
26
|
color: opts.color ?? "#2ab1ac",
|
|
27
|
+
...(opts.position !== undefined ? { position: opts.position, } : {}),
|
|
27
28
|
});
|
|
28
29
|
return this.client.safeParse(FlowZoneSchema, raw, "flowZones.create");
|
|
29
30
|
}
|
|
30
|
-
/** Update flow zone settings such as name and
|
|
31
|
+
/** Update flow zone settings such as name, color, and manual position. */
|
|
31
32
|
async update(zoneId, opts) {
|
|
32
33
|
const current = await this.get(zoneId, opts.projectKey);
|
|
33
34
|
const merged = deepMerge(current, {
|
|
34
35
|
...(opts.name !== undefined ? { name: opts.name, } : {}),
|
|
35
36
|
...(opts.color !== undefined ? { color: opts.color, } : {}),
|
|
37
|
+
...(opts.position !== undefined ? { position: opts.position, } : {}),
|
|
36
38
|
});
|
|
37
39
|
await this.client.putVoid(`/public/api/projects/${this.enc(opts.projectKey)}/flow/zones/${encodeURIComponent(zoneId)}`, merged);
|
|
38
40
|
return this.get(zoneId, opts.projectKey);
|
|
@@ -2,10 +2,17 @@ import type { BuildMode, JobSummary, JobWaitResult } from "../schemas.js";
|
|
|
2
2
|
import { BaseResource } from "./base.js";
|
|
3
3
|
export type JobBuildTargetType = "DATASET" | "MANAGED_FOLDER";
|
|
4
4
|
export type JobLogFilter = "stdout" | "stderr" | "user" | "errors";
|
|
5
|
+
export interface JobLogProgress {
|
|
6
|
+
lastProgressLine?: string;
|
|
7
|
+
doneLine?: string;
|
|
8
|
+
counters: Record<string, number>;
|
|
9
|
+
rowsPerMinute?: number;
|
|
10
|
+
}
|
|
5
11
|
export interface JobLogSummary {
|
|
6
12
|
state: string;
|
|
7
13
|
lineCount: number;
|
|
8
14
|
lines: string[];
|
|
15
|
+
progress?: JobLogProgress;
|
|
9
16
|
}
|
|
10
17
|
export interface JobBuildTarget {
|
|
11
18
|
id: string;
|
|
@@ -27,6 +34,7 @@ export interface JobBuildAndWaitOptions extends JobBuildOptions {
|
|
|
27
34
|
pollIntervalMs?: number;
|
|
28
35
|
timeoutMs?: number;
|
|
29
36
|
logFilter?: JobLogFilter;
|
|
37
|
+
logId?: string;
|
|
30
38
|
summary?: boolean;
|
|
31
39
|
}
|
|
32
40
|
interface ComputeNextPollDelayMsOptions {
|
|
@@ -40,6 +48,7 @@ interface ComputeNextPollDelayMsOptions {
|
|
|
40
48
|
* capped at MAX_POLL_INTERVAL_MS (or baseIntervalMs if it's larger).
|
|
41
49
|
*/
|
|
42
50
|
export declare function computeNextPollDelayMs({ pollCount, baseIntervalMs, adaptiveEnabled, }: ComputeNextPollDelayMsOptions): number;
|
|
51
|
+
export declare function parseJobLogProgress(log: string, elapsedMs?: number): JobLogProgress | undefined;
|
|
43
52
|
export declare class JobsResource extends BaseResource {
|
|
44
53
|
/** List jobs in a project. */
|
|
45
54
|
list(projectKey?: string): Promise<JobSummary[]>;
|
|
@@ -52,9 +61,13 @@ export declare class JobsResource extends BaseResource {
|
|
|
52
61
|
*/
|
|
53
62
|
log(jobId: string, opts?: {
|
|
54
63
|
activity?: string;
|
|
64
|
+
logId?: string;
|
|
55
65
|
maxLogLines?: number;
|
|
56
66
|
projectKey?: string;
|
|
57
67
|
}): Promise<string>;
|
|
68
|
+
logFromUrl(logUrl: string, opts?: {
|
|
69
|
+
maxLogLines?: number;
|
|
70
|
+
}): Promise<string>;
|
|
58
71
|
/**
|
|
59
72
|
* Start a build job for one or more dataset or managed-folder outputs.
|
|
60
73
|
* Returns the new job's ID.
|
|
@@ -95,6 +108,7 @@ export declare class JobsResource extends BaseResource {
|
|
|
95
108
|
activity?: string;
|
|
96
109
|
includeLogs?: boolean;
|
|
97
110
|
logFilter?: JobLogFilter;
|
|
111
|
+
logId?: string;
|
|
98
112
|
maxLogLines?: number;
|
|
99
113
|
pollIntervalMs?: number;
|
|
100
114
|
summary?: boolean;
|
|
@@ -104,13 +104,58 @@ function limitJobLog(log, maxLines) {
|
|
|
104
104
|
const tail = lines.slice(-Math.max(1, limit)).join("\n");
|
|
105
105
|
return hasTrailingLineBreak ? `${tail}\n` : tail;
|
|
106
106
|
}
|
|
107
|
-
function
|
|
107
|
+
function parsedCounterValue(value) {
|
|
108
|
+
return Number(value.replace(/,/g, ""));
|
|
109
|
+
}
|
|
110
|
+
export function parseJobLogProgress(log, elapsedMs) {
|
|
111
|
+
const counters = {};
|
|
112
|
+
let lastProgressLine;
|
|
113
|
+
let doneLine;
|
|
114
|
+
for (const line of jobLogLines(log)) {
|
|
115
|
+
const normalized = line.trim();
|
|
116
|
+
if (!normalized)
|
|
117
|
+
continue;
|
|
118
|
+
const lower = normalized.toLowerCase();
|
|
119
|
+
let matched = false;
|
|
120
|
+
for (const match of normalized.matchAll(/\b(scanned|matched|joined|written|emitted)\s+([0-9][0-9,]*)/gi)) {
|
|
121
|
+
counters[match[1].toLowerCase()] = parsedCounterValue(match[2]);
|
|
122
|
+
matched = true;
|
|
123
|
+
}
|
|
124
|
+
const written = normalized.match(/\b([0-9][0-9,]*)\s+rows\s+successfully\s+written\b/i);
|
|
125
|
+
if (written) {
|
|
126
|
+
counters.written = parsedCounterValue(written[1]);
|
|
127
|
+
doneLine = normalized;
|
|
128
|
+
matched = true;
|
|
129
|
+
}
|
|
130
|
+
if (lower.includes("done!")) {
|
|
131
|
+
doneLine = normalized;
|
|
132
|
+
matched = true;
|
|
133
|
+
}
|
|
134
|
+
if (matched)
|
|
135
|
+
lastProgressLine = normalized;
|
|
136
|
+
}
|
|
137
|
+
if (lastProgressLine === undefined && doneLine === undefined)
|
|
138
|
+
return undefined;
|
|
139
|
+
const writtenRows = counters.written ?? counters.emitted;
|
|
140
|
+
const rowsPerMinute = writtenRows !== undefined && elapsedMs !== undefined && elapsedMs > 0
|
|
141
|
+
? writtenRows / (elapsedMs / 60_000)
|
|
142
|
+
: undefined;
|
|
143
|
+
return {
|
|
144
|
+
...(lastProgressLine ? { lastProgressLine, } : {}),
|
|
145
|
+
...(doneLine ? { doneLine, } : {}),
|
|
146
|
+
counters,
|
|
147
|
+
...(rowsPerMinute !== undefined ? { rowsPerMinute, } : {}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function summarizeJobLog(state, log, maxLines, elapsedMs) {
|
|
108
151
|
const lines = jobLogLines(log).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
109
152
|
const summaryLines = lines.slice(-Math.max(1, maxLines));
|
|
153
|
+
const progress = parseJobLogProgress(log, elapsedMs);
|
|
110
154
|
return {
|
|
111
155
|
state,
|
|
112
156
|
lineCount: lines.length,
|
|
113
157
|
lines: summaryLines,
|
|
158
|
+
...(progress ? { progress, } : {}),
|
|
114
159
|
};
|
|
115
160
|
}
|
|
116
161
|
export class JobsResource extends BaseResource {
|
|
@@ -133,9 +178,21 @@ export class JobsResource extends BaseResource {
|
|
|
133
178
|
async log(jobId, opts) {
|
|
134
179
|
const jobEnc = encodeURIComponent(jobId);
|
|
135
180
|
const query = opts?.activity ? `?activity=${encodeURIComponent(opts.activity)}` : "";
|
|
136
|
-
|
|
181
|
+
// DSS cat-activity-log URLs require a browser session; API-key callers must use the public log endpoint.
|
|
182
|
+
const path = `/public/api/projects/${this.enc(opts?.projectKey)}/jobs/${jobEnc}/log/${query}`;
|
|
183
|
+
const log = await this.client.getText(path);
|
|
137
184
|
return limitJobLog(log, opts?.maxLogLines);
|
|
138
185
|
}
|
|
186
|
+
async logFromUrl(logUrl, opts) {
|
|
187
|
+
const parsed = new URL(logUrl, "http://dss.local");
|
|
188
|
+
const projectKey = parsed.searchParams.get("projectKey") ?? undefined;
|
|
189
|
+
const jobId = parsed.searchParams.get("jobId") ?? undefined;
|
|
190
|
+
const activity = parsed.searchParams.get("activityId") ?? undefined;
|
|
191
|
+
if (!projectKey || !jobId || !activity) {
|
|
192
|
+
throw new Error("Log URL must include projectKey, jobId, and activityId query parameters.");
|
|
193
|
+
}
|
|
194
|
+
return this.log(jobId, { activity, projectKey, maxLogLines: opts?.maxLogLines, });
|
|
195
|
+
}
|
|
139
196
|
/**
|
|
140
197
|
* Start a build job for one or more dataset or managed-folder outputs.
|
|
141
198
|
* Returns the new job's ID.
|
|
@@ -168,6 +225,7 @@ export class JobsResource extends BaseResource {
|
|
|
168
225
|
activity: opts?.activity,
|
|
169
226
|
includeLogs: opts?.includeLogs,
|
|
170
227
|
logFilter: opts?.logFilter,
|
|
228
|
+
logId: opts?.logId,
|
|
171
229
|
maxLogLines: opts?.maxLogLines,
|
|
172
230
|
pollIntervalMs: opts?.pollIntervalMs,
|
|
173
231
|
summary: opts?.summary,
|
|
@@ -218,13 +276,14 @@ export class JobsResource extends BaseResource {
|
|
|
218
276
|
const rawLog = await this.log(jobId, {
|
|
219
277
|
activity: opts.activity,
|
|
220
278
|
maxLogLines: opts.summary ? 0 : opts.maxLogLines,
|
|
279
|
+
logId: opts.logId,
|
|
221
280
|
projectKey: opts.projectKey,
|
|
222
281
|
});
|
|
223
282
|
const filteredLog = filterJobLog(rawLog, opts.logFilter);
|
|
224
283
|
if (opts.includeLogs)
|
|
225
284
|
log = limitJobLog(filteredLog, opts.maxLogLines);
|
|
226
285
|
if (opts.summary) {
|
|
227
|
-
logSummary = summarizeJobLog(state, filteredLog, opts.maxLogLines ?? 20);
|
|
286
|
+
logSummary = summarizeJobLog(state, filteredLog, opts.maxLogLines ?? 20, elapsedMs);
|
|
228
287
|
}
|
|
229
288
|
}
|
|
230
289
|
return {
|
|
@@ -42,6 +42,29 @@ export type RecipeRunResult = {
|
|
|
42
42
|
} & ({
|
|
43
43
|
jobId: string;
|
|
44
44
|
} | JobWaitResult);
|
|
45
|
+
export interface RecipeCloneOptions {
|
|
46
|
+
projectKey?: string;
|
|
47
|
+
name: string;
|
|
48
|
+
outputDataset?: string;
|
|
49
|
+
outputRewrites?: Record<string, string>;
|
|
50
|
+
inputRewrites?: Record<string, string>;
|
|
51
|
+
payloadRewrites?: Record<string, string>;
|
|
52
|
+
payloadTextRewrites?: Record<string, string>;
|
|
53
|
+
copyOutputSettings?: boolean;
|
|
54
|
+
outputPath?: string;
|
|
55
|
+
metastoreTableName?: string;
|
|
56
|
+
recipeType?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface RecipeCloneResult {
|
|
59
|
+
sourceRecipeName: string;
|
|
60
|
+
recipeName: string;
|
|
61
|
+
projectKey: string;
|
|
62
|
+
outputRewrites: Record<string, string>;
|
|
63
|
+
inputRewrites: Record<string, string>;
|
|
64
|
+
payloadRewrites: Record<string, string>;
|
|
65
|
+
payloadTextRewrites: Record<string, string>;
|
|
66
|
+
copiedOutputDatasets: string[];
|
|
67
|
+
}
|
|
45
68
|
export declare class RecipesResource extends BaseResource {
|
|
46
69
|
/** List all recipes in a project. */
|
|
47
70
|
list(projectKey?: string): Promise<RecipeSummary[]>;
|
|
@@ -75,6 +98,10 @@ export declare class RecipesResource extends BaseResource {
|
|
|
75
98
|
* The `recipe` sub-object is deep-merged to preserve nested fields.
|
|
76
99
|
*/
|
|
77
100
|
update(recipeName: string, data: Record<string, unknown>, projectKey?: string): Promise<void>;
|
|
101
|
+
/** Replace a full recipe API document. */
|
|
102
|
+
replace(recipeName: string, document: Record<string, unknown>, projectKey?: string): Promise<void>;
|
|
103
|
+
/** Clone recipe graph/settings and optionally clone a dataset output. */
|
|
104
|
+
clone(sourceName: string, opts: RecipeCloneOptions): Promise<RecipeCloneResult>;
|
|
78
105
|
/**
|
|
79
106
|
* Download a recipe code payload to a local file.
|
|
80
107
|
|
|
@@ -86,6 +86,78 @@ function recipeInputItems(recipe) {
|
|
|
86
86
|
}
|
|
87
87
|
return result;
|
|
88
88
|
}
|
|
89
|
+
function rewriteRefs(value, rewrites) {
|
|
90
|
+
if (Object.keys(rewrites).length === 0)
|
|
91
|
+
return value;
|
|
92
|
+
if (Array.isArray(value))
|
|
93
|
+
return value.map((item) => rewriteRefs(item, rewrites));
|
|
94
|
+
const record = asRecord(value);
|
|
95
|
+
if (!record)
|
|
96
|
+
return value;
|
|
97
|
+
const next = {};
|
|
98
|
+
for (const [key, item,] of Object.entries(record)) {
|
|
99
|
+
if (key === "ref" && typeof item === "string" && rewrites[item]) {
|
|
100
|
+
next[key] = rewrites[item];
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
next[key] = rewriteRefs(item, rewrites);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return next;
|
|
107
|
+
}
|
|
108
|
+
function escapedRegExp(value) {
|
|
109
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
110
|
+
}
|
|
111
|
+
function isSqlRecipeType(recipeType) {
|
|
112
|
+
return typeof recipeType === "string" && recipeType.toLowerCase().includes("sql");
|
|
113
|
+
}
|
|
114
|
+
function rewriteSqlTableReferences(payload, rewrites) {
|
|
115
|
+
let next = payload;
|
|
116
|
+
for (const [from, to,] of Object.entries(rewrites)) {
|
|
117
|
+
if (!from)
|
|
118
|
+
continue;
|
|
119
|
+
const escaped = escapedRegExp(from);
|
|
120
|
+
const pattern = new RegExp(String
|
|
121
|
+
.raw `\b(FROM|JOIN)(\s+)(?:(["\`])${escaped}\3|(\[)${escaped}\]|${escaped})(?![A-Za-z0-9_.])`, "gi");
|
|
122
|
+
next = next.replace(pattern, (_match, keyword, space, quote, bracket) => {
|
|
123
|
+
if (quote)
|
|
124
|
+
return `${keyword}${space}${quote}${to}${quote}`;
|
|
125
|
+
if (bracket)
|
|
126
|
+
return `${keyword}${space}[${to}]`;
|
|
127
|
+
return `${keyword}${space}${to}`;
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return next;
|
|
131
|
+
}
|
|
132
|
+
function rewritePayload(payload, rewrites, payloadTextRewrites = {}, recipeType) {
|
|
133
|
+
if (payload === undefined
|
|
134
|
+
|| (Object.keys(rewrites).length === 0 && Object.keys(payloadTextRewrites).length === 0)) {
|
|
135
|
+
return payload;
|
|
136
|
+
}
|
|
137
|
+
let next = payload;
|
|
138
|
+
for (const [from, to,] of Object.entries(rewrites)) {
|
|
139
|
+
if (!from)
|
|
140
|
+
continue;
|
|
141
|
+
const escaped = escapedRegExp(from);
|
|
142
|
+
next = next.replace(new RegExp(`\\bdataiku\\.(Dataset|Folder)\\(\\s*(['"])${escaped}\\2\\s*\\)`, "g"), (_match, kind, quote) => `dataiku.${kind}(${quote}${to}${quote})`);
|
|
143
|
+
}
|
|
144
|
+
if (isSqlRecipeType(recipeType)) {
|
|
145
|
+
next = rewriteSqlTableReferences(next, rewrites);
|
|
146
|
+
}
|
|
147
|
+
for (const [from, to,] of Object.entries(payloadTextRewrites)) {
|
|
148
|
+
if (from.length > 0)
|
|
149
|
+
next = next.split(from).join(to);
|
|
150
|
+
}
|
|
151
|
+
return next;
|
|
152
|
+
}
|
|
153
|
+
function cloneRecipeDefinition(recipe, targetName, projectKey, rewrites) {
|
|
154
|
+
const cloned = rewriteRefs(structuredClone(recipe), rewrites);
|
|
155
|
+
delete cloned.versionTag;
|
|
156
|
+
delete cloned.neverBuilt;
|
|
157
|
+
cloned.name = targetName;
|
|
158
|
+
cloned.projectKey = projectKey;
|
|
159
|
+
return cloned;
|
|
160
|
+
}
|
|
89
161
|
function inferRecipeCodeExtension(recipeType) {
|
|
90
162
|
const normalized = typeof recipeType === "string" ? recipeType.trim().toLowerCase() : "";
|
|
91
163
|
if (!normalized)
|
|
@@ -562,6 +634,72 @@ export class RecipesResource extends BaseResource {
|
|
|
562
634
|
const merged = { ...current, ...data, recipe: mergedRecipe, };
|
|
563
635
|
await this.client.put(`/public/api/projects/${enc}/recipes/${rnEnc}`, merged);
|
|
564
636
|
}
|
|
637
|
+
/** Replace a full recipe API document. */
|
|
638
|
+
async replace(recipeName, document, projectKey) {
|
|
639
|
+
const enc = this.enc(projectKey);
|
|
640
|
+
const rnEnc = encodeURIComponent(recipeName);
|
|
641
|
+
await this.client.put(`/public/api/projects/${enc}/recipes/${rnEnc}`, document);
|
|
642
|
+
}
|
|
643
|
+
/** Clone recipe graph/settings and optionally clone a dataset output. */
|
|
644
|
+
async clone(sourceName, opts) {
|
|
645
|
+
const pk = this.resolveProjectKey(opts.projectKey);
|
|
646
|
+
const source = await this.get(sourceName, { includePayload: true, projectKey: pk, });
|
|
647
|
+
const outputRewrites = {};
|
|
648
|
+
if (opts.outputRewrites)
|
|
649
|
+
Object.assign(outputRewrites, opts.outputRewrites);
|
|
650
|
+
if (opts.outputDataset !== undefined) {
|
|
651
|
+
const outputs = recipeOutputItems(source.recipe).filter((item) => item.type !== "MANAGED_FOLDER");
|
|
652
|
+
if (outputs.length !== 1 && Object.keys(outputRewrites).length === 0) {
|
|
653
|
+
throw new Error(`Recipe "${sourceName}" has ${outputs.length} dataset outputs; pass explicit outputRewrites instead of outputDataset.`);
|
|
654
|
+
}
|
|
655
|
+
if (outputs[0])
|
|
656
|
+
outputRewrites[outputs[0].ref] = opts.outputDataset;
|
|
657
|
+
}
|
|
658
|
+
const inputRewrites = {};
|
|
659
|
+
if (opts.inputRewrites)
|
|
660
|
+
Object.assign(inputRewrites, opts.inputRewrites);
|
|
661
|
+
const graphRewrites = { ...inputRewrites, ...outputRewrites, };
|
|
662
|
+
const payloadRewrites = { ...graphRewrites, };
|
|
663
|
+
if (opts.payloadRewrites)
|
|
664
|
+
Object.assign(payloadRewrites, opts.payloadRewrites);
|
|
665
|
+
if (opts.copyOutputSettings === true
|
|
666
|
+
&& Object.keys(outputRewrites).length > 1
|
|
667
|
+
&& (opts.outputPath !== undefined || opts.metastoreTableName !== undefined)) {
|
|
668
|
+
throw new Error("Cannot reuse --path or --metastore-table for multiple cloned output datasets; pass per-output settings in a separate step.");
|
|
669
|
+
}
|
|
670
|
+
const payloadTextRewrites = {};
|
|
671
|
+
if (opts.payloadTextRewrites)
|
|
672
|
+
Object.assign(payloadTextRewrites, opts.payloadTextRewrites);
|
|
673
|
+
const recipe = cloneRecipeDefinition(source.recipe, opts.name, pk, graphRewrites);
|
|
674
|
+
const payload = rewritePayload(source.payload, payloadRewrites, payloadTextRewrites, opts.recipeType ?? source.recipe.type);
|
|
675
|
+
const copiedOutputDatasets = [];
|
|
676
|
+
if (opts.copyOutputSettings) {
|
|
677
|
+
for (const [from, to,] of Object.entries(outputRewrites)) {
|
|
678
|
+
await this.client.datasets.clone(from, to, {
|
|
679
|
+
projectKey: pk,
|
|
680
|
+
path: opts.outputPath,
|
|
681
|
+
metastoreTableName: opts.metastoreTableName,
|
|
682
|
+
});
|
|
683
|
+
copiedOutputDatasets.push(to);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
const rnEnc = encodeURIComponent(opts.name);
|
|
687
|
+
await this.client.post(`/public/api/projects/${encodeURIComponent(pk)}/recipes/`, {
|
|
688
|
+
recipePrototype: recipe,
|
|
689
|
+
creationSettings: payload !== undefined ? { script: payload, } : {},
|
|
690
|
+
});
|
|
691
|
+
await this.client.put(`/public/api/projects/${encodeURIComponent(pk)}/recipes/${rnEnc}`, { recipe, ...(payload !== undefined ? { payload, } : {}), });
|
|
692
|
+
return {
|
|
693
|
+
sourceRecipeName: sourceName,
|
|
694
|
+
recipeName: opts.name,
|
|
695
|
+
projectKey: pk,
|
|
696
|
+
outputRewrites,
|
|
697
|
+
inputRewrites,
|
|
698
|
+
payloadRewrites,
|
|
699
|
+
payloadTextRewrites,
|
|
700
|
+
copiedOutputDatasets,
|
|
701
|
+
};
|
|
702
|
+
}
|
|
565
703
|
/**
|
|
566
704
|
* Download a recipe code payload to a local file.
|
|
567
705
|
|
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
import type { ScenarioDetails, ScenarioStatus, ScenarioSummary, ScenarioWaitResult } from "../schemas.js";
|
|
2
2
|
import { BaseResource } from "./base.js";
|
|
3
|
+
export declare const SCENARIO_CANONICAL_EDITABLE_FIELDS: readonly ["params.steps", "params.triggers", "params.reporters", "params.customScript", "active", "name"];
|
|
4
|
+
export interface ScenarioUpdateNormalization {
|
|
5
|
+
from: string;
|
|
6
|
+
to: string;
|
|
7
|
+
action: "promoted" | "ignored";
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ScenarioFieldChange {
|
|
11
|
+
path: string;
|
|
12
|
+
before: unknown;
|
|
13
|
+
after: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface ScenarioFieldMismatch {
|
|
16
|
+
path: string;
|
|
17
|
+
expected: unknown;
|
|
18
|
+
actual: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface ScenarioUpdatePreview {
|
|
21
|
+
canonicalEditableFields: typeof SCENARIO_CANONICAL_EDITABLE_FIELDS;
|
|
22
|
+
normalization: ScenarioUpdateNormalization[];
|
|
23
|
+
normalizedData: Record<string, unknown>;
|
|
24
|
+
current: Record<string, unknown>;
|
|
25
|
+
next: Record<string, unknown>;
|
|
26
|
+
changes: ScenarioFieldChange[];
|
|
27
|
+
unchangedPaths: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface ScenarioUpdateResult extends ScenarioUpdatePreview {
|
|
30
|
+
after: Record<string, unknown>;
|
|
31
|
+
verified: true;
|
|
32
|
+
mismatches: [];
|
|
33
|
+
}
|
|
34
|
+
export declare function normalizeScenarioUpdateData(data: Record<string, unknown>): {
|
|
35
|
+
normalizedData: Record<string, unknown>;
|
|
36
|
+
normalization: ScenarioUpdateNormalization[];
|
|
37
|
+
};
|
|
38
|
+
export declare function scenarioUpdatePreview(current: Record<string, unknown>, data: Record<string, unknown>): ScenarioUpdatePreview;
|
|
3
39
|
export declare class ScenariosResource extends BaseResource {
|
|
4
40
|
/** List all scenarios in a project. */
|
|
5
41
|
list(projectKey?: string): Promise<ScenarioSummary[]>;
|
|
@@ -19,8 +55,8 @@ export declare class ScenariosResource extends BaseResource {
|
|
|
19
55
|
}>;
|
|
20
56
|
/** Get the light/status view of a scenario. */
|
|
21
57
|
status(scenarioId: string, projectKey?: string): Promise<ScenarioStatus>;
|
|
22
|
-
/** Merge-update a scenario's definition. */
|
|
23
|
-
update(scenarioId: string, data: Record<string, unknown>, projectKey?: string): Promise<
|
|
58
|
+
/** Merge-update a scenario's definition, then refetch and verify requested fields persisted. */
|
|
59
|
+
update(scenarioId: string, data: Record<string, unknown>, projectKey?: string): Promise<ScenarioUpdateResult>;
|
|
24
60
|
/** Delete a scenario. */
|
|
25
61
|
delete(scenarioId: string, projectKey?: string): Promise<void>;
|
|
26
62
|
/**
|