@8ms/helpers 3.2.6 → 3.2.8

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.
Files changed (106) hide show
  1. package/AGENTS.md +20 -0
  2. package/dist/aws/s3/{server → _shared}/awsS3File.cjs +1 -1
  3. package/dist/aws/s3/{server → _shared}/awsS3File.d.cts +1 -1
  4. package/dist/aws/s3/{server → _shared}/awsS3File.d.mts +1 -1
  5. package/dist/aws/s3/{server → _shared}/awsS3File.mjs +1 -1
  6. package/dist/aws/s3/_shared/index.cjs +3 -0
  7. package/dist/aws/s3/_shared/index.d.cts +3 -0
  8. package/dist/aws/s3/_shared/index.d.mts +3 -0
  9. package/dist/aws/s3/_shared/index.mjs +2 -0
  10. package/dist/aws/s3/_shared/types.cjs +0 -0
  11. package/dist/aws/s3/_shared/types.d.cts +35 -0
  12. package/dist/aws/s3/_shared/types.d.mts +35 -0
  13. package/dist/aws/s3/_shared/types.mjs +1 -0
  14. package/dist/aws/s3/server/AwsS3.cjs +83 -4
  15. package/dist/aws/s3/server/AwsS3.d.cts +19 -26
  16. package/dist/aws/s3/server/AwsS3.d.mts +19 -26
  17. package/dist/aws/s3/server/AwsS3.mjs +81 -2
  18. package/dist/aws/s3/server/index.cjs +3 -2
  19. package/dist/aws/s3/server/index.d.cts +4 -3
  20. package/dist/aws/s3/server/index.d.mts +4 -3
  21. package/dist/aws/s3/server/index.mjs +2 -1
  22. package/dist/file/_shared/dataFileType.cjs +2 -0
  23. package/dist/file/_shared/dataFileType.d.cts +2 -0
  24. package/dist/file/_shared/dataFileType.d.mts +2 -0
  25. package/dist/file/_shared/dataFileType.mjs +2 -0
  26. package/dist/file/_shared/fileMimeType.cjs +2 -0
  27. package/dist/file/_shared/fileMimeType.mjs +2 -0
  28. package/dist/file/_shared/fileType.d.cts +2 -0
  29. package/dist/file/_shared/fileType.d.mts +2 -0
  30. package/dist/googleCloud/bigquery/_shared/index.d.cts +2 -2
  31. package/dist/googleCloud/bigquery/_shared/index.d.mts +2 -2
  32. package/dist/googleCloud/bigquery/_shared/types.d.cts +54 -0
  33. package/dist/googleCloud/bigquery/_shared/types.d.mts +54 -0
  34. package/dist/googleCloud/bigquery/client/index.d.cts +2 -2
  35. package/dist/googleCloud/bigquery/client/index.d.mts +2 -2
  36. package/dist/googleCloud/bigquery/server/GoogleCloudBigquery.cjs +158 -7
  37. package/dist/googleCloud/bigquery/server/GoogleCloudBigquery.d.cts +47 -31
  38. package/dist/googleCloud/bigquery/server/GoogleCloudBigquery.d.mts +47 -31
  39. package/dist/googleCloud/bigquery/server/GoogleCloudBigquery.mjs +158 -7
  40. package/dist/googleCloud/bigquery/server/index.d.cts +3 -3
  41. package/dist/googleCloud/bigquery/server/index.d.mts +3 -3
  42. package/dist/googleCloud/drive/server/GoogleCloudDrive.cjs +85 -0
  43. package/dist/googleCloud/drive/server/GoogleCloudDrive.d.cts +34 -0
  44. package/dist/googleCloud/drive/server/GoogleCloudDrive.d.mts +34 -0
  45. package/dist/googleCloud/drive/server/GoogleCloudDrive.mjs +85 -0
  46. package/dist/stream/server/index.cjs +11 -0
  47. package/dist/stream/server/index.d.cts +4 -1
  48. package/dist/stream/server/index.d.mts +4 -1
  49. package/dist/stream/server/index.mjs +4 -1
  50. package/dist/stream/server/json/logic.cjs +18 -0
  51. package/dist/stream/server/json/logic.d.cts +27 -0
  52. package/dist/stream/server/json/logic.d.mts +27 -0
  53. package/dist/stream/server/json/logic.mjs +16 -0
  54. package/dist/stream/server/json/read.cjs +46 -0
  55. package/dist/stream/server/json/read.d.cts +7 -0
  56. package/dist/stream/server/json/read.d.mts +7 -0
  57. package/dist/stream/server/json/read.mjs +42 -0
  58. package/dist/stream/server/json/write.cjs +69 -0
  59. package/dist/stream/server/json/write.d.cts +14 -0
  60. package/dist/stream/server/json/write.d.mts +14 -0
  61. package/dist/stream/server/json/write.mjs +63 -0
  62. package/dist/stream/server/sort.cjs +12 -23
  63. package/dist/stream/server/sort.d.cts +10 -6
  64. package/dist/stream/server/sort.d.mts +10 -6
  65. package/dist/stream/server/sort.mjs +12 -23
  66. package/dist/xlsx/_shared/createXlsx.cjs +12 -22
  67. package/dist/xlsx/_shared/createXlsx.mjs +12 -22
  68. package/dist/xlsx/_shared/modifyXlsx.cjs +32 -44
  69. package/dist/xlsx/_shared/modifyXlsx.mjs +32 -44
  70. package/dist/xlsx/client/index.cjs +0 -1
  71. package/dist/xlsx/client/index.mjs +0 -1
  72. package/dist/xlsx/server/index.cjs +0 -1
  73. package/dist/xlsx/server/index.mjs +0 -1
  74. package/dist/zip/_shared/ZipArchive.cjs +49 -0
  75. package/dist/zip/_shared/ZipArchive.d.cts +24 -0
  76. package/dist/zip/_shared/ZipArchive.d.mts +24 -0
  77. package/dist/zip/_shared/ZipArchive.mjs +48 -0
  78. package/dist/zip/_shared/crc32.cjs +24 -0
  79. package/dist/zip/_shared/crc32.d.cts +4 -0
  80. package/dist/zip/_shared/crc32.d.mts +4 -0
  81. package/dist/zip/_shared/crc32.mjs +23 -0
  82. package/dist/zip/_shared/deflate.cjs +21 -0
  83. package/dist/zip/_shared/deflate.d.cts +10 -0
  84. package/dist/zip/_shared/deflate.d.mts +10 -0
  85. package/dist/zip/_shared/deflate.mjs +19 -0
  86. package/dist/zip/_shared/index.cjs +12 -0
  87. package/dist/zip/_shared/index.d.cts +6 -0
  88. package/dist/zip/_shared/index.d.mts +6 -0
  89. package/dist/zip/_shared/index.mjs +6 -0
  90. package/dist/zip/_shared/readZip.cjs +63 -0
  91. package/dist/zip/_shared/readZip.d.cts +9 -0
  92. package/dist/zip/_shared/readZip.d.mts +9 -0
  93. package/dist/zip/_shared/readZip.mjs +62 -0
  94. package/dist/zip/_shared/writeZip.cjs +105 -0
  95. package/dist/zip/_shared/writeZip.d.cts +7 -0
  96. package/dist/zip/_shared/writeZip.d.mts +7 -0
  97. package/dist/zip/_shared/writeZip.mjs +104 -0
  98. package/dist/zip/client/index.cjs +12 -0
  99. package/dist/zip/client/index.d.cts +6 -0
  100. package/dist/zip/client/index.d.mts +6 -0
  101. package/dist/zip/client/index.mjs +6 -0
  102. package/dist/zip/server/index.cjs +12 -0
  103. package/dist/zip/server/index.d.cts +6 -0
  104. package/dist/zip/server/index.d.mts +6 -0
  105. package/dist/zip/server/index.mjs +6 -0
  106. package/package.json +65 -10
