deepline 0.3.233 → 0.3.234

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.
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
200
200
  // getters keep their established compatibility behavior.
201
201
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
202
202
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
203
- version: '0.3.233',
203
+ version: '0.3.234',
204
204
  updateSummary:
205
205
  'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
206
206
  packageCapabilities: {
@@ -245,8 +245,74 @@ export const RuntimeSheetColumns = {
245
245
  // jsonb_populate_record maps JSON null to SQL NULL. A legacy JSONB cell
246
246
  // must retain explicit JSON null, distinct from an omitted/SQL NULL cell.
247
247
  if (type === 'jsonb') return jsonExpression;
248
- // Resolve the actual row type inside PostgreSQL, never from a cached
249
- // contract. This also preserves JSON scalar strings for legacy JSONB.
248
+ // These types come from the locked, live catalog. Extract scalar text
249
+ // before casting so JSON null becomes SQL NULL and strings stay unquoted.
250
+ if (type === 'boolean' || type === 'double precision' || type === 'text')
251
+ return `((${jsonExpression}) #>> '{}')::${type}`;
252
+ // Preserve PostgreSQL's conversion rules for other pre-existing SQL types.
250
253
  return `(jsonb_populate_record(NULL::${tableReference}, jsonb_build_object(${literal(columnName)}, ${jsonExpression}))).${identifier(columnName)}`;
251
254
  },
255
+
256
+ /** Convert native cells once per input row; retain raw JSONB cell semantics. */
257
+ jsonRowSql(input: {
258
+ jsonExpression: string;
259
+ tableReference: string;
260
+ columns: readonly PhysicalSheetColumnProjection[];
261
+ types: RuntimeSheetColumnTypes;
262
+ alias?: string;
263
+ // Guard conversion itself when an existing row makes incoming cells inert.
264
+ when?: string;
265
+ }): { joinSql: string; valueSql: (columnName: string) => string } {
266
+ const alias = identifier(input.alias ?? '_typed_cells');
267
+ const columns = new Map(
268
+ input.columns.map((column) => [column.sqlName, column]),
269
+ );
270
+ const native = input.columns.filter((column) => {
271
+ const type = input.types.get(column.sqlName);
272
+ if (!type)
273
+ throw new Error(`Runtime Sheet column is missing: ${column.sqlName}`);
274
+ return (
275
+ type === 'boolean' || type === 'double precision' || type === 'text'
276
+ );
277
+ });
278
+ const nativeNames = new Set(native.map((column) => column.sqlName));
279
+ // Unmapped keys are ignored by jsonb_to_record. Remap only renamed fields,
280
+ // overriding any unrelated payload key that happens to use the SQL name.
281
+ const renamed = native.filter(
282
+ (column) => column.sqlName !== column.fieldName,
283
+ );
284
+ let payload = `(${input.jsonExpression})`;
285
+ // jsonb_build_object accepts at most 100 arguments (50 key/value pairs).
286
+ for (let offset = 0; offset < renamed.length; offset += 50) {
287
+ payload += ` || jsonb_build_object(${renamed
288
+ .slice(offset, offset + 50)
289
+ .map(
290
+ (column) =>
291
+ `${literal(column.sqlName)}, (${input.jsonExpression}) -> ${literal(column.fieldName)}`,
292
+ )
293
+ .join(', ')})`;
294
+ }
295
+ if (input.when)
296
+ payload = `CASE WHEN ${input.when} THEN ${payload} ELSE NULL::jsonb END`;
297
+ const joinSql =
298
+ native.length === 0
299
+ ? ''
300
+ : `CROSS JOIN LATERAL jsonb_to_record(${payload}) AS ${alias}(${native.map((column) => `${identifier(column.sqlName)} ${input.types.get(column.sqlName)}`).join(', ')})`;
301
+ return {
302
+ joinSql,
303
+ valueSql(columnName: string): string {
304
+ const column = columns.get(columnName);
305
+ if (!column)
306
+ throw new Error(`Runtime Sheet column is missing: ${columnName}`);
307
+ if (nativeNames.has(columnName))
308
+ return `${alias}.${identifier(columnName)}`;
309
+ return RuntimeSheetColumns.jsonValueSql(
310
+ `(${input.jsonExpression}) -> ${literal(column.fieldName)}`,
311
+ input.tableReference,
312
+ columnName,
313
+ input.types,
314
+ );
315
+ },
316
+ };
317
+ },
252
318
  };
