dataiku-sdk 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +253 -38
- package/dist/build-metadata.json +1 -1
- package/dist/packages/types/src/index.d.ts +102 -0
- package/dist/packages/types/src/index.js +76 -0
- package/dist/src/auth.js +1 -1
- package/dist/src/cli/coerce.js +11 -2
- package/dist/src/cli/commands/analysis.js +4 -3
- package/dist/src/cli/commands/api-service.js +5 -3
- package/dist/src/cli/commands/app.js +61 -18
- package/dist/src/cli/commands/bundle.js +3 -2
- package/dist/src/cli/commands/code-env.js +23 -16
- package/dist/src/cli/commands/connection.d.ts +9 -0
- package/dist/src/cli/commands/connection.js +267 -1
- package/dist/src/cli/commands/dashboard.js +7 -6
- package/dist/src/cli/commands/data-collection.d.ts +2 -0
- package/dist/src/cli/commands/data-collection.js +164 -0
- package/dist/src/cli/commands/data-quality.js +9 -8
- package/dist/src/cli/commands/dataset.js +170 -40
- package/dist/src/cli/commands/doctor.js +4 -2
- package/dist/src/cli/commands/flow-zone.js +9 -8
- package/dist/src/cli/commands/folder.js +9 -8
- package/dist/src/cli/commands/future.js +4 -3
- package/dist/src/cli/commands/group.d.ts +2 -0
- package/dist/src/cli/commands/group.js +109 -0
- package/dist/src/cli/commands/index.js +151 -78
- package/dist/src/cli/commands/insight.js +8 -7
- package/dist/src/cli/commands/job.js +4 -3
- package/dist/src/cli/commands/knowledge-bank.d.ts +2 -0
- package/dist/src/cli/commands/knowledge-bank.js +80 -0
- package/dist/src/cli/commands/llm.d.ts +2 -0
- package/dist/src/cli/commands/llm.js +93 -0
- package/dist/src/cli/commands/macro.d.ts +2 -0
- package/dist/src/cli/commands/macro.js +221 -0
- package/dist/src/cli/commands/meaning.js +5 -4
- package/dist/src/cli/commands/ml-task.js +21 -8
- package/dist/src/cli/commands/model-evaluation-store.js +4 -3
- package/dist/src/cli/commands/notebook.js +17 -12
- package/dist/src/cli/commands/plugin.d.ts +2 -0
- package/dist/src/cli/commands/plugin.js +799 -0
- package/dist/src/cli/commands/project-folder.d.ts +2 -0
- package/dist/src/cli/commands/project-folder.js +197 -0
- package/dist/src/cli/commands/project-git.js +14 -54
- package/dist/src/cli/commands/project-library.js +7 -6
- package/dist/src/cli/commands/project.js +55 -8
- package/dist/src/cli/commands/recipe.js +50 -14
- package/dist/src/cli/commands/saved-model.d.ts +5 -0
- package/dist/src/cli/commands/saved-model.js +392 -4
- package/dist/src/cli/commands/scenario.js +147 -9
- package/dist/src/cli/commands/sql.js +3 -2
- package/dist/src/cli/commands/statistics.js +7 -6
- package/dist/src/cli/commands/user.d.ts +8 -0
- package/dist/src/cli/commands/user.js +296 -0
- package/dist/src/cli/commands/variable.js +2 -1
- package/dist/src/cli/commands/webapp.js +2 -1
- package/dist/src/cli/commands/wiki.js +7 -6
- package/dist/src/cli/contract.d.ts +2 -3
- package/dist/src/cli/contract.js +1167 -163
- package/dist/src/cli/flags.d.ts +4 -0
- package/dist/src/cli/flags.js +50 -2
- package/dist/src/cli/helpers/app-successor.d.ts +19 -4
- package/dist/src/cli/helpers/app-successor.js +90 -30
- package/dist/src/cli/helpers/cleanup.js +3 -1
- package/dist/src/cli/helpers/flow-zone.js +1 -2
- package/dist/src/cli/output.d.ts +1 -1
- package/dist/src/cli/output.js +23 -10
- package/dist/src/cli/usage.d.ts +1 -0
- package/dist/src/cli/usage.js +47 -1
- package/dist/src/cli.js +225 -95
- package/dist/src/client.d.ts +86 -6
- package/dist/src/client.js +263 -50
- package/dist/src/errors.d.ts +3 -0
- package/dist/src/errors.js +4 -0
- package/dist/src/index.d.ts +16 -7
- package/dist/src/index.js +11 -2
- package/dist/src/resources/analyses.js +1 -8
- package/dist/src/resources/applications.d.ts +8 -6
- package/dist/src/resources/applications.js +21 -21
- package/dist/src/resources/base.d.ts +4 -0
- package/dist/src/resources/base.js +15 -0
- package/dist/src/resources/bundles.d.ts +9 -4
- package/dist/src/resources/bundles.js +10 -5
- package/dist/src/resources/connections.d.ts +78 -1
- package/dist/src/resources/connections.js +132 -1
- package/dist/src/resources/data-collections.d.ts +118 -0
- package/dist/src/resources/data-collections.js +49 -0
- package/dist/src/resources/datasets.d.ts +69 -0
- package/dist/src/resources/datasets.js +99 -1
- package/dist/src/resources/folders.js +2 -1
- package/dist/src/resources/futures.d.ts +4 -1
- package/dist/src/resources/futures.js +38 -6
- package/dist/src/resources/groups.d.ts +47 -0
- package/dist/src/resources/groups.js +56 -0
- package/dist/src/resources/jobs.d.ts +8 -13
- package/dist/src/resources/jobs.js +41 -16
- package/dist/src/resources/knowledge-banks.d.ts +58 -0
- package/dist/src/resources/knowledge-banks.js +61 -0
- package/dist/src/resources/llms.d.ts +92 -0
- package/dist/src/resources/llms.js +62 -0
- package/dist/src/resources/macros.d.ts +121 -0
- package/dist/src/resources/macros.js +231 -0
- package/dist/src/resources/ml-tasks.d.ts +37 -2
- package/dist/src/resources/ml-tasks.js +100 -20
- package/dist/src/resources/model-evaluation-stores.js +1 -8
- package/dist/src/resources/notebooks.d.ts +43 -7
- package/dist/src/resources/notebooks.js +53 -13
- package/dist/src/resources/plugins.d.ts +265 -0
- package/dist/src/resources/plugins.js +458 -0
- package/dist/src/resources/project-folders.d.ts +71 -0
- package/dist/src/resources/project-folders.js +57 -0
- package/dist/src/resources/project-git.d.ts +6 -0
- package/dist/src/resources/project-git.js +69 -42
- package/dist/src/resources/project-library.d.ts +0 -1
- package/dist/src/resources/project-library.js +1 -17
- package/dist/src/resources/projects.d.ts +19 -3
- package/dist/src/resources/projects.js +30 -18
- package/dist/src/resources/recipes.d.ts +15 -1
- package/dist/src/resources/recipes.js +73 -6
- package/dist/src/resources/saved-models.d.ts +134 -1
- package/dist/src/resources/saved-models.js +214 -6
- package/dist/src/resources/scenarios.d.ts +105 -0
- package/dist/src/resources/scenarios.js +232 -106
- package/dist/src/resources/sql.js +5 -1
- package/dist/src/resources/users.d.ts +129 -0
- package/dist/src/resources/users.js +128 -0
- package/dist/src/resources/webapps.d.ts +15 -2
- package/dist/src/resources/webapps.js +18 -4
- package/dist/src/schemas.d.ts +2 -2
- package/dist/src/schemas.js +1 -1
- package/dist/src/skill.d.ts +13 -4
- package/dist/src/skill.js +75 -24
- package/dist/src/utils/deep-merge.d.ts +1 -1
- package/dist/src/utils/polling.d.ts +20 -0
- package/dist/src/utils/polling.js +27 -0
- package/dist/src/utils/response-file.d.ts +2 -0
- package/dist/src/utils/response-file.js +34 -0
- package/dist/src/utils/secret-sanitize.d.ts +54 -0
- package/dist/src/utils/secret-sanitize.js +101 -0
- package/package.json +8 -5
- package/packages/types/dist/index.d.ts +102 -0
- package/packages/types/dist/index.js +76 -0
- package/plugin.json +1 -1
- package/skills/dataiku-dss/SKILL.md +47 -225
- package/skills/dataiku-dss/references/app-releases.md +28 -0
- package/skills/dataiku-dss/references/authentication.md +39 -0
- package/skills/dataiku-dss/references/coding.md +8 -0
- package/skills/dataiku-dss/references/discovery.md +30 -0
- package/skills/dataiku-dss/references/flow-maps.md +12 -0
- package/skills/dataiku-dss/references/mutations.md +33 -0
- package/skills/dataiku-dss/references/troubleshooting.md +29 -0
|
@@ -48,10 +48,23 @@ export declare class WebappsResource extends BaseResource {
|
|
|
48
48
|
/**
|
|
49
49
|
* Start or restart a webapp backend. The documented endpoint returns a
|
|
50
50
|
* reference to a future, which is surfaced as-is; settle it with
|
|
51
|
-
* {@link restartBackendAndWait} or `client.futures.wait`.
|
|
51
|
+
* {@link restartBackendAndWait} or `client.futures.wait`. DSS 15 returns
|
|
52
|
+
* an empty body (no future) when no async job was spawned — the official
|
|
53
|
+
* Python client tolerates that (`DSSFuture.from_resp` accepts a missing
|
|
54
|
+
* jobId), so an empty response surfaces as `{}` rather than crashing.
|
|
52
55
|
*/
|
|
53
56
|
startOrRestartBackend(webappId: string, projectKey?: string): Promise<Record<string, unknown>>;
|
|
54
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Restart a webapp backend and wait for the returned future to settle.
|
|
59
|
+
* The documented endpoint returns a reference to a future; with a real
|
|
60
|
+
* jobId this polls that future to completion. An empty response carries
|
|
61
|
+
* NO future to wait on (observed on DSS 15 for a webapp whose backend is
|
|
62
|
+
* not enabled — a no-op restart, not a supported wait target), so the
|
|
63
|
+
* wait reports the missing future explicitly instead of fabricating a
|
|
64
|
+
* result for it. Enable the backend (params.backendEnabled with the
|
|
65
|
+
* params.python code, exactly as the DSS editor does) to get a real
|
|
66
|
+
* restart future.
|
|
67
|
+
*/
|
|
55
68
|
restartBackendAndWait(webappId: string, projectKey?: string, options?: WebappWaitOptions): Promise<FutureWaitResult>;
|
|
56
69
|
/** Get a webapp backend's state. */
|
|
57
70
|
getBackendState(webappId: string, projectKey?: string): Promise<Record<string, unknown>>;
|
|
@@ -59,18 +59,32 @@ export class WebappsResource extends BaseResource {
|
|
|
59
59
|
/**
|
|
60
60
|
* Start or restart a webapp backend. The documented endpoint returns a
|
|
61
61
|
* reference to a future, which is surfaced as-is; settle it with
|
|
62
|
-
* {@link restartBackendAndWait} or `client.futures.wait`.
|
|
62
|
+
* {@link restartBackendAndWait} or `client.futures.wait`. DSS 15 returns
|
|
63
|
+
* an empty body (no future) when no async job was spawned — the official
|
|
64
|
+
* Python client tolerates that (`DSSFuture.from_resp` accepts a missing
|
|
65
|
+
* jobId), so an empty response surfaces as `{}` rather than crashing.
|
|
63
66
|
*/
|
|
64
67
|
async startOrRestartBackend(webappId, projectKey) {
|
|
65
68
|
const id = encodeURIComponent(webappId);
|
|
66
|
-
|
|
69
|
+
const future = await this.client.put(`/public/api/projects/${this.enc(projectKey)}/webapps/${id}/backend/actions/restart`, {});
|
|
70
|
+
return future ?? {};
|
|
67
71
|
}
|
|
68
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Restart a webapp backend and wait for the returned future to settle.
|
|
74
|
+
* The documented endpoint returns a reference to a future; with a real
|
|
75
|
+
* jobId this polls that future to completion. An empty response carries
|
|
76
|
+
* NO future to wait on (observed on DSS 15 for a webapp whose backend is
|
|
77
|
+
* not enabled — a no-op restart, not a supported wait target), so the
|
|
78
|
+
* wait reports the missing future explicitly instead of fabricating a
|
|
79
|
+
* result for it. Enable the backend (params.backendEnabled with the
|
|
80
|
+
* params.python code, exactly as the DSS editor does) to get a real
|
|
81
|
+
* restart future.
|
|
82
|
+
*/
|
|
69
83
|
async restartBackendAndWait(webappId, projectKey, options = {}) {
|
|
70
84
|
const future = await this.startOrRestartBackend(webappId, projectKey);
|
|
71
85
|
const jobId = future.jobId;
|
|
72
86
|
if (typeof jobId !== "string" || jobId.length === 0) {
|
|
73
|
-
throw new
|
|
87
|
+
throw new ClientValidationError("Webapp backend restart returned no future jobId, so there is nothing to wait on.", "validation_failed", "The restart endpoint returns a future reference only when it starts an async job (a webapp with an enabled Python backend). Enable the backend before restarting with --wait.", { webappId, restartResponseKeys: Object.keys(future), });
|
|
74
88
|
}
|
|
75
89
|
return this.client.futures.wait(jobId, {
|
|
76
90
|
pollIntervalMs: options.pollIntervalMs,
|
package/dist/src/schemas.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* The types package (packages/types/) owns the TypeBox schema definitions.
|
|
4
4
|
* SDK consumers get everything through this re-export.
|
|
5
5
|
*/
|
|
6
|
-
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
|
7
|
-
export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvGetLogOptions, CodeEnvLogResult, CodeEnvLogSummary, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdateImagesOptions, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvVersionForProject, 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, ProjectGitActionResult, ProjectGitDiffResult, ProjectGitFutureResponse, ProjectGitFutureState, ProjectGitLibraries, ProjectGitLibrary, ProjectGitLogResult, ProjectGitRemote, ProjectGitStatus, ProjectGitTag, ProjectGitTags, ProjectMetadata, ProjectSummary, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioStepRun, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookHistory, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
|
|
6
|
+
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, MacroDefinitionSchema, MacroRunStartSchema, MacroStateSchema, MacroSummaryArraySchema, MacroSummarySchema, MacroWaitResultSchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectTagsSchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
|
7
|
+
export type { BuildMode, CodeEnvActionResult, CodeEnvCreateOptions, CodeEnvDetails, CodeEnvGetLogOptions, CodeEnvLogResult, CodeEnvLogSummary, CodeEnvPackageList, CodeEnvSetPackagesOptions, CodeEnvSummary, CodeEnvUpdateImagesOptions, CodeEnvUpdatePackagesOptions, CodeEnvUsage, CodeEnvVersionForProject, 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, MacroDefinition, MacroRunStart, MacroState, MacroSummary, MacroSummaryArray, MacroWaitResult, NotebookSession, ProjectDetails, ProjectGitActionResult, ProjectGitDiffResult, ProjectGitFutureResponse, ProjectGitFutureState, ProjectGitLibraries, ProjectGitLibrary, ProjectGitLogResult, ProjectGitRemote, ProjectGitStatus, ProjectGitTag, ProjectGitTags, ProjectMetadata, ProjectSummary, ProjectTags, ProjectVariables, RecipeCreateOptions, RecipeCreateResult, RecipeDetails, RecipeSummary, SafeParseResult, ScenarioDetails, ScenarioStatus, ScenarioStepRun, ScenarioSummary, ScenarioWaitResult, SqlNotebookCell, SqlNotebookContent, SqlNotebookHistory, SqlNotebookSummary, SqlQueryResponse, SqlQueryResult, SqlQuerySchema, WikiArticleData, WikiArticleMetadata, WikiSettings, WikiTaxonomyNode, } from "../packages/types/src/index.js";
|
package/dist/src/schemas.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* The types package (packages/types/) owns the TypeBox schema definitions.
|
|
4
4
|
* SDK consumers get everything through this re-export.
|
|
5
5
|
*/
|
|
6
|
-
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
|
6
|
+
export { BuildModeSchema, CodeEnvActionResultSchema, CodeEnvCreateOptionsSchema, CodeEnvDetailsSchema, CodeEnvGetLogOptionsSchema, CodeEnvLogResultSchema, CodeEnvLogSummaryArraySchema, CodeEnvLogSummarySchema, CodeEnvPackageListSchema, CodeEnvSetPackagesOptionsSchema, CodeEnvSummaryArraySchema, CodeEnvSummarySchema, CodeEnvUpdateImagesOptionsSchema, CodeEnvUpdatePackagesOptionsSchema, CodeEnvUsageArraySchema, CodeEnvVersionForProjectSchema, 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, MacroDefinitionSchema, MacroRunStartSchema, MacroStateSchema, MacroSummaryArraySchema, MacroSummarySchema, MacroWaitResultSchema, NotebookSessionArraySchema, NotebookSessionSchema, parseSchema, ProjectDetailsSchema, ProjectGitActionResultSchema, ProjectGitDiffResultSchema, ProjectGitFutureResponseSchema, ProjectGitFutureStateSchema, ProjectGitLibrariesSchema, ProjectGitLibrarySchema, ProjectGitLogResultSchema, ProjectGitRemoteSchema, ProjectGitStatusSchema, ProjectGitTagSchema, ProjectGitTagsSchema, ProjectMetadataSchema, ProjectSummaryArraySchema, ProjectSummarySchema, ProjectTagsSchema, ProjectVariablesSchema, RecipeCreateOptionsSchema, RecipeCreateResultSchema, RecipeDetailsSchema, RecipeSummaryArraySchema, RecipeSummarySchema, safeParseSchema, ScenarioDetailsSchema, ScenarioStatusSchema, ScenarioStepRunSchema, ScenarioSummaryArraySchema, ScenarioSummarySchema, ScenarioWaitResultSchema, SqlNotebookCellSchema, SqlNotebookContentSchema, SqlNotebookHistorySchema, SqlNotebookSummaryArraySchema, SqlNotebookSummarySchema, SqlQueryResponseSchema, SqlQueryResultSchema, SqlQuerySchemaSchema, WikiArticleDataArraySchema, WikiArticleDataSchema, WikiArticleMetadataSchema, WikiSettingsSchema, WikiTaxonomyNodeSchema, } from "../packages/types/src/index.js";
|
package/dist/src/skill.d.ts
CHANGED
|
@@ -29,18 +29,27 @@ export declare function detectAgents(): DetectedAgent[];
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function findWorkspaceRoot(startDir: string): string;
|
|
31
31
|
export type SkillStatus = "missing" | "stale" | "current";
|
|
32
|
+
export interface InstalledSkillFile {
|
|
33
|
+
relativePath: string;
|
|
34
|
+
path: string;
|
|
35
|
+
status: SkillStatus;
|
|
36
|
+
changed: boolean;
|
|
37
|
+
expectedSha256: string;
|
|
38
|
+
actualSha256?: string;
|
|
39
|
+
}
|
|
32
40
|
export interface InstallResult {
|
|
33
41
|
agent: string;
|
|
34
42
|
path: string;
|
|
35
43
|
via: DetectedAgent["via"];
|
|
36
|
-
/**
|
|
44
|
+
/** Missing entrypoint, incomplete/different bundle, or entirely current bundle. */
|
|
37
45
|
status: SkillStatus;
|
|
38
|
-
/** Whether
|
|
46
|
+
/** Whether any bundled file would (or did) change. Unmanaged files are preserved. */
|
|
39
47
|
changed: boolean;
|
|
40
|
-
/** SHA-256
|
|
48
|
+
/** SHA-256 of the canonical SKILL.md entrypoint, not the whole bundle. */
|
|
41
49
|
expectedSha256: string;
|
|
42
|
-
/**
|
|
50
|
+
/** Hash of the existing entrypoint; absent when that file is missing. */
|
|
43
51
|
actualSha256?: string;
|
|
52
|
+
files: InstalledSkillFile[];
|
|
44
53
|
}
|
|
45
54
|
export declare function planSkillInstalls(agents: DetectedAgent[], opts: {
|
|
46
55
|
global: boolean;
|
package/dist/src/skill.js
CHANGED
|
@@ -2,17 +2,21 @@ import { createHash, } from "node:crypto";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
+
import { fileURLToPath, } from "node:url";
|
|
5
6
|
const SKILL_URLS = [
|
|
6
7
|
new URL("../skills/dataiku-dss/SKILL.md", import.meta.url),
|
|
7
8
|
new URL("../../skills/dataiku-dss/SKILL.md", import.meta.url),
|
|
8
9
|
];
|
|
9
|
-
function
|
|
10
|
+
function skillDirectory() {
|
|
10
11
|
for (const skillUrl of SKILL_URLS) {
|
|
11
12
|
if (fs.existsSync(skillUrl))
|
|
12
|
-
return
|
|
13
|
+
return new URL("./", skillUrl);
|
|
13
14
|
}
|
|
14
15
|
throw new Error(`Bundled Dataiku skill not found. Checked: ${SKILL_URLS.map((url) => url.pathname).join(", ")}`);
|
|
15
16
|
}
|
|
17
|
+
function skillContent() {
|
|
18
|
+
return fs.readFileSync(new URL("SKILL.md", skillDirectory()), "utf-8");
|
|
19
|
+
}
|
|
16
20
|
export const AGENTS = {
|
|
17
21
|
claude: {
|
|
18
22
|
name: "Claude Code",
|
|
@@ -110,7 +114,27 @@ function skillState(target, expectedSha256) {
|
|
|
110
114
|
actualSha256,
|
|
111
115
|
};
|
|
112
116
|
}
|
|
113
|
-
|
|
117
|
+
/** Load the packaged tree, keeping portable relative paths in the report. */
|
|
118
|
+
function skillFiles() {
|
|
119
|
+
const root = fileURLToPath(skillDirectory());
|
|
120
|
+
const files = new Map();
|
|
121
|
+
function visit(relativeDir) {
|
|
122
|
+
const dir = path.join(root, relativeDir);
|
|
123
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true, }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
|
|
124
|
+
const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
|
|
125
|
+
if (entry.isDirectory())
|
|
126
|
+
visit(relativePath);
|
|
127
|
+
else if (entry.isFile()) {
|
|
128
|
+
files.set(relativePath, fs.readFileSync(path.join(root, relativePath)));
|
|
129
|
+
}
|
|
130
|
+
else
|
|
131
|
+
throw new Error(`Unsupported bundled skill entry: ${relativePath}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
visit("");
|
|
135
|
+
return files;
|
|
136
|
+
}
|
|
137
|
+
function skillInstallPlan(agents, opts, bundle) {
|
|
114
138
|
const home = os.homedir();
|
|
115
139
|
const results = [];
|
|
116
140
|
for (const { id, def, via, } of agents) {
|
|
@@ -121,38 +145,65 @@ export function planSkillInstalls(agents, opts) {
|
|
|
121
145
|
: undefined;
|
|
122
146
|
if (!dir)
|
|
123
147
|
continue;
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
148
|
+
const files = [];
|
|
149
|
+
for (const [sourcePath, source,] of bundle) {
|
|
150
|
+
const relativePath = sourcePath === "SKILL.md" ? def.filename : sourcePath;
|
|
151
|
+
const target = path.join(dir, relativePath);
|
|
152
|
+
const expectedSha256 = sha256Hex(sourcePath === "SKILL.md" ? def.content() : source);
|
|
153
|
+
const state = skillState(target, expectedSha256);
|
|
154
|
+
files.push({
|
|
155
|
+
relativePath,
|
|
156
|
+
path: target,
|
|
157
|
+
...state,
|
|
158
|
+
changed: state.status !== "current",
|
|
159
|
+
expectedSha256,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const entrypoint = files.find((file) => file.relativePath === def.filename);
|
|
163
|
+
const changed = files.some((file) => file.changed);
|
|
127
164
|
results.push({
|
|
128
165
|
agent: id,
|
|
129
|
-
path:
|
|
166
|
+
path: entrypoint.path,
|
|
130
167
|
via,
|
|
131
|
-
|
|
132
|
-
changed
|
|
133
|
-
expectedSha256,
|
|
168
|
+
status: entrypoint.status === "missing" ? "missing" : changed ? "stale" : "current",
|
|
169
|
+
changed,
|
|
170
|
+
expectedSha256: entrypoint.expectedSha256,
|
|
171
|
+
...(entrypoint.actualSha256 !== undefined ? { actualSha256: entrypoint.actualSha256, } : {}),
|
|
172
|
+
files,
|
|
134
173
|
});
|
|
135
174
|
}
|
|
136
175
|
return results;
|
|
137
176
|
}
|
|
177
|
+
export function planSkillInstalls(agents, opts) {
|
|
178
|
+
return skillInstallPlan(agents, opts, skillFiles());
|
|
179
|
+
}
|
|
180
|
+
function writeSkillFile(file, content) {
|
|
181
|
+
if (!file.changed)
|
|
182
|
+
return;
|
|
183
|
+
const dir = path.dirname(file.path);
|
|
184
|
+
fs.mkdirSync(dir, { recursive: true, });
|
|
185
|
+
const tmpPath = path.join(dir, `.${path.basename(file.path)}.tmp-${process.pid}-${Date.now().toString(36)}`);
|
|
186
|
+
try {
|
|
187
|
+
fs.writeFileSync(tmpPath, content);
|
|
188
|
+
fs.renameSync(tmpPath, file.path);
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
fs.rmSync(tmpPath, { force: true, });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
138
194
|
export function installSkill(agents, opts) {
|
|
139
|
-
const
|
|
195
|
+
const bundle = skillFiles();
|
|
196
|
+
const results = skillInstallPlan(agents, opts, bundle);
|
|
140
197
|
for (const result of results) {
|
|
141
|
-
|
|
142
|
-
if (!def || !result.changed)
|
|
198
|
+
if (!result.changed)
|
|
143
199
|
continue;
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
fs.renameSync(tmpPath, result.path);
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
fs.rmSync(tmpPath, { force: true, });
|
|
154
|
-
throw error;
|
|
200
|
+
const def = agents.find((agent) => agent.id === result.agent).def;
|
|
201
|
+
// Publish referenced files first; never expose a new entrypoint with missing references.
|
|
202
|
+
for (const file of result.files) {
|
|
203
|
+
if (file.relativePath !== def.filename)
|
|
204
|
+
writeSkillFile(file, bundle.get(file.relativePath));
|
|
155
205
|
}
|
|
206
|
+
writeSkillFile(result.files.find((file) => file.relativePath === def.filename), def.content());
|
|
156
207
|
}
|
|
157
208
|
return results;
|
|
158
209
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function deepMerge<T extends
|
|
1
|
+
export declare function deepMerge<T extends object>(base: T, patch: Record<string, unknown>): T & Record<string, unknown>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared polling helpers used by every long-running wait loop (jobs, futures,
|
|
3
|
+
* scenarios, macros, Visual ML training, Project Git futures).
|
|
4
|
+
*/
|
|
5
|
+
/** Hard ceiling for one adaptive backoff step (ms). */
|
|
6
|
+
export declare const MAX_POLL_INTERVAL_MS = 10000;
|
|
7
|
+
interface ComputeNextPollDelayMsOptions {
|
|
8
|
+
pollCount: number;
|
|
9
|
+
baseIntervalMs: number;
|
|
10
|
+
adaptiveEnabled: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compute the next poll delay.
|
|
14
|
+
* When adaptive polling is enabled, the interval doubles every 3 polls,
|
|
15
|
+
* capped at MAX_POLL_INTERVAL_MS (or baseIntervalMs if it's larger).
|
|
16
|
+
*/
|
|
17
|
+
export declare function computeNextPollDelayMs({ pollCount, baseIntervalMs, adaptiveEnabled, }: ComputeNextPollDelayMsOptions): number;
|
|
18
|
+
/** Distinguish an exhausted wait deadline from an earlier request timeout. */
|
|
19
|
+
export declare function isRequestDeadlineError(error: unknown, deadlineAt: number): boolean;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DataikuError, } from "../errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Shared polling helpers used by every long-running wait loop (jobs, futures,
|
|
4
|
+
* scenarios, macros, Visual ML training, Project Git futures).
|
|
5
|
+
*/
|
|
6
|
+
/** Hard ceiling for one adaptive backoff step (ms). */
|
|
7
|
+
export const MAX_POLL_INTERVAL_MS = 10_000;
|
|
8
|
+
/**
|
|
9
|
+
* Compute the next poll delay.
|
|
10
|
+
* When adaptive polling is enabled, the interval doubles every 3 polls,
|
|
11
|
+
* capped at MAX_POLL_INTERVAL_MS (or baseIntervalMs if it's larger).
|
|
12
|
+
*/
|
|
13
|
+
export function computeNextPollDelayMs({ pollCount, baseIntervalMs, adaptiveEnabled, }) {
|
|
14
|
+
if (!adaptiveEnabled) {
|
|
15
|
+
return baseIntervalMs;
|
|
16
|
+
}
|
|
17
|
+
const step = Math.max(0, Math.floor((pollCount - 1) / 3));
|
|
18
|
+
const interval = baseIntervalMs * 2 ** step;
|
|
19
|
+
return Math.min(interval, Math.max(baseIntervalMs, MAX_POLL_INTERVAL_MS));
|
|
20
|
+
}
|
|
21
|
+
/** Distinguish an exhausted wait deadline from an earlier request timeout. */
|
|
22
|
+
export function isRequestDeadlineError(error, deadlineAt) {
|
|
23
|
+
return Date.now() >= deadlineAt
|
|
24
|
+
&& error instanceof DataikuError
|
|
25
|
+
&& error.status === 0
|
|
26
|
+
&& (error.retry?.timedOut === true || error.statusText === "Request Timeout");
|
|
27
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { randomUUID, } from "node:crypto";
|
|
2
|
+
import { createWriteStream, } from "node:fs";
|
|
3
|
+
import { chmod, rename, rm, stat, } from "node:fs/promises";
|
|
4
|
+
import { basename, dirname, join, } from "node:path";
|
|
5
|
+
import { Readable, } from "node:stream";
|
|
6
|
+
import { pipeline, } from "node:stream/promises";
|
|
7
|
+
/** Stream with backpressure; publish only a complete download, preserving existing output on failure. */
|
|
8
|
+
export async function writeResponseToFile(path, response, permissions = "private") {
|
|
9
|
+
let mode;
|
|
10
|
+
if (permissions === "preserve") {
|
|
11
|
+
try {
|
|
12
|
+
mode = (await stat(path)).mode & 0o777;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
if (error.code !== "ENOENT")
|
|
16
|
+
throw error;
|
|
17
|
+
mode = 0o666 & ~process.umask();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const input = Readable.from(response.body, { objectMode: false, });
|
|
21
|
+
const temporaryPath = join(dirname(path), `.${basename(path)}.tmp-${randomUUID()}`);
|
|
22
|
+
const output = createWriteStream(temporaryPath, { flags: "wx", mode: 0o600, });
|
|
23
|
+
try {
|
|
24
|
+
await pipeline(input, output);
|
|
25
|
+
// Keep partial contents private; restore publication permissions only after completion.
|
|
26
|
+
if (mode !== undefined)
|
|
27
|
+
await chmod(temporaryPath, mode);
|
|
28
|
+
await rename(temporaryPath, path);
|
|
29
|
+
return output.bytesWritten;
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await rm(temporaryPath, { force: true, });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared recursive secret sanitizer for CLI output and error surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Walks any JSON-like value and:
|
|
5
|
+
* - replaces values under sensitive keys (per-domain key table) with `[redacted]`;
|
|
6
|
+
* - replaces exact occurrences of known secret values anywhere in strings;
|
|
7
|
+
* - optionally redacts userinfo embedded in HTTP(S) URL authorities
|
|
8
|
+
* (`https://user:pass@host/...` -> `https://[redacted]@host/...`).
|
|
9
|
+
*
|
|
10
|
+
* The SDK resource layer forwards values verbatim to DSS over TLS; sanitization
|
|
11
|
+
* is a CLI presentation concern and must never leak secret material instead.
|
|
12
|
+
*/
|
|
13
|
+
/** Marker replacing every redacted value or secret occurrence. */
|
|
14
|
+
export declare const SECRET_REDACTED = "[redacted]";
|
|
15
|
+
/** Sensitive keys are matched after stripping `-`/`_` and lowercasing. */
|
|
16
|
+
export declare function normalizeSecretKey(key: string): string;
|
|
17
|
+
export interface SecretSanitizeOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Per-domain table of sensitive keys (normalized form -> true). Policies
|
|
20
|
+
* deliberately differ between domains; never merge them.
|
|
21
|
+
*/
|
|
22
|
+
sensitiveKeys: Record<string, true>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional extra predicate over normalized keys for key families a flat
|
|
25
|
+
* table cannot express (e.g. the user `secrets` array).
|
|
26
|
+
*/
|
|
27
|
+
isSensitiveKey?: (normalizedKey: string) => boolean;
|
|
28
|
+
/** Exact secret values to replace everywhere in strings. */
|
|
29
|
+
secrets?: string[];
|
|
30
|
+
/** Also redact userinfo embedded in HTTP(S) URL authorities. */
|
|
31
|
+
redactUrlUserinfo?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Replace every exact occurrence of each secret so echoed errors cannot leak
|
|
35
|
+
* it. Empty secrets are skipped (an empty needle would corrupt every string).
|
|
36
|
+
*/
|
|
37
|
+
export declare function replaceSecrets(text: string, secrets: readonly string[]): string;
|
|
38
|
+
/**
|
|
39
|
+
* Redact the userinfo of every HTTP(S) URL in a string. DSS may contain legacy
|
|
40
|
+
* remotes with credentials in the URL, and Git error text can echo them.
|
|
41
|
+
*/
|
|
42
|
+
export declare function redactUrlUserinfo(text: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Recursively sanitize `value`: strings lose exact secret occurrences (and
|
|
45
|
+
* URL userinfo when enabled), objects redact values under sensitive keys and
|
|
46
|
+
* recurse, arrays recurse. Non-string scalars pass through unchanged.
|
|
47
|
+
*/
|
|
48
|
+
export declare function sanitizeSecrets<T>(value: T, options: SecretSanitizeOptions): T;
|
|
49
|
+
/**
|
|
50
|
+
* Scrub secret material from an error's message, stack, and string body.
|
|
51
|
+
* `DataikuError.message` is built at construction, so all three carriers need
|
|
52
|
+
* the same string pass as output values.
|
|
53
|
+
*/
|
|
54
|
+
export declare function sanitizeErrorSecrets(error: unknown, options: SecretSanitizeOptions): unknown;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared recursive secret sanitizer for CLI output and error surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Walks any JSON-like value and:
|
|
5
|
+
* - replaces values under sensitive keys (per-domain key table) with `[redacted]`;
|
|
6
|
+
* - replaces exact occurrences of known secret values anywhere in strings;
|
|
7
|
+
* - optionally redacts userinfo embedded in HTTP(S) URL authorities
|
|
8
|
+
* (`https://user:pass@host/...` -> `https://[redacted]@host/...`).
|
|
9
|
+
*
|
|
10
|
+
* The SDK resource layer forwards values verbatim to DSS over TLS; sanitization
|
|
11
|
+
* is a CLI presentation concern and must never leak secret material instead.
|
|
12
|
+
*/
|
|
13
|
+
/** Marker replacing every redacted value or secret occurrence. */
|
|
14
|
+
export const SECRET_REDACTED = "[redacted]";
|
|
15
|
+
/** Sensitive keys are matched after stripping `-`/`_` and lowercasing. */
|
|
16
|
+
export function normalizeSecretKey(key) {
|
|
17
|
+
return key.replace(/[-_]/g, "").toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Replace every exact occurrence of each secret so echoed errors cannot leak
|
|
21
|
+
* it. Empty secrets are skipped (an empty needle would corrupt every string).
|
|
22
|
+
*/
|
|
23
|
+
export function replaceSecrets(text, secrets) {
|
|
24
|
+
let result = text;
|
|
25
|
+
for (const secret of secrets) {
|
|
26
|
+
if (secret !== "" && secret !== undefined && secret !== null) {
|
|
27
|
+
result = result.split(secret).join(SECRET_REDACTED);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Redact the userinfo of every HTTP(S) URL in a string. DSS may contain legacy
|
|
34
|
+
* remotes with credentials in the URL, and Git error text can echo them.
|
|
35
|
+
*/
|
|
36
|
+
export function redactUrlUserinfo(text) {
|
|
37
|
+
return text.replace(/https?:[\\/]{1,2}[^\s"'<>]+/giu, (url) => {
|
|
38
|
+
const schemeEnd = url.indexOf(":") + 1;
|
|
39
|
+
let authorityStart = schemeEnd;
|
|
40
|
+
while (url[authorityStart] === "/" || url[authorityStart] === "\\")
|
|
41
|
+
authorityStart++;
|
|
42
|
+
const slash = url.slice(authorityStart).search(/[\\/]/u);
|
|
43
|
+
const authorityEnd = slash === -1 ? url.length : authorityStart + slash;
|
|
44
|
+
const at = url.lastIndexOf("@", authorityEnd - 1);
|
|
45
|
+
if (at < authorityStart)
|
|
46
|
+
return url;
|
|
47
|
+
return `${url.slice(0, authorityStart)}${SECRET_REDACTED}@${url.slice(at + 1)}`;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Recursively sanitize `value`: strings lose exact secret occurrences (and
|
|
52
|
+
* URL userinfo when enabled), objects redact values under sensitive keys and
|
|
53
|
+
* recurse, arrays recurse. Non-string scalars pass through unchanged.
|
|
54
|
+
*/
|
|
55
|
+
export function sanitizeSecrets(value, options) {
|
|
56
|
+
const { secrets = [], } = options;
|
|
57
|
+
const stringPass = (text) => {
|
|
58
|
+
const sanitized = options.redactUrlUserinfo ? redactUrlUserinfo(text) : text;
|
|
59
|
+
return replaceSecrets(sanitized, secrets);
|
|
60
|
+
};
|
|
61
|
+
if (typeof value === "string") {
|
|
62
|
+
return stringPass(value);
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(value)) {
|
|
65
|
+
return value.map((item) => sanitizeSecrets(item, options));
|
|
66
|
+
}
|
|
67
|
+
if (value !== null && typeof value === "object") {
|
|
68
|
+
const sanitized = {};
|
|
69
|
+
for (const [key, item,] of Object.entries(value)) {
|
|
70
|
+
const normalizedKey = normalizeSecretKey(key);
|
|
71
|
+
sanitized[key] = options.sensitiveKeys[normalizedKey] === true
|
|
72
|
+
|| options.isSensitiveKey?.(normalizedKey) === true
|
|
73
|
+
? SECRET_REDACTED
|
|
74
|
+
: sanitizeSecrets(item, options);
|
|
75
|
+
}
|
|
76
|
+
return sanitized;
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Scrub secret material from an error's message, stack, and string body.
|
|
82
|
+
* `DataikuError.message` is built at construction, so all three carriers need
|
|
83
|
+
* the same string pass as output values.
|
|
84
|
+
*/
|
|
85
|
+
export function sanitizeErrorSecrets(error, options) {
|
|
86
|
+
if (!(error instanceof Error))
|
|
87
|
+
return error;
|
|
88
|
+
const stringPass = (text) => {
|
|
89
|
+
const sanitized = options.redactUrlUserinfo ? redactUrlUserinfo(text) : text;
|
|
90
|
+
return replaceSecrets(sanitized, options.secrets ?? []);
|
|
91
|
+
};
|
|
92
|
+
error.message = stringPass(error.message);
|
|
93
|
+
if (typeof error.stack === "string") {
|
|
94
|
+
error.stack = stringPass(error.stack);
|
|
95
|
+
}
|
|
96
|
+
const errorWithBody = error;
|
|
97
|
+
if (typeof errorWithBody.body === "string") {
|
|
98
|
+
errorWithBody.body = stringPass(errorWithBody.body);
|
|
99
|
+
}
|
|
100
|
+
return error;
|
|
101
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataiku-sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Dataiku DSS SDK and CLI for programmatic access to DSS REST APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -25,13 +25,15 @@
|
|
|
25
25
|
"build": "tsc && bun scripts/generate-build-metadata.mjs && tsc -p packages/types/tsconfig.json",
|
|
26
26
|
"prepack": "bun scripts/sync-plugin-version.mjs --check && tsc && bun scripts/generate-build-metadata.mjs && tsc -p packages/types/tsconfig.json",
|
|
27
27
|
"prepublishOnly": "bun scripts/sync-plugin-version.mjs --check && tsc && bun scripts/generate-build-metadata.mjs && tsc -p packages/types/tsconfig.json",
|
|
28
|
-
"check": "tsc --noEmit && bun scripts/sync-plugin-version.mjs --check",
|
|
28
|
+
"check": "tsc --noEmit && tsc -p tools/oxlint/tsconfig.json && bun run check:live && bun scripts/sync-plugin-version.mjs --check",
|
|
29
29
|
"version": "bun scripts/sync-plugin-version.mjs && git add plugin.json",
|
|
30
|
-
"lint": "oxlint src/",
|
|
31
|
-
"lint:fix": "oxlint --fix src/",
|
|
30
|
+
"lint": "oxlint src/ tools/oxlint/ scripts/live-suite.ts tests/live-*.ts",
|
|
31
|
+
"lint:fix": "oxlint --fix src/ tools/oxlint/ scripts/live-suite.ts tests/live-*.ts",
|
|
32
32
|
"format": "dprint fmt",
|
|
33
33
|
"format:check": "dprint check",
|
|
34
34
|
"test": "bun test",
|
|
35
|
+
"test:live": "bun --no-env-file scripts/live-suite.ts",
|
|
36
|
+
"check:live": "tsc --noEmit -p tsconfig.live.json",
|
|
35
37
|
"test:tokens": "bun test tests/cli/agent-token-budget.test.ts",
|
|
36
38
|
"test:platform": "bun scripts/platform-smoke.mjs",
|
|
37
39
|
"test:integration": "cross-env RUN_DATAIKU_INTEGRATION=1 bun test tests/integration-playground.test.ts",
|
|
@@ -40,11 +42,12 @@
|
|
|
40
42
|
"test:integration:rigorous:mutating": "cross-env RUN_DATAIKU_INTEGRATION=1 RUN_DATAIKU_INTEGRATION_MUTATING=1 bun test tests/integration-rigorous.test.ts"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
45
|
+
"@oxlint/plugins": "1.81.0",
|
|
43
46
|
"@types/bun": "^1.4.0",
|
|
44
47
|
"cross-env": "^10.1.0",
|
|
45
48
|
"dprint": "^0.57.0",
|
|
46
49
|
"js-tiktoken": "1.0.21",
|
|
47
|
-
"oxlint": "
|
|
50
|
+
"oxlint": "1.81.0",
|
|
48
51
|
"typescript": "^7.0.2",
|
|
49
52
|
"typescript-language-server": "6.0.0",
|
|
50
53
|
"typescript-language-service": "npm:typescript@5.9.3"
|