deepline 0.2.71 → 0.2.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundling-sources/sdk/src/client.ts +8 -2
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +67 -14
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +55 -14
- package/dist/cli/index.js +306 -24
- package/dist/cli/index.mjs +343 -53
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +43 -16
- package/dist/index.mjs +43 -16
- package/dist/plays/bundle-play-file.mjs +35 -14
- package/package.json +1 -1
|
@@ -4008,9 +4008,15 @@ export class DeeplineClient {
|
|
|
4008
4008
|
* console.log(`Total runs: ${detail.play.runCount}`);
|
|
4009
4009
|
* ```
|
|
4010
4010
|
*/
|
|
4011
|
-
async getPlay(
|
|
4011
|
+
async getPlay(
|
|
4012
|
+
name: string,
|
|
4013
|
+
options?: { source?: 'working' | 'live' | `version:${number}` },
|
|
4014
|
+
): Promise<PlayDetail> {
|
|
4012
4015
|
const encodedName = encodeURIComponent(name);
|
|
4013
|
-
|
|
4016
|
+
const query = options?.source
|
|
4017
|
+
? `?include=source&revision=${encodeURIComponent(options.source)}`
|
|
4018
|
+
: '';
|
|
4019
|
+
return this.http.get<PlayDetail>(`/api/v2/plays/${encodedName}${query}`);
|
|
4014
4020
|
}
|
|
4015
4021
|
|
|
4016
4022
|
/**
|
|
@@ -183,7 +183,7 @@ export const SDK_RELEASE = {
|
|
|
183
183
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
184
184
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
185
185
|
// release keeps lazy paging semantics independent of row residency.
|
|
186
|
-
version: '0.2.
|
|
186
|
+
version: '0.2.72',
|
|
187
187
|
contracts: {
|
|
188
188
|
api: {
|
|
189
189
|
name: 'sdk-http-api',
|
|
@@ -1200,6 +1200,16 @@ export interface PlayDetail {
|
|
|
1200
1200
|
customerDbUrl: string;
|
|
1201
1201
|
/** Change cursor for incremental sync. */
|
|
1202
1202
|
deltaCursor: number;
|
|
1203
|
+
/**
|
|
1204
|
+
* Present only when requested through `getPlay(..., { source: ... })`.
|
|
1205
|
+
* `files` is the complete authored source tree, keyed by logical path.
|
|
1206
|
+
*/
|
|
1207
|
+
source?: {
|
|
1208
|
+
selector: 'working' | 'live' | `version:${number}`;
|
|
1209
|
+
revision: { id: string; version: number };
|
|
1210
|
+
entryFile: string;
|
|
1211
|
+
files: Record<string, string>;
|
|
1212
|
+
};
|
|
1203
1213
|
}
|
|
1204
1214
|
|
|
1205
1215
|
export interface ClearPlayHistoryRequest {
|
|
@@ -61,16 +61,60 @@ const liveToolResultListDatasets = new Map<
|
|
|
61
61
|
PlayDataset<Record<string, unknown>>
|
|
62
62
|
>();
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Keys that describe a field rather than carry it.
|
|
66
|
+
*
|
|
67
|
+
* These sit next to the real value under a similar name, so a substring match
|
|
68
|
+
* on the target name reaches them as soon as the real field is absent.
|
|
69
|
+
* `phone_status: "unfound"` is not a phone number and `email_type: "work"` is
|
|
70
|
+
* not an email address.
|
|
71
|
+
*/
|
|
72
|
+
const DESCRIPTOR_SUFFIX =
|
|
73
|
+
/_(status|type|score|count|id|verified|valid|confidence|quality|source)$/i;
|
|
74
|
+
|
|
75
|
+
/** A company-scoped key is never the person-scoped answer. */
|
|
76
|
+
const COMPANY_SCOPED = /company/i;
|
|
77
|
+
|
|
78
|
+
type TargetFallbackRule = {
|
|
79
|
+
/** Key names that may carry this target's value. */
|
|
80
|
+
match: readonly RegExp[];
|
|
81
|
+
/** Key names that must never be treated as this target's value. */
|
|
82
|
+
reject?: readonly RegExp[];
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const TARGET_FALLBACK_KEYS: Record<string, TargetFallbackRule> = {
|
|
86
|
+
email: {
|
|
87
|
+
match: [/^email$/i, /^address$/i, /email/i],
|
|
88
|
+
reject: [DESCRIPTOR_SUFFIX],
|
|
89
|
+
},
|
|
90
|
+
phone: {
|
|
91
|
+
match: [/^phone$/i, /mobile/i, /phone/i, /telephone/i],
|
|
92
|
+
reject: [DESCRIPTOR_SUFFIX],
|
|
93
|
+
},
|
|
94
|
+
linkedin: {
|
|
95
|
+
match: [/^linkedin_url$/i, /^linkedin$/i, /linkedin/i],
|
|
96
|
+
reject: [DESCRIPTOR_SUFFIX, COMPANY_SCOPED],
|
|
97
|
+
},
|
|
98
|
+
company_linkedin_url: {
|
|
99
|
+
match: [/company.*linkedin/i, /linkedin.*company/i],
|
|
100
|
+
reject: [DESCRIPTOR_SUFFIX],
|
|
101
|
+
},
|
|
102
|
+
company_domain: {
|
|
103
|
+
match: [/^company_domain$/i, /company.*domain/i],
|
|
104
|
+
reject: [DESCRIPTOR_SUFFIX],
|
|
105
|
+
},
|
|
106
|
+
company_name: {
|
|
107
|
+
match: [/^company_name$/i, /company.*name/i],
|
|
108
|
+
reject: [DESCRIPTOR_SUFFIX],
|
|
109
|
+
},
|
|
110
|
+
domain: {
|
|
111
|
+
match: [/^domain$/i, /company_domain/i, /domain/i],
|
|
112
|
+
reject: [DESCRIPTOR_SUFFIX],
|
|
113
|
+
},
|
|
114
|
+
// Status targets legitimately want the `_status` keys the suffix rule
|
|
115
|
+
// rejects elsewhere, so they carry no rejections.
|
|
116
|
+
status: { match: [/^email_status$/i, /^status$/i] },
|
|
117
|
+
email_status: { match: [/^email_status$/i, /^status$/i] },
|
|
74
118
|
};
|
|
75
119
|
|
|
76
120
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
@@ -586,12 +630,13 @@ function findFirstTargetByKey(
|
|
|
586
630
|
}
|
|
587
631
|
if (!isRecord(result)) return null;
|
|
588
632
|
|
|
589
|
-
const
|
|
590
|
-
new RegExp(`^${target}$`, 'i'),
|
|
591
|
-
|
|
633
|
+
const rule: TargetFallbackRule = TARGET_FALLBACK_KEYS[target] ?? {
|
|
634
|
+
match: [new RegExp(`^${target}$`, 'i')],
|
|
635
|
+
};
|
|
592
636
|
for (const [key, value] of Object.entries(result)) {
|
|
637
|
+
if (rule.reject?.some((pattern) => pattern.test(key))) continue;
|
|
593
638
|
if (
|
|
594
|
-
|
|
639
|
+
rule.match.some((pattern) => pattern.test(key)) &&
|
|
595
640
|
isMeaningfulValue(value)
|
|
596
641
|
) {
|
|
597
642
|
return { value, path: pathToString([...path, key]) };
|
|
@@ -896,6 +941,14 @@ function buildTargets(
|
|
|
896
941
|
targets[target] = fromMetadata;
|
|
897
942
|
continue;
|
|
898
943
|
}
|
|
944
|
+
// Declared paths are routinely incomplete against the shape a provider
|
|
945
|
+
// actually returns (zerobounce declares `result.data.email` and answers
|
|
946
|
+
// with `address`), so the key scan stays as the rescue. It is bounded by
|
|
947
|
+
// each target's `reject` rules: the scan runs precisely when the provider
|
|
948
|
+
// returned no value, which is when a same-named neighbour is most likely
|
|
949
|
+
// to be a different field. Without those rules a real Wiza miss resolved
|
|
950
|
+
// `phone` to `phone_status: "unfound"` and `linkedin` to
|
|
951
|
+
// `company_linkedin`, reporting a company page as the person's profile.
|
|
899
952
|
const fallback = findFirstTargetByKey(result, target);
|
|
900
953
|
if (fallback) {
|
|
901
954
|
targets[target] = fallback;
|
|
@@ -137,6 +137,18 @@ export type PlayBundlingAdapter = {
|
|
|
137
137
|
warnAboutNonDevelopmentBundling?(filePath: string): void;
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
+
type PathRelationshipApi = {
|
|
141
|
+
relative(from: string, to: string): string;
|
|
142
|
+
isAbsolute(path: string): boolean;
|
|
143
|
+
sep: string;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const defaultPathRelationshipApi: PathRelationshipApi = {
|
|
147
|
+
relative,
|
|
148
|
+
isAbsolute,
|
|
149
|
+
sep,
|
|
150
|
+
};
|
|
151
|
+
|
|
140
152
|
function assertValidExportName(exportName: string): void {
|
|
141
153
|
if (exportName === 'default') return;
|
|
142
154
|
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(exportName)) {
|
|
@@ -207,10 +219,10 @@ function sha256(value: string): string {
|
|
|
207
219
|
|
|
208
220
|
function sourceIdentityPath(
|
|
209
221
|
filePath: string,
|
|
210
|
-
|
|
222
|
+
sourceIdentityRoot: string | undefined,
|
|
211
223
|
): string {
|
|
212
|
-
if (!
|
|
213
|
-
const identityRoot = resolve(
|
|
224
|
+
if (!sourceIdentityRoot) return filePath;
|
|
225
|
+
const identityRoot = resolve(sourceIdentityRoot);
|
|
214
226
|
const logicalPath = relative(identityRoot, resolve(filePath));
|
|
215
227
|
if (
|
|
216
228
|
!logicalPath ||
|
|
@@ -254,8 +266,18 @@ function createPlayWorkspace(entryFile: string): PlayWorkspace {
|
|
|
254
266
|
};
|
|
255
267
|
}
|
|
256
268
|
|
|
257
|
-
function isPathInsideDirectory(
|
|
258
|
-
|
|
269
|
+
export function isPathInsideDirectory(
|
|
270
|
+
filePath: string,
|
|
271
|
+
directory: string,
|
|
272
|
+
pathApi: PathRelationshipApi = defaultPathRelationshipApi,
|
|
273
|
+
): boolean {
|
|
274
|
+
const relationship = pathApi.relative(directory, filePath);
|
|
275
|
+
return (
|
|
276
|
+
relationship === '' ||
|
|
277
|
+
(relationship !== '..' &&
|
|
278
|
+
!relationship.startsWith(`..${pathApi.sep}`) &&
|
|
279
|
+
!pathApi.isAbsolute(relationship))
|
|
280
|
+
);
|
|
259
281
|
}
|
|
260
282
|
|
|
261
283
|
function assertWithinPlayWorkspace(input: {
|
|
@@ -1851,6 +1873,7 @@ async function analyzeSourceGraph(
|
|
|
1851
1873
|
): Promise<SourceGraphAnalysis> {
|
|
1852
1874
|
const absoluteEntryFile = await normalizeLocalPath(entryFile);
|
|
1853
1875
|
const workspace = createPlayWorkspace(absoluteEntryFile);
|
|
1876
|
+
const sourceIdentityRoot = adapter.sourceIdentityRoot;
|
|
1854
1877
|
const localFiles = new Map<string, string>();
|
|
1855
1878
|
const nodeBuiltins = new Set<string>();
|
|
1856
1879
|
const packages = new Map<string, string | null>();
|
|
@@ -1961,10 +1984,10 @@ async function analyzeSourceGraph(
|
|
|
1961
1984
|
const sourceHash = sha256(sourceCode);
|
|
1962
1985
|
const graphHash = sha256(
|
|
1963
1986
|
JSON.stringify({
|
|
1964
|
-
entryFile: sourceIdentityPath(absoluteEntryFile,
|
|
1987
|
+
entryFile: sourceIdentityPath(absoluteEntryFile, sourceIdentityRoot),
|
|
1965
1988
|
localFiles: [...localFiles.entries()]
|
|
1966
1989
|
.map(([filePath, contents]) => ({
|
|
1967
|
-
filePath: sourceIdentityPath(filePath,
|
|
1990
|
+
filePath: sourceIdentityPath(filePath, sourceIdentityRoot),
|
|
1968
1991
|
hash: sha256(contents),
|
|
1969
1992
|
}))
|
|
1970
1993
|
.sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
@@ -1974,7 +1997,7 @@ async function analyzeSourceGraph(
|
|
|
1974
1997
|
.sort((left, right) => left.name.localeCompare(right.name)),
|
|
1975
1998
|
importedPlayDependencies: [...importedPlayDependencies.values()]
|
|
1976
1999
|
.map((dependency) => ({
|
|
1977
|
-
filePath: sourceIdentityPath(dependency.filePath,
|
|
2000
|
+
filePath: sourceIdentityPath(dependency.filePath, sourceIdentityRoot),
|
|
1978
2001
|
playName: dependency.playName,
|
|
1979
2002
|
}))
|
|
1980
2003
|
.sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
@@ -2199,6 +2222,11 @@ export async function bundlePlayFile(
|
|
|
2199
2222
|
const exportName = options.exportName?.trim() || 'default';
|
|
2200
2223
|
assertValidExportName(exportName);
|
|
2201
2224
|
const absolutePath = await normalizeLocalPath(filePath);
|
|
2225
|
+
// Keep the existing absolute-path wire format unless a caller explicitly
|
|
2226
|
+
// opts into a logical identity root. Production's deployed checker still
|
|
2227
|
+
// uses absolute paths to reconcile bundled imports; source export normalizes
|
|
2228
|
+
// those paths into a portable tree at the API boundary.
|
|
2229
|
+
const sourceIdentityRoot = adapter.sourceIdentityRoot;
|
|
2202
2230
|
adapter.warnAboutNonDevelopmentBundling?.(absolutePath);
|
|
2203
2231
|
|
|
2204
2232
|
try {
|
|
@@ -2210,6 +2238,19 @@ export async function bundlePlayFile(
|
|
|
2210
2238
|
analysis.graphHash = sha256(
|
|
2211
2239
|
`${analysis.graphHash}\nentry-export:${exportName}\nauthoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`,
|
|
2212
2240
|
);
|
|
2241
|
+
const sourceFiles = Object.fromEntries(
|
|
2242
|
+
Object.entries(analysis.sourceFiles).map(([sourcePath, sourceCode]) => [
|
|
2243
|
+
sourceIdentityPath(sourcePath, sourceIdentityRoot),
|
|
2244
|
+
sourceCode,
|
|
2245
|
+
]),
|
|
2246
|
+
);
|
|
2247
|
+
const importPolicy: PlayImportPolicy = {
|
|
2248
|
+
...analysis.importPolicy,
|
|
2249
|
+
localFiles: analysis.importPolicy.localFiles.map((sourcePath) =>
|
|
2250
|
+
sourceIdentityPath(sourcePath, sourceIdentityRoot),
|
|
2251
|
+
),
|
|
2252
|
+
};
|
|
2253
|
+
const entryFile = sourceIdentityPath(absolutePath, sourceIdentityRoot);
|
|
2213
2254
|
try {
|
|
2214
2255
|
validatePlaySourceFilesHaveNoInlineSecrets(analysis.sourceFiles);
|
|
2215
2256
|
} catch (error) {
|
|
@@ -2267,9 +2308,9 @@ export async function bundlePlayFile(
|
|
|
2267
2308
|
success: true,
|
|
2268
2309
|
artifact: {
|
|
2269
2310
|
...cachedArtifact,
|
|
2270
|
-
entryFile
|
|
2311
|
+
entryFile,
|
|
2271
2312
|
sourceHash: analysis.sourceHash,
|
|
2272
|
-
importPolicy
|
|
2313
|
+
importPolicy,
|
|
2273
2314
|
compatibility: buildPlayContractCompatibility({
|
|
2274
2315
|
toolErrorSchemaVersion:
|
|
2275
2316
|
analysis.toolErrorSchemaVersion ?? undefined,
|
|
@@ -2277,7 +2318,7 @@ export async function bundlePlayFile(
|
|
|
2277
2318
|
cacheHit: true,
|
|
2278
2319
|
},
|
|
2279
2320
|
sourceCode: analysis.sourceCode,
|
|
2280
|
-
sourceFiles
|
|
2321
|
+
sourceFiles,
|
|
2281
2322
|
filePath: absolutePath,
|
|
2282
2323
|
playName: analysis.playName,
|
|
2283
2324
|
playDescription: analysis.playDescription,
|
|
@@ -2330,7 +2371,7 @@ export async function bundlePlayFile(
|
|
|
2330
2371
|
const artifact: PlayBundleArtifact = {
|
|
2331
2372
|
codeFormat: 'cjs_module',
|
|
2332
2373
|
artifactKind: target,
|
|
2333
|
-
entryFile
|
|
2374
|
+
entryFile,
|
|
2334
2375
|
virtualFilename,
|
|
2335
2376
|
sourceHash: analysis.sourceHash,
|
|
2336
2377
|
graphHash: analysis.graphHash,
|
|
@@ -2338,7 +2379,7 @@ export async function bundlePlayFile(
|
|
|
2338
2379
|
sourceMapHash: sha256(normalizedSourceMap),
|
|
2339
2380
|
bundledCode: executableCode,
|
|
2340
2381
|
sourceMap: normalizedSourceMap,
|
|
2341
|
-
importPolicy
|
|
2382
|
+
importPolicy,
|
|
2342
2383
|
compatibility: buildPlayContractCompatibility({
|
|
2343
2384
|
toolErrorSchemaVersion: analysis.toolErrorSchemaVersion ?? undefined,
|
|
2344
2385
|
}),
|
|
@@ -2352,7 +2393,7 @@ export async function bundlePlayFile(
|
|
|
2352
2393
|
success: true,
|
|
2353
2394
|
artifact,
|
|
2354
2395
|
sourceCode: analysis.sourceCode,
|
|
2355
|
-
sourceFiles
|
|
2396
|
+
sourceFiles,
|
|
2356
2397
|
filePath: absolutePath,
|
|
2357
2398
|
playName: analysis.playName,
|
|
2358
2399
|
playDescription: analysis.playDescription,
|