@@ -1,6 +1,22 @@
1
1
  import { isObject } from "../../../lodash/_shared/isObject.mjs";
2
2
  import { BaseNamespace } from "../../../_class/_shared/BaseNamespace.mjs";
3
+ import { getYmdHisNumber } from "../../../date/_shared/format.mjs";
4
+ import "../../../date/_shared/index.mjs";
5
+ import { fileType } from "../../../file/_shared/fileType.mjs";
6
+ import { fileMimeType } from "../../../file/_shared/fileMimeType.mjs";
7
+ import "../../../file/_shared/index.mjs";
8
+ import { getJsonNewline } from "../../../json/_shared/getJsonNewline.mjs";
9
+ import { toRowReadable } from "../../../stream/server/json/logic.mjs";
10
+ import { jsonNewLineStringifier } from "../../../stream/server/json/write.mjs";
11
+ import "../../../stream/server/index.mjs";
12
+ import { pipeline } from "node:stream/promises";
3
13
  //#region src/googleCloud/bigquery/server/GoogleCloudBigquery.ts
14
+ /** Maps this library's generic file-type catalog onto BigQuery's own load-job sourceFormat strings. */
15
+ const bigQuerySourceFormat = {
16
+ [fileType.CSV]: "CSV",
17
+ [fileType.JSON_NEWLINE]: "NEWLINE_DELIMITED_JSON",
18
+ [fileType.PARQUET]: "PARQUET"
19
+ };
4
20
  var GoogleCloudBigquery = class extends BaseNamespace {
5
21
  /**
6
22
  * Either a Google Cloud JSON Config or V10 Auth helper.
@@ -64,7 +80,7 @@ var GoogleCloudBigquery = class extends BaseNamespace {
64
80
  });
65
81
  return response;
66
82
  };
67
- query = async (props) => {
83
+ buildQueryOptions = (props) => {
68
84
  let options = { query: "" };
69
85
  if ("string" === typeof props) {
70
86
  options.query = props;
@@ -75,7 +91,19 @@ var GoogleCloudBigquery = class extends BaseNamespace {
75
91
  if (resolvedLocation) options.location = resolvedLocation;
76
92
  if (props?.params) options["params"] = props.params;
77
93
  }
78
- return await this.client.query(options);
94
+ return options;
95
+ };
96
+ /**
97
+ * Make a request to the database and return the object per row.
98
+ */
99
+ query = async (props) => {
100
+ return await this.client.query(this.buildQueryOptions(props));
101
+ };
102
+ /**
103
+ * Return the raw row stream for a query, without buffering the full result set in memory.
104
+ */
105
+ queryStream = (props) => {
106
+ return this.client.createQueryStream(this.buildQueryOptions(props));
79
107
  };
80
108
  /**
81
109
  * Create a Table if it doesn't already exist.
@@ -112,14 +140,137 @@ var GoogleCloudBigquery = class extends BaseNamespace {
112
140
  return true;
113
141
  };
114
142
  /**
115
- * Load data into this table using Google Cloud Storage.
143
+ * Load a Google Cloud Storage file into a table. BigQuery load jobs default to
144
+ * createDisposition "CREATE_IF_NEEDED"; paired with autodetect, this creates the table itself
145
+ * from the source file's inferred schema if it doesn't already exist, rather than this library
146
+ * pre-checking existence and silently skipping the load if it isn't there.
116
147
  */
117
- loadData = async ({ file, googleCloudStorageClient, table }) => {
118
- if (await this.tableExists(table.datasetId, table.tableId)) await this.client.dataset(table.datasetId, { location: table?.region }).table(table.tableId).load(googleCloudStorageClient.client.bucket(file.bucket).file(file.key), {
119
- ...file?.metadata ?? {},
120
- location: file?.region
148
+ loadData = async (props) => {
149
+ const finalTableId = props.table.tableId;
150
+ await this.createTable(props.table.datasetId, {}, finalTableId, props.table.options);
151
+ await this.client.dataset(props.table.datasetId, { location: props.table.region }).table(finalTableId).load(props.googleCloudStorage.client.bucket(props.file.bucket).file(props.file.key), {
152
+ autodetect: true,
153
+ sourceFormat: bigQuerySourceFormat[props.file.sourceFormat ?? fileType.JSON_NEWLINE],
154
+ schemaUpdateOptions: ["ALLOW_FIELD_ADDITION"],
155
+ location: props.table.region
121
156
  });
122
157
  };
158
+ /**
159
+ * Write rows to Google Cloud Storage, then load them into the table - creating the table first
160
+ * if it doesn't already exist. Only JSON_NEWLINE (the default) is actually serialised by this
161
+ * library (getJsonNewline); for PARQUET, `data` is written as-is and must already be encoded -
162
+ * this library has no Parquet encoder.
163
+ */
164
+ loadTable = async (props) => {
165
+ const finalTableId = props.table.tableId ?? props.table.definition.tableId;
166
+ const fileSourceFormat = props.file.sourceFormat ?? fileType.JSON_NEWLINE;
167
+ const finalData = fileType.JSON_NEWLINE === fileSourceFormat ? getJsonNewline(props.file.data) : props.file.data;
168
+ await props.googleCloudStorage.writeFile(props.file.bucket, props.file.key, finalData);
169
+ await this.loadData({
170
+ ...props,
171
+ table: {
172
+ ...props.table,
173
+ tableId: finalTableId
174
+ }
175
+ });
176
+ };
177
+ /**
178
+ * Same as loadTable, but streams a row source into Google Cloud Storage instead of buffering the
179
+ * full collection in memory first. Writes directly against the Storage client's own write stream
180
+ * (GoogleCloudStorage.writeFile can't stream a Readable source) - creates the table first if it
181
+ * doesn't already exist. For JSON_NEWLINE (the default) `source` is a stream of row objects,
182
+ * stringified one at a time; for PARQUET there is no stringify stage - `source` must already be a
183
+ * byte-level Readable of encoded Parquet content, piped straight through.
184
+ */
185
+ loadStreamTable = async (props) => {
186
+ const finalTableId = props.table.tableId ?? props.table.definition.tableId;
187
+ const fileSourceFormat = props.file.sourceFormat ?? fileType.JSON_NEWLINE;
188
+ const destination = props.googleCloudStorage.client.bucket(props.file.bucket).file(props.file.key).createWriteStream({
189
+ contentType: fileMimeType[fileSourceFormat],
190
+ resumable: false
191
+ });
192
+ const source = toRowReadable(props.file.data);
193
+ if (fileType.JSON_NEWLINE === fileSourceFormat) await pipeline([
194
+ source,
195
+ jsonNewLineStringifier(),
196
+ destination
197
+ ]);
198
+ else await pipeline([source, destination]);
199
+ await this.loadData({
200
+ ...props,
201
+ table: {
202
+ ...props.table,
203
+ tableId: finalTableId
204
+ }
205
+ });
206
+ };
207
+ /**
208
+ * Brings an existing table's clustering in line with `definition.options.clustering`, if it differs.
209
+ * Partitioning is immutable on an existing BigQuery table - changing it requires recreating the
210
+ * table and backfilling data, which this method deliberately does not attempt.
211
+ */
212
+ syncTableClustering = async (datasetId, tableId, clustering) => {
213
+ const [metadata] = await this.client.dataset(datasetId).table(tableId).getMetadata();
214
+ const currentFields = metadata?.clustering?.fields ?? [];
215
+ const desiredFields = clustering?.fields ?? [];
216
+ if (currentFields.length === desiredFields.length && currentFields.every((field, index) => field === desiredFields[index])) return;
217
+ await this.client.dataset(datasetId).table(tableId).setMetadata(desiredFields.length > 0 ? { clustering: { fields: desiredFields } } : { clustering: void 0 });
218
+ };
219
+ /**
220
+ * Upsert rows into a table via a staging table + a single MERGE statement.
221
+ *
222
+ * BigQuery has no efficient row-level UPDATE/DELETE - both rewrite the affected partitions and
223
+ * are subject to daily DML mutation quotas. Loading new rows into a disposable staging table and
224
+ * running one MERGE is the standard, quota-friendly way to upsert in BigQuery.
225
+ */
226
+ mergeTable = async (props) => {
227
+ if (0 === props.file.data.length) return;
228
+ const finalTableId = props.table.tableId ?? props.table.definition.tableId;
229
+ if (await this.tableExists(props.table.datasetId, finalTableId)) await this.syncTableClustering(props.table.datasetId, finalTableId, props.table.definition.options?.clustering);
230
+ const stagingTableId = `${finalTableId}_staging_${getYmdHisNumber()}`;
231
+ const stagingTableRef = `\`${props.table.datasetId}.${stagingTableId}\``;
232
+ try {
233
+ const stagingDefinition = {
234
+ ...props.table.definition,
235
+ tableId: stagingTableId,
236
+ options: props.table.definition.options ? {
237
+ ...props.table.definition.options,
238
+ timePartitioning: void 0,
239
+ clustering: void 0
240
+ } : void 0
241
+ };
242
+ await this.loadTable({
243
+ googleCloudStorage: props.googleCloudStorage,
244
+ file: props.file,
245
+ table: {
246
+ datasetId: props.table.datasetId,
247
+ definition: stagingDefinition,
248
+ tableId: stagingTableId,
249
+ region: props.table.region
250
+ }
251
+ });
252
+ const mainTableRef = `\`${props.table.datasetId}.${finalTableId}\``;
253
+ const updateSet = props.table.updateColumns.map((column) => `${column} = S.${column}`).join(", ");
254
+ const allColumns = props.table.definition.options?.schema.map((field) => field.name) ?? [];
255
+ const mergeQuery = `
256
+ MERGE ${mainTableRef} AS T
257
+ USING ${stagingTableRef} AS S
258
+ ON T.${props.table.mergeKey} = S.${props.table.mergeKey}
259
+ WHEN MATCHED THEN
260
+ UPDATE SET ${updateSet}
261
+ WHEN NOT MATCHED THEN
262
+ INSERT (${allColumns.join(", ")})
263
+ VALUES (${allColumns.map((column) => `S.${column}`).join(", ")})
264
+ `;
265
+ await this.query(mergeQuery);
266
+ } finally {
267
+ try {
268
+ await this.query(`DROP TABLE IF EXISTS ${stagingTableRef}`);
269
+ } catch (error) {
270
+ console.error(`mergeTable: failed to drop staging table ${stagingTableRef} - it must be dropped manually.`, error);
271
+ }
272
+ }
273
+ };
123
274
  };
124
275
  //#endregion
125
276
  export { GoogleCloudBigquery };
@@ -17,8 +17,8 @@ import { GoogleCloudBQRow, googleCloudBQRow } from "../_shared/lookup/googleClou
17
17
  import { LanguageBQRow, languageBQRow } from "../_shared/lookup/language.cjs";
18
18
  import { PartitionType, partitionType } from "../_shared/partitionType.cjs";
19
19
  import { BQField, zodToBQSchema } from "../_shared/zodToBQDefinition.cjs";
20
- import { TableDefinition } from "../_shared/types.cjs";
20
+ import { BigqueryLoadFormat, Dataset, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, QueryInput, Table, TableDefinition } from "../_shared/types.cjs";
21
21
  import "../_shared/index.cjs";
22
- import { GoogleCloudBigquery, QueryInput } from "./GoogleCloudBigquery.cjs";
22
+ import { GoogleCloudBigquery } from "./GoogleCloudBigquery.cjs";
23
23
  import { getHandlerPath } from "./getHandlerPath.cjs";
24
- export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, CountryBQRow, GoogleAdsAccountBQRow, GoogleCloudBQRow, GoogleCloudBigquery, LanguageBQRow, PartitionType, QueryInput, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, getHandlerPath, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
24
+ export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, BigqueryLoadFormat, CountryBQRow, Dataset, GoogleAdsAccountBQRow, GoogleCloudBQRow, GoogleCloudBigquery, LanguageBQRow, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, PartitionType, QueryInput, Table, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, getHandlerPath, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
@@ -17,8 +17,8 @@ import { GoogleCloudBQRow, googleCloudBQRow } from "../_shared/lookup/googleClou
17
17
  import { LanguageBQRow, languageBQRow } from "../_shared/lookup/language.mjs";
18
18
  import { PartitionType, partitionType } from "../_shared/partitionType.mjs";
19
19
  import { BQField, zodToBQSchema } from "../_shared/zodToBQDefinition.mjs";
20
- import { TableDefinition } from "../_shared/types.mjs";
20
+ import { BigqueryLoadFormat, Dataset, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, QueryInput, Table, TableDefinition } from "../_shared/types.mjs";
21
21
  import "../_shared/index.mjs";
22
- import { GoogleCloudBigquery, QueryInput } from "./GoogleCloudBigquery.mjs";
22
+ import { GoogleCloudBigquery } from "./GoogleCloudBigquery.mjs";
23
23
  import { getHandlerPath } from "./getHandlerPath.mjs";
24
- export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, CountryBQRow, GoogleAdsAccountBQRow, GoogleCloudBQRow, GoogleCloudBigquery, LanguageBQRow, PartitionType, QueryInput, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, getHandlerPath, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
24
+ export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, BigqueryLoadFormat, CountryBQRow, Dataset, GoogleAdsAccountBQRow, GoogleCloudBQRow, GoogleCloudBigquery, LanguageBQRow, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, PartitionType, QueryInput, Table, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, getHandlerPath, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
@@ -1,8 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require__class__shared_BaseNamespace = require("../../../_class/_shared/BaseNamespace.cjs");
3
+ const require_stream_server_json_read = require("../../../stream/server/json/read.cjs");
4
+ const require_stream_server_json_write = require("../../../stream/server/json/write.cjs");
5
+ require("../../../stream/server/index.cjs");
3
6
  const require_util_server_getGzipDecompressed = require("../../../util/server/getGzipDecompressed.cjs");
4
7
  const require_util_server_getGzipCompressed = require("../../../util/server/getGzipCompressed.cjs");
5
8
  require("../../../util/server/index.cjs");
9
+ let stream = require("stream");
6
10
  //#region src/googleCloud/drive/server/GoogleCloudDrive.ts
7
11
  var GoogleCloudDrive = class extends require__class__shared_BaseNamespace.BaseNamespace {
8
12
  /**
@@ -172,6 +176,57 @@ var GoogleCloudDrive = class extends require__class__shared_BaseNamespace.BaseNa
172
176
  return await this.writeFile(parentFolderId, fileName, finalData, driveOptions);
173
177
  };
174
178
  /**
179
+ * Write a row source (stream, array, or async iterable) as a JSON array to Drive,
180
+ * without buffering the full payload in memory. `media.body` being a stream makes
181
+ * @googleapis/drive perform a resumable upload automatically.
182
+ */
183
+ writeJsonStream = async (parentFolderId, fileName, source, options = {}) => {
184
+ const googleApisDrive = await import("@googleapis/drive");
185
+ const destination = new stream.PassThrough();
186
+ const createPromise = googleApisDrive.drive("v3").files.create({
187
+ auth: this.client,
188
+ fields: "id, name",
189
+ media: {
190
+ body: destination,
191
+ mimeType: options.driveOptions?.mimeType ?? "application/json"
192
+ },
193
+ requestBody: {
194
+ name: fileName,
195
+ parents: [parentFolderId]
196
+ }
197
+ });
198
+ const [, createResponse] = await Promise.all([require_stream_server_json_write.writeJsonStream({
199
+ source,
200
+ destination,
201
+ rowCallback: options.rowCallback,
202
+ sortCallback: options.sortCallback
203
+ }), createPromise]);
204
+ return createResponse.data;
205
+ };
206
+ writeJsonGzipStream = async (parentFolderId, fileName, source, options = {}) => {
207
+ const googleApisDrive = await import("@googleapis/drive");
208
+ const destination = new stream.PassThrough();
209
+ const createPromise = googleApisDrive.drive("v3").files.create({
210
+ auth: this.client,
211
+ fields: "id, name",
212
+ media: {
213
+ body: destination,
214
+ mimeType: options.driveOptions?.mimeType ?? "application/gzip"
215
+ },
216
+ requestBody: {
217
+ name: fileName,
218
+ parents: [parentFolderId]
219
+ }
220
+ });
221
+ const [, createResponse] = await Promise.all([require_stream_server_json_write.writeJsonGzipStream({
222
+ source,
223
+ destination,
224
+ rowCallback: options.rowCallback,
225
+ sortCallback: options.sortCallback
226
+ }), createPromise]);
227
+ return createResponse.data;
228
+ };
229
+ /**
175
230
  * Read a file's contents from Google Drive.
176
231
  */
177
232
  readFile = async (fileId, options = {}) => {
@@ -182,6 +237,36 @@ var GoogleCloudDrive = class extends require__class__shared_BaseNamespace.BaseNa
182
237
  ...options
183
238
  }, { responseType: "text" })).data };
184
239
  };
