deepline 0.3.273 → 0.3.275
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 +143 -14
- package/dist/bundling-sources/sdk/src/index.ts +4 -1
- package/dist/bundling-sources/sdk/src/play.ts +5 -11
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/runs/log-cursor.ts +35 -0
- package/dist/bundling-sources/sdk/src/types.ts +10 -3
- package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -26
- package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +7 -3
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +15 -7
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +18 -18
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +7 -4
- package/dist/bundling-sources/shared_libs/plays/table-csv.ts +152 -0
- package/dist/cli/index.js +418 -103
- package/dist/cli/index.mjs +418 -103
- package/dist/{client-5xpuGpRn.d.ts → client-5zY7LsId.d.ts} +72 -7
- package/dist/{client-D9annc6K.d.mts → client-CbNvJLgV.d.mts} +72 -7
- package/dist/index.d.mts +6 -12
- package/dist/index.d.ts +6 -12
- package/dist/index.js +90 -12
- package/dist/index.mjs +90 -12
- package/dist/install-integrity.json +4 -2
- package/dist/plays/run-request.d.mts +1 -1
- package/dist/plays/run-request.d.ts +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one CSV writer for a Play table export, shared by the dashboard download
|
|
3
|
+
* (`GET /api/v2/plays/{name}/sheet/export`) and the CLI
|
|
4
|
+
* (`deepline runs export`), so the same table reads the same in either file.
|
|
5
|
+
* Pure: it runs on the server, in the browser (clipboard copy) and in the CLI.
|
|
6
|
+
*
|
|
7
|
+
* Cell rules: an empty value is an empty field, booleans are `true`/`false`,
|
|
8
|
+
* objects and arrays are compact JSON, and a field is quoted only when it has
|
|
9
|
+
* to be (RFC 4180).
|
|
10
|
+
*
|
|
11
|
+
* A failed row exports as written, and says why it failed: when any row of the
|
|
12
|
+
* export failed, every record ends with an `_error` column holding the row's
|
|
13
|
+
* failure reason (empty on a row that did not fail).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** The trailing column carrying a failed row's reason. */
|
|
17
|
+
export const TABLE_EXPORT_ERROR_COLUMN = '_error';
|
|
18
|
+
|
|
19
|
+
/** Legacy settled-sheet columns retained for existing CSV consumers. */
|
|
20
|
+
export const TABLE_EXPORT_STATUS_COLUMN = 'row_status';
|
|
21
|
+
export const TABLE_EXPORT_ROW_ERROR_COLUMN = 'row_error';
|
|
22
|
+
|
|
23
|
+
/** What a failed row says when its writer recorded no reason. */
|
|
24
|
+
const UNRECORDED_FAILURE_REASON = 'Row failed without a recorded reason.';
|
|
25
|
+
|
|
26
|
+
/** A cell's raw value as text: objects as JSON, empty as ''. */
|
|
27
|
+
export function tableCellText(value: unknown): string {
|
|
28
|
+
if (value === null || value === undefined) return '';
|
|
29
|
+
if (typeof value === 'string') return value;
|
|
30
|
+
if (
|
|
31
|
+
typeof value === 'number' ||
|
|
32
|
+
typeof value === 'bigint' ||
|
|
33
|
+
typeof value === 'boolean'
|
|
34
|
+
)
|
|
35
|
+
return String(value);
|
|
36
|
+
if (value instanceof Date) return value.toISOString();
|
|
37
|
+
if (typeof value === 'symbol' || typeof value === 'function') return '';
|
|
38
|
+
try {
|
|
39
|
+
return (
|
|
40
|
+
JSON.stringify(value, (_key, nested: unknown) =>
|
|
41
|
+
typeof nested === 'bigint' ? nested.toString() : nested,
|
|
42
|
+
) ?? ''
|
|
43
|
+
);
|
|
44
|
+
} catch {
|
|
45
|
+
return String(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** One RFC 4180 field: quoted (quotes doubled) when it holds `,` `"` or a newline. */
|
|
50
|
+
export function csvField(value: unknown): string {
|
|
51
|
+
const text = tableCellText(value);
|
|
52
|
+
return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** One CSV record, newline-terminated. */
|
|
56
|
+
export function csvRecord(values: readonly unknown[]): string {
|
|
57
|
+
return `${values.map(csvField).join(',')}\n`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** A sheet row as an export reads it: its data, its status, its error. */
|
|
61
|
+
export type TableExportRow = {
|
|
62
|
+
data: Record<string, unknown>;
|
|
63
|
+
status?: unknown;
|
|
64
|
+
error?: unknown;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function isFailedRow(row: { status?: unknown }): boolean {
|
|
68
|
+
return row.status === 'failed';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Whether any of these rows failed, so the export carries `_error`. */
|
|
72
|
+
export function tableExportHasFailedRows(
|
|
73
|
+
rows: Iterable<{ status?: unknown }>,
|
|
74
|
+
): boolean {
|
|
75
|
+
for (const row of rows) if (isFailedRow(row)) return true;
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The `_error` cell of one row: its failure reason, or '' when it did not fail. */
|
|
80
|
+
export function tableExportErrorCell(row: {
|
|
81
|
+
status?: unknown;
|
|
82
|
+
error?: unknown;
|
|
83
|
+
}): string {
|
|
84
|
+
if (!isFailedRow(row)) return '';
|
|
85
|
+
const reason = typeof row.error === 'string' ? row.error.trim() : '';
|
|
86
|
+
return reason || UNRECORDED_FAILURE_REASON;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** The export header: the table's columns, then `_error` when a row failed. */
|
|
90
|
+
export function tableExportColumns(
|
|
91
|
+
columns: readonly string[],
|
|
92
|
+
withError: boolean,
|
|
93
|
+
): string[] {
|
|
94
|
+
if (!withError) return [...columns];
|
|
95
|
+
return [
|
|
96
|
+
...columns.filter((column) => column !== TABLE_EXPORT_ERROR_COLUMN),
|
|
97
|
+
TABLE_EXPORT_ERROR_COLUMN,
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** One row's cells, in `tableExportColumns(columns, withError)` order. */
|
|
102
|
+
export function tableExportCells(
|
|
103
|
+
row: TableExportRow,
|
|
104
|
+
columns: readonly string[],
|
|
105
|
+
withError: boolean,
|
|
106
|
+
): unknown[] {
|
|
107
|
+
return tableExportColumns(columns, withError).map((column) =>
|
|
108
|
+
column === TABLE_EXPORT_ERROR_COLUMN && withError
|
|
109
|
+
? tableExportErrorCell(row)
|
|
110
|
+
: Object.hasOwn(row.data, column)
|
|
111
|
+
? row.data[column]
|
|
112
|
+
: undefined,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Settled dashboard downloads keep their established status/reason columns.
|
|
118
|
+
* The CLI's newer `_error` projection is separate; both use this module's CSV
|
|
119
|
+
* encoding so spreadsheet escaping and cell formatting stay consistent.
|
|
120
|
+
*/
|
|
121
|
+
export function tableExportSettledColumns(
|
|
122
|
+
columns: readonly string[],
|
|
123
|
+
withFailureDetails: boolean,
|
|
124
|
+
): string[] {
|
|
125
|
+
return withFailureDetails
|
|
126
|
+
? [...columns, TABLE_EXPORT_STATUS_COLUMN, TABLE_EXPORT_ROW_ERROR_COLUMN]
|
|
127
|
+
: [...columns];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** A settled dashboard row, preserving the public `row_status,row_error` contract. */
|
|
131
|
+
export function tableExportSettledCells(
|
|
132
|
+
row: TableExportRow,
|
|
133
|
+
columns: readonly string[],
|
|
134
|
+
withFailureDetails: boolean,
|
|
135
|
+
): unknown[] {
|
|
136
|
+
const values = columns.map((column) =>
|
|
137
|
+
Object.hasOwn(row.data, column) ? row.data[column] : undefined,
|
|
138
|
+
);
|
|
139
|
+
return withFailureDetails
|
|
140
|
+
? [...values, row.status, row.status === 'failed' ? (row.error ?? '') : '']
|
|
141
|
+
: values;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** A whole table as CSV text: the header record, then one record per row. */
|
|
145
|
+
export function tableCsvText(
|
|
146
|
+
header: readonly string[],
|
|
147
|
+
records: Iterable<readonly unknown[]>,
|
|
148
|
+
): string {
|
|
149
|
+
let text = csvRecord(header);
|
|
150
|
+
for (const record of records) text += csvRecord(record);
|
|
151
|
+
return text;
|
|
152
|
+
}
|