@@ -3406,16 +3406,20 @@ async function writeRuntimeRows(
3406
3406
  .map((entry) => entry.row);
3407
3407
  },
3408
3408
  });
3409
+ const incomingRow = RuntimeSheetColumns.jsonRowSql({
3410
+ jsonExpression: 'input_rows.payload',
3411
+ tableReference: sheetTable(session),
3412
+ columns: physicalColumnProjections,
3413
+ types: columnTypes,
3414
+ ...(input.mode === 'upsert'
3415
+ ? { when: 'existing_input._key IS NULL' }
3416
+ : {}),
3417
+ });
3409
3418
  const physicalInsertValuesSql =
3410
3419
  physicalColumns.length > 0
3411
3420
  ? `, ${physicalColumnProjections
3412
3421
  .map((column) => {
3413
- const incoming = RuntimeSheetColumns.jsonValueSql(
3414
- `input_rows.payload -> ${quoteLiteral(column.fieldName)}`,
3415
- sheetTable(session),
3416
- column.sqlName,
3417
- columnTypes,
3418
- );
3422
+ const incoming = incomingRow.valueSql(column.sqlName);
3419
3423
  return input.mode === 'upsert'
3420
3424
  ? `CASE WHEN existing_input._key IS NOT NULL THEN existing_input.${quoteIdentifier(column.sqlName)} ELSE ${incoming} END`
3421
3425
  : incoming;
@@ -3476,6 +3480,7 @@ async function writeRuntimeRows(
3476
3480
  SELECT input_rows._key, 'pending', $4::text, input_rows._input_index, now()${physicalInsertValuesSql}
3477
3481
  FROM input_rows
3478
3482
  LEFT JOIN ${sheetTable(session)} AS existing_input ON existing_input._key = input_rows._key
3483
+ ${incomingRow.joinSql}
3479
3484
  ON CONFLICT (_key) DO UPDATE SET
3480
3485
  _status = 'pending',
3481
3486
  _run_id = EXCLUDED._run_id,
@@ -3487,8 +3492,9 @@ async function writeRuntimeRows(
3487
3492
  ),`
3488
3493
  : `inserted_rows AS (
3489
3494
  INSERT INTO ${sheetTable(session)} (_key, _status, _run_id, _input_index, _created_at${physicalInsertColumnsSql})
3490
- SELECT _key, 'pending', $4::text, _input_index, now()${physicalInsertValuesSql}
3495
+ SELECT input_rows._key, 'pending', $4::text, input_rows._input_index, now()${physicalInsertValuesSql}
3491
3496
  FROM input_rows
3497
+ ${incomingRow.joinSql}
3492
3498
  RETURNING _key
3493
3499
  ),`;
3494
3500
 
@@ -3645,6 +3651,7 @@ async function prepareRuntimeSheetDatasetRows(
3645
3651
  writeVersion: number;
3646
3652
  physicalInsertColumnsSql: string;
3647
3653
  physicalInsertValuesSql: string;
3654
+ physicalInsertJoinSql: string;
3648
3655
  physicalRefreshSetSql: string;
3649
3656
  physicalUpsertSetSql: string;
3650
3657
  outputPhysicalColumns: PhysicalSheetColumnProjection[];
@@ -3803,6 +3810,7 @@ async function prepareRuntimeSheetDatasetRows(
3803
3810
  SELECT input_rows._key, 'pending', $4::text, input_rows._input_index, $7::text, $8::text, $9::timestamptz, $10::integer, $12::bigint, $4::text, now()${input.physicalInsertValuesSql}
3804
3811
  FROM input_rows
3805
3812
  LEFT JOIN ${sheetTable(session)} AS existing_input ON existing_input._key = input_rows._key
3813
+ ${input.physicalInsertJoinSql}
3806
3814
  ON CONFLICT (_key) DO UPDATE SET
3807
3815
  _status = 'pending',
3808
3816
  _run_id = EXCLUDED._run_id,
@@ -4097,6 +4105,7 @@ async function prepareNetNewRuntimeSheetDatasetRows(
4097
4105
  writeVersion: number;
4098
4106
  physicalInsertColumnsSql: string;
4099
4107
  physicalInsertValuesSql: string;
4108
+ physicalInsertJoinSql: string;
4100
4109
  },
4101
4110
  ): Promise<{
4102
4111
  inserted: number;
@@ -4152,6 +4161,7 @@ async function prepareNetNewRuntimeSheetDatasetRows(
4152
4161
  $7::timestamptz, $8::integer, $9::bigint, $4::text, now()${input.physicalInsertValuesSql}
4153
4162
  FROM input_rows
4154
4163
  LEFT JOIN ${sheetTable(session)} AS existing_input ON existing_input._key = input_rows._key
4164
+ ${input.physicalInsertJoinSql}
4155
4165
  ON CONFLICT (_key) DO NOTHING
4156
4166
  RETURNING _key
4157
4167
  ),
@@ -6772,16 +6782,23 @@ export async function startRuntimeSheetDataset(
6772
6782
  });
6773
6783
  },