240
+ /**
241
+ * Return a file's contents as a stream, without buffering it into memory.
242
+ */
243
+ readStream = async (fileId, options = {}) => {
244
+ return (await (await import("@googleapis/drive")).drive("v3").files.get({
245
+ auth: this.client,
246
+ fileId,
247
+ alt: "media",
248
+ ...options
249
+ }, { responseType: "stream" })).data;
250
+ };
251
+ /**
252
+ * Read a JSON array file back, parsing it incrementally without buffering the full document.
253
+ */
254
+ readJsonStream = async (fileId, options = {}) => {
255
+ const source = await this.readStream(fileId, options.driveOptions);
256
+ return require_stream_server_json_read.readJsonStream({
257
+ source,
258
+ rowCallback: options.rowCallback,
259
+ sortCallback: options.sortCallback
260
+ });
261
+ };
262
+ readJsonGzipStream = async (fileId, options = {}) => {
263
+ const source = await this.readStream(fileId, options.driveOptions);
264
+ return require_stream_server_json_read.readJsonGzipStream({
265
+ source,
266
+ rowCallback: options.rowCallback,
267
+ sortCallback: options.sortCallback
268
+ });
269
+ };
185
270
  readJson = async (fileId) => {
186
271
  const apiResponse = await this.readFile(fileId);
187
272
  apiResponse.body = JSON.parse(apiResponse.body) || null;
@@ -1,4 +1,6 @@
1
1
  import { BaseNamespace } from "../../../_class/_shared/BaseNamespace.cjs";
2
+ import { RowCallback, RowSource, SortCallback } from "../../../stream/server/json/logic.cjs";
3
+ import { Readable } from "stream";
2
4
  //#region src/googleCloud/drive/server/GoogleCloudDrive.d.ts
3
5
  type Options = {
4
6
  [key: string]: any;
@@ -50,12 +52,44 @@ export declare class GoogleCloudDrive extends BaseNamespace {
50
52
  writeFile: (parentFolderId: string, fileName: string, data: any, options?: Options) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
51
53
  writeJson: (parentFolderId: string, fileName: string, data: any, options?: Options) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
52
54
  writeJsonGzip: (parentFolderId: string, fileName: string, data: any, gzipOptions?: object, driveOptions?: Options) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
55
+ /**
56
+ * Write a row source (stream, array, or async iterable) as a JSON array to Drive,
57
+ * without buffering the full payload in memory. `media.body` being a stream makes
58
+ * @googleapis/drive perform a resumable upload automatically.
59
+ */
60
+ writeJsonStream: <T = any>(parentFolderId: string, fileName: string, source: RowSource<T>, options?: {
61
+ rowCallback?: RowCallback<T>;
62
+ sortCallback?: SortCallback<T>;
63
+ driveOptions?: Options;
64
+ }) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
65
+ writeJsonGzipStream: <T = any>(parentFolderId: string, fileName: string, source: RowSource<T>, options?: {
66
+ rowCallback?: RowCallback<T>;
67
+ sortCallback?: SortCallback<T>;
68
+ driveOptions?: Options;
69
+ }) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
53
70
  /**
54
71
  * Read a file's contents from Google Drive.
55
72
  */
56
73
  readFile: (fileId: string, options?: Options) => Promise<{
57
74
  body: string;
58
75
  }>;
76
+ /**
77
+ * Return a file's contents as a stream, without buffering it into memory.
78
+ */
79
+ readStream: (fileId: string, options?: Options) => Promise<Readable>;
80
+ /**
81
+ * Read a JSON array file back, parsing it incrementally without buffering the full document.
82
+ */
83
+ readJsonStream: <T = any>(fileId: string, options?: {
84
+ rowCallback?: RowCallback<T>;
85
+ sortCallback?: SortCallback<T>;
86
+ driveOptions?: Options;
87
+ }) => Promise<T[]>;
88
+ readJsonGzipStream: <T = any>(fileId: string, options?: {
89
+ rowCallback?: RowCallback<T>;
90
+ sortCallback?: SortCallback<T>;
91
+ driveOptions?: Options;
92
+ }) => Promise<T[]>;
59
93
  readJson: (fileId: string) => Promise<{
60
94
  body: string;
61
95
  }>;
@@ -1,4 +1,6 @@
1
1
  import { BaseNamespace } from "../../../_class/_shared/BaseNamespace.mjs";
2
+ import { RowCallback, RowSource, SortCallback } from "../../../stream/server/json/logic.mjs";
3
+ import { Readable } from "stream";
2
4
  //#region src/googleCloud/drive/server/GoogleCloudDrive.d.ts
3
5
  type Options = {
4
6
  [key: string]: any;
@@ -50,12 +52,44 @@ export declare class GoogleCloudDrive extends BaseNamespace {
50
52
  writeFile: (parentFolderId: string, fileName: string, data: any, options?: Options) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
51
53
  writeJson: (parentFolderId: string, fileName: string, data: any, options?: Options) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
52
54
  writeJsonGzip: (parentFolderId: string, fileName: string, data: any, gzipOptions?: object, driveOptions?: Options) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
55
+ /**
56
+ * Write a row source (stream, array, or async iterable) as a JSON array to Drive,
57
+ * without buffering the full payload in memory. `media.body` being a stream makes
58
+ * @googleapis/drive perform a resumable upload automatically.
59
+ */
60
+ writeJsonStream: <T = any>(parentFolderId: string, fileName: string, source: RowSource<T>, options?: {
61
+ rowCallback?: RowCallback<T>;
62
+ sortCallback?: SortCallback<T>;
63
+ driveOptions?: Options;
64
+ }) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
65
+ writeJsonGzipStream: <T = any>(parentFolderId: string, fileName: string, source: RowSource<T>, options?: {
66
+ rowCallback?: RowCallback<T>;
67
+ sortCallback?: SortCallback<T>;
68
+ driveOptions?: Options;
69
+ }) => Promise<import("@googleapis/drive").drive_v3.Schema$File>;
53
70
  /**
54
71
  * Read a file's contents from Google Drive.
55
72
  */
56
73
  readFile: (fileId: string, options?: Options) => Promise<{
57
74
  body: string;
58
75
  }>;
76
+ /**
77
+ * Return a file's contents as a stream, without buffering it into memory.
78
+ */
79
+ readStream: (fileId: string, options?: Options) => Promise<Readable>;
80
+ /**
81
+ * Read a JSON array file back, parsing it incrementally without buffering the full document.
82
+ */
83
+ readJsonStream: <T = any>(fileId: string, options?: {
84
+ rowCallback?: RowCallback<T>;
85
+ sortCallback?: SortCallback<T>;
86
+ driveOptions?: Options;
87
+ }) => Promise<T[]>;
88
+ readJsonGzipStream: <T = any>(fileId: string, options?: {
89
+ rowCallback?: RowCallback<T>;
90
+ sortCallback?: SortCallback<T>;
91
+ driveOptions?: Options;
92
+ }) => Promise<T[]>;
59
93
  readJson: (fileId: string) => Promise<{
60
94
  body: string;
61
95
  }>;
@@ -1,7 +1,11 @@
1
1
  import { BaseNamespace } from "../../../_class/_shared/BaseNamespace.mjs";
2
+ import { readJsonGzipStream, readJsonStream } from "../../../stream/server/json/read.mjs";
3
+ import { writeJsonGzipStream, writeJsonStream } from "../../../stream/server/json/write.mjs";
4
+ import "../../../stream/server/index.mjs";
2
5
  import { getGzipDecompressed } from "../../../util/server/getGzipDecompressed.mjs";
3
6
  import { getGzipCompressed } from "../../../util/server/getGzipCompressed.mjs";
4
7
  import "../../../util/server/index.mjs";
8
+ import { PassThrough } from "stream";
5
9
  //#region src/googleCloud/drive/server/GoogleCloudDrive.ts
6
10
  var GoogleCloudDrive = class extends BaseNamespace {
7
11
  /**
@@ -171,6 +175,57 @@ var GoogleCloudDrive = class extends BaseNamespace {
171
175
  return await this.writeFile(parentFolderId, fileName, finalData, driveOptions);
172
176
  };
173
177
  /**
178
+ * Write a row source (stream, array, or async iterable) as a JSON array to Drive,
179
+ * without buffering the full payload in memory. `media.body` being a stream makes
180
+ * @googleapis/drive perform a resumable upload automatically.
181
+ */
182
+ writeJsonStream = async (parentFolderId, fileName, source, options = {}) => {
183
+ const googleApisDrive = await import("@googleapis/drive");
184
+ const destination = new PassThrough();
185
+ const createPromise = googleApisDrive.drive("v3").files.create({
186
+ auth: this.client,
187
+ fields: "id, name",
188
+ media: {
189
+ body: destination,
190
+ mimeType: options.driveOptions?.mimeType ?? "application/json"
191
+ },
192
+ requestBody: {
193
+ name: fileName,
194
+ parents: [parentFolderId]
195
+ }
196
+ });
197
+ const [, createResponse] = await Promise.all([writeJsonStream({
198
+ source,
199
+ destination,
200
+ rowCallback: options.rowCallback,
201
+ sortCallback: options.sortCallback
202
+ }), createPromise]);
203
+ return createResponse.data;
204
+ };
205
+ writeJsonGzipStream = async (parentFolderId, fileName, source, options = {}) => {
206
+ const googleApisDrive = await import("@googleapis/drive");
207
+ const destination = new PassThrough();
208
+ const createPromise = googleApisDrive.drive("v3").files.create({
209
+ auth: this.client,
210
+ fields: "id, name",
211
+ media: {
212
+ body: destination,
213
+ mimeType: options.driveOptions?.mimeType ?? "application/gzip"
214
+ },
215
+ requestBody: {
216
+ name: fileName,
217
+ parents: [parentFolderId]
218
+ }
219
+ });
220
+ const [, createResponse] = await Promise.all([writeJsonGzipStream({
221
+ source,
222
+ destination,
223
+ rowCallback: options.rowCallback,
224
+ sortCallback: options.sortCallback
225
+ }), createPromise]);
226
+ return createResponse.data;
227
+ };
228
+ /**
174
229
  * Read a file's contents from Google Drive.
175
230
  */
176
231
  readFile = async (fileId, options = {}) => {
@@ -181,6 +236,36 @@ var GoogleCloudDrive = class extends BaseNamespace {
181
236
  ...options
182
237
  }, { responseType: "text" })).data };
183
238
  };
239
+ /**
240
+ * Return a file's contents as a stream, without buffering it into memory.
241
+ */
242
+ readStream = async (fileId, options = {}) => {
243
+ return (await (await import("@googleapis/drive")).drive("v3").files.get({
244
+ auth: this.client,
245
+ fileId,
246
+ alt: "media",
247
+ ...options
248
+ }, { responseType: "stream" })).data;
249
+ };
250
+ /**
251
+ * Read a JSON array file back, parsing it incrementally without buffering the full document.
252
+ */
253
+ readJsonStream = async (fileId, options = {}) => {
254
+ const source = await this.readStream(fileId, options.driveOptions);
255
+ return readJsonStream({
256
+ source,
257
+ rowCallback: options.rowCallback,
258
+ sortCallback: options.sortCallback
259
+ });
260
+ };
261
+ readJsonGzipStream = async (fileId, options = {}) => {
262
+ const source = await this.readStream(fileId, options.driveOptions);
263
+ return readJsonGzipStream({
264
+ source,
265
+ rowCallback: options.rowCallback,
266
+ sortCallback: options.sortCallback
267
+ });
268
+ };
184
269
  readJson = async (fileId) => {
185
270
  const apiResponse = await this.readFile(fileId);
186
271
  apiResponse.body = JSON.parse(apiResponse.body) || null;
@@ -1,3 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_stream_server_sort = require("./sort.cjs");
3
+ const require_stream_server_json_logic = require("./json/logic.cjs");
4
+ const require_stream_server_json_read = require("./json/read.cjs");
5
+ const require_stream_server_json_write = require("./json/write.cjs");
6
+ exports.JsonNewLineStringifier = require_stream_server_json_write.JsonNewLineStringifier;
7
+ exports.jsonNewLineStringifier = require_stream_server_json_write.jsonNewLineStringifier;
8
+ exports.readJsonGzipStream = require_stream_server_json_read.readJsonGzipStream;
9
+ exports.readJsonStream = require_stream_server_json_read.readJsonStream;
10
+ exports.rowCallbackTransform = require_stream_server_json_logic.rowCallbackTransform;
3
11
  exports.sort = require_stream_server_sort.sort;
12
+ exports.toRowReadable = require_stream_server_json_logic.toRowReadable;
13
+ exports.writeJsonGzipStream = require_stream_server_json_write.writeJsonGzipStream;
14
+ exports.writeJsonStream = require_stream_server_json_write.writeJsonStream;
@@ -1,2 +1,5 @@
1
1
  import { sort } from "./sort.cjs";
2
- export { sort };
2
+ import { ReadJsonStreamProps, RowCallback, RowSource, SortCallback, WriteJsonStreamProps, rowCallbackTransform, toRowReadable } from "./json/logic.cjs";
3
+ import { readJsonGzipStream, readJsonStream } from "./json/read.cjs";
4
+ import { JsonNewLineStringifier, jsonNewLineStringifier, writeJsonGzipStream, writeJsonStream } from "./json/write.cjs";
5
+ export { JsonNewLineStringifier, ReadJsonStreamProps, RowCallback, RowSource, SortCallback, WriteJsonStreamProps, jsonNewLineStringifier, readJsonGzipStream, readJsonStream, rowCallbackTransform, sort, toRowReadable, writeJsonGzipStream, writeJsonStream };
@@ -1,2 +1,5 @@
1
1
  import { sort } from "./sort.mjs";
2
- export { sort };
2
+ import { ReadJsonStreamProps, RowCallback, RowSource, SortCallback, WriteJsonStreamProps, rowCallbackTransform, toRowReadable } from "./json/logic.mjs";
3
+ import { readJsonGzipStream, readJsonStream } from "./json/read.mjs";
4
+ import { JsonNewLineStringifier, jsonNewLineStringifier, writeJsonGzipStream, writeJsonStream } from "./json/write.mjs";
5
+ export { JsonNewLineStringifier, ReadJsonStreamProps, RowCallback, RowSource, SortCallback, WriteJsonStreamProps, jsonNewLineStringifier, readJsonGzipStream, readJsonStream, rowCallbackTransform, sort, toRowReadable, writeJsonGzipStream, writeJsonStream };
@@ -1,2 +1,5 @@
1
1
  import { sort } from "./sort.mjs";
2
- export { sort };
2
+ import { rowCallbackTransform, toRowReadable } from "./json/logic.mjs";
3
+ import { readJsonGzipStream, readJsonStream } from "./json/read.mjs";
4
+ import { JsonNewLineStringifier, jsonNewLineStringifier, writeJsonGzipStream, writeJsonStream } from "./json/write.mjs";
5
+ export { JsonNewLineStringifier, jsonNewLineStringifier, readJsonGzipStream, readJsonStream, rowCallbackTransform, sort, toRowReadable, writeJsonGzipStream, writeJsonStream };
@@ -0,0 +1,18 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let stream = require("stream");
3
+ //#region src/stream/server/json/logic.ts
4
+ const toRowReadable = (source) => {
5
+ return source instanceof stream.Readable ? source : stream.Readable.from(source, { objectMode: true });
6
+ };
7
+ /**
8
+ * Applies the optional per-row callback, dropping rows for which it resolves null/undefined.
9
+ */
10
+ const rowCallbackTransform = (rowCallback) => new stream.Transform({
11
+ objectMode: true,
12
+ transform(row, _encoding, callback) {
13
+ Promise.resolve(rowCallback(row)).then((result) => callback(null, null === result || void 0 === result ? void 0 : result)).catch((error) => callback(error));
14
+ }
15
+ });
16
+ //#endregion
17
+ exports.rowCallbackTransform = rowCallbackTransform;
18
+ exports.toRowReadable = toRowReadable;
@@ -0,0 +1,27 @@
1
+ import { Readable, Transform, Writable } from "stream";
2
+ //#region src/stream/server/json/logic.d.ts
3
+ /** Per-row hook run during write or read; returning null/undefined drops the row. */
4
+ export type RowCallback<T = any> = (row: T) => T | null | undefined | Promise<T | null | undefined>;
5
+ /** Comparator for the optional sort stage, same shape as `Array.prototype.sort`'s compare function. */
6
+ export type SortCallback<T = any> = (a: T, b: T) => number;
7
+ /** Anything a row can be streamed from: a Readable, an async iterable, or a plain array. */
8
+ export type RowSource<T = any> = Readable | AsyncIterable<T> | T[];
9
+ /** Input for writeJsonStream/writeJsonGzipStream: where rows come from and where the JSON goes. */
10
+ export type WriteJsonStreamProps<T = any> = {
11
+ source: RowSource<T>;
12
+ destination: Writable;
13
+ rowCallback?: RowCallback<T>;
14
+ sortCallback?: SortCallback<T>;
15
+ };
16
+ /** Input for readJsonStream/readJsonGzipStream: the raw JSON byte source to parse. */
17
+ export type ReadJsonStreamProps<T = any> = {
18
+ source: Readable;
19
+ rowCallback?: RowCallback<T>;
20
+ sortCallback?: SortCallback<T>;
21
+ };
22
+ export declare const toRowReadable: <T>(source: RowSource<T>) => Readable;
23
+ /**
24
+ * Applies the optional per-row callback, dropping rows for which it resolves null/undefined.
25
+ */
26
+ export declare const rowCallbackTransform: <T>(rowCallback: RowCallback<T>) => Transform;
27
+ //#endregion
@@ -0,0 +1,27 @@
1
+ import { Readable, Transform, Writable } from "stream";
2
+ //#region src/stream/server/json/logic.d.ts
3
+ /** Per-row hook run during write or read; returning null/undefined drops the row. */
4
+ export type RowCallback<T = any> = (row: T) => T | null | undefined | Promise<T | null | undefined>;
5
+ /** Comparator for the optional sort stage, same shape as `Array.prototype.sort`'s compare function. */
6
+ export type SortCallback<T = any> = (a: T, b: T) => number;
7
+ /** Anything a row can be streamed from: a Readable, an async iterable, or a plain array. */
8
+ export type RowSource<T = any> = Readable | AsyncIterable<T> | T[];
9
+ /** Input for writeJsonStream/writeJsonGzipStream: where rows come from and where the JSON goes. */
10
+ export type WriteJsonStreamProps<T = any> = {
11
+ source: RowSource<T>;
12
+ destination: Writable;
13
+ rowCallback?: RowCallback<T>;
14
+ sortCallback?: SortCallback<T>;
15
+ };
16
+ /** Input for readJsonStream/readJsonGzipStream: the raw JSON byte source to parse. */
17
+ export type ReadJsonStreamProps<T = any> = {
18
+ source: Readable;
19
+ rowCallback?: RowCallback<T>;
20
+ sortCallback?: SortCallback<T>;
21
+ };
22
+ export declare const toRowReadable: <T>(source: RowSource<T>) => Readable;
23
+ /**
24
+ * Applies the optional per-row callback, dropping rows for which it resolves null/undefined.
25
+ */
26
+ export declare const rowCallbackTransform: <T>(rowCallback: RowCallback<T>) => Transform;
27
+ //#endregion