6774
6784
  });
6785
+ const incomingRow = RuntimeSheetColumns.jsonRowSql({
6786
+ jsonExpression: 'input_rows.payload',
6787
+ tableReference: sheetTable(session),
6788
+ columns: physicalSheetColumnProjections(input.sheetContract).map(
6789
+ (column) => ({ ...column, fieldName: column.sqlName }),
6790
+ ),
6791
+ types: columnTypes,
6792
+ when:
6793
+ input.mode === 'net_new'
6794
+ ? 'existing_input._key IS NULL'
6795
+ : "existing_input._key IS NULL OR existing_input._status = 'stale'",
6796
+ });
6775
6797
  const physicalInsertValuesSql =
6776
6798
  physicalColumns.length > 0
6777
6799
  ? `, ${physicalColumns
6778
6800
  .map((column) => {
6779
- const incoming = RuntimeSheetColumns.jsonValueSql(
6780
- `input_rows.payload -> ${quoteLiteral(column)}`,
6781
- sheetTable(session),
6782
- column,
6783
- columnTypes,
6784
- );
6801
+ const incoming = incomingRow.valueSql(column);
6785
6802
  const preserveExisting =
6786
6803
  input.mode === 'net_new'
6787
6804
  ? 'existing_input._key IS NOT NULL'
@@ -6817,6 +6834,7 @@ export async function startRuntimeSheetDataset(
6817
6834
  writeVersion,
6818
6835
  physicalInsertColumnsSql,
6819
6836
  physicalInsertValuesSql,
6837
+ physicalInsertJoinSql: incomingRow.joinSql,
6820
6838
  })
6821
6839
  : await prepareRuntimeSheetDatasetRows(client, session, {
6822
6840
  chunks,
@@ -6830,6 +6848,7 @@ export async function startRuntimeSheetDataset(
6830
6848
  writeVersion,
6831
6849
  physicalInsertColumnsSql,
6832
6850
  physicalInsertValuesSql,
6851
+ physicalInsertJoinSql: incomingRow.joinSql,
6833
6852
  physicalRefreshSetSql:
6834
6853
  input.force === true ? physicalRefreshSetSql : '',
6835
6854
  physicalUpsertSetSql,
@@ -8095,17 +8114,16 @@ async function insertMissingCompletedMapRowChunks(
8095
8114
  return accepted.rows.map((row) => row.data_patch);
8096
8115
  },
8097
8116
  });
8117
+ const incomingRow = RuntimeSheetColumns.jsonRowSql({
8118
+ jsonExpression: 'missing_rows.data_patch',
8119
+ tableReference: sheetTable(session),
8120
+ columns: input.physicalColumnProjections,
8121
+ types: columnTypes,
8122
+ });
8098
8123
  const physicalInsertValuesSql =
8099
8124
  input.physicalColumnProjections.length > 0
8100
8125
  ? `, ${input.physicalColumnProjections
8101
- .map((column) =>
8102
- RuntimeSheetColumns.jsonValueSql(
8103
- `missing_rows.data_patch -> ${quoteLiteral(column.fieldName)}`,
8104
- sheetTable(session),
8105
- column.sqlName,
8106
- columnTypes,
8107
- ),
8108
- )
8126
+ .map((column) => incomingRow.valueSql(column.sqlName))
8109
8127
  .join(', ')}`
8110
8128
  : '';
8111
8129
 
@@ -8123,7 +8141,9 @@ async function insertMissingCompletedMapRowChunks(
8123
8141
  JOIN unnest($4::jsonb[]) WITH ORDINALITY AS cell_meta_values(cell_meta_patch, ord)
8124
8142
  ON cell_meta_values.ord = key_values.ord
8125
8143
  ),
8126
- missing_rows AS (
8144
+ -- Decode only accepted rows: a rejected replay may contain values
8145
+ -- incompatible with the stored native types.
8146
+ missing_rows AS MATERIALIZED (
8127
8147
  SELECT input_rows.*
8128
8148
  FROM input_rows
8129
8149
  WHERE NOT EXISTS (
@@ -8150,17 +8170,18 @@ async function insertMissingCompletedMapRowChunks(
8150
8170
  _created_at,
8151
8171
  _cell_meta${physicalInsertColumnsSql}
8152
8172
  )
8153
- SELECT _key,
8173
+ SELECT missing_rows._key,
8154
8174
  'enriched',
8155
8175
  $5::text,
8156
- input_index,
8176
+ missing_rows.input_index,
8157
8177
  $8::text,
8158
8178
  $9::text,
8159
8179
  $10::timestamptz,
8160
8180
  $11::integer,
8161
8181
  now(),
8162
- cell_meta_patch${physicalInsertValuesSql}
8182
+ missing_rows.cell_meta_patch${physicalInsertValuesSql}
8163
8183
  FROM missing_rows
8184
+ ${incomingRow.joinSql}
8164
8185
  ON CONFLICT (_key) DO NOTHING
8165
8186
  RETURNING _key
8166
8187
  ),
package/dist/cli/index.js CHANGED
@@ -3454,7 +3454,7 @@ var SDK_RELEASE = {
3454
3454
  // getters keep their established compatibility behavior.
3455
3455
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3456
3456
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3457
- version: "0.3.233",
3457
+ version: "0.3.234",
3458
3458
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3459
3459
  packageCapabilities: {
3460
3460
  updatePreferences: 1
@@ -3449,7 +3449,7 @@ var SDK_RELEASE = {
3449
3449
  // getters keep their established compatibility behavior.
3450
3450
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3451
3451
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3452
- version: "0.3.233",
3452
+ version: "0.3.234",
3453
3453
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3454
3454
  packageCapabilities: {
3455
3455
  updatePreferences: 1
package/dist/index.js CHANGED
@@ -1267,7 +1267,7 @@ var SDK_RELEASE = {
1267
1267
  // getters keep their established compatibility behavior.
1268
1268
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1269
1269
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1270
- version: "0.3.233",
1270
+ version: "0.3.234",
1271
1271
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
1272
1272
  packageCapabilities: {
1273
1273
  updatePreferences: 1
package/dist/index.mjs CHANGED
@@ -1171,7 +1171,7 @@ var SDK_RELEASE = {
1171
1171
  // getters keep their established compatibility behavior.
1172
1172
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
1173
1173
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
1174
- version: "0.3.233",
1174
+ version: "0.3.234",
1175
1175
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
1176
1176
  packageCapabilities: {
1177
1177
  updatePreferences: 1
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.233";
152
+ readonly version: "0.3.234";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.d.ts CHANGED
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.233";
152
+ readonly version: "0.3.234";
153
153
  readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
154
154
  readonly packageCapabilities: {
155
155
  readonly updatePreferences: 1;
package/dist/release.js CHANGED
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
74
74
  // getters keep their established compatibility behavior.
75
75
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
76
76
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
77
- version: "0.3.233",
77
+ version: "0.3.234",
78
78
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
79
79
  packageCapabilities: {
80
80
  updatePreferences: 1
package/dist/release.mjs CHANGED
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
48
48
  // getters keep their established compatibility behavior.
49
49
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
50
50
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
51
- version: "0.3.233",
51
+ version: "0.3.234",
52
52
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
53
53
  packageCapabilities: {
54
54
  updatePreferences: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.233",
3
+ "version": "0.3.234",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",