@8ms/helpers 3.2.7 → 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 (68) 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 +1 -1
  67. package/dist/xlsx/_shared/createXlsx.mjs +1 -1
  68. package/package.json +33 -5
@@ -9,9 +9,11 @@ const fileMimeType = {
9
9
  [fileType.JPEG]: "image/jpeg",
10
10
  [fileType.JPG]: "image/jpeg",
11
11
  [fileType.JSON]: "application/json",
12
+ [fileType.JSON_NEWLINE]: "application/x-ndjson",
12
13
  [fileType.MKV]: "video/x-matroska",
13
14
  [fileType.MOV]: "video/quicktime",
14
15
  [fileType.MP4]: "video/mp4",
16
+ [fileType.PARQUET]: "application/vnd.apache.parquet",
15
17
  [fileType.PDF]: "application/pdf",
16
18
  [fileType.PNG]: "image/png",
17
19
  [fileType.PPT]: "application/vnd.ms-powerpoint",
@@ -2,6 +2,8 @@
2
2
  export declare const fileType: {
3
3
  readonly ZIP: "zip";
4
4
  readonly JSON: "json";
5
+ readonly JSON_NEWLINE: "jsonl";
6
+ readonly PARQUET: "parquet";
5
7
  readonly XML: "xml";
6
8
  readonly DOC: "doc";
7
9
  readonly DOCX: "docx";
@@ -2,6 +2,8 @@
2
2
  export declare const fileType: {
3
3
  readonly ZIP: "zip";
4
4
  readonly JSON: "json";
5
+ readonly JSON_NEWLINE: "jsonl";
6
+ readonly PARQUET: "parquet";
5
7
  readonly XML: "xml";
6
8
  readonly DOC: "doc";
7
9
  readonly DOCX: "docx";
@@ -17,5 +17,5 @@ import { GoogleCloudBQRow, googleCloudBQRow } from "./lookup/googleCloud.cjs";
17
17
  import { LanguageBQRow, languageBQRow } from "./lookup/language.cjs";
18
18
  import { PartitionType, partitionType } from "./partitionType.cjs";
19
19
  import { BQField, zodToBQSchema } from "./zodToBQDefinition.cjs";
20
- import { TableDefinition } from "./types.cjs";
21
- export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, CountryBQRow, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, PartitionType, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
20
+ import { BigqueryLoadFormat, Dataset, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, QueryInput, Table, TableDefinition } from "./types.cjs";
21
+ export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, BigqueryLoadFormat, CountryBQRow, Dataset, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, PartitionType, QueryInput, Table, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
@@ -17,5 +17,5 @@ import { GoogleCloudBQRow, googleCloudBQRow } from "./lookup/googleCloud.mjs";
17
17
  import { LanguageBQRow, languageBQRow } from "./lookup/language.mjs";
18
18
  import { PartitionType, partitionType } from "./partitionType.mjs";
19
19
  import { BQField, zodToBQSchema } from "./zodToBQDefinition.mjs";
20
- import { TableDefinition } from "./types.mjs";
21
- export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, CountryBQRow, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, PartitionType, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
20
+ import { BigqueryLoadFormat, Dataset, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, QueryInput, Table, TableDefinition } from "./types.mjs";
21
+ export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, BigqueryLoadFormat, CountryBQRow, Dataset, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, PartitionType, QueryInput, Table, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
@@ -1,6 +1,12 @@
1
+ import { RowSource } from "../../../stream/server/json/logic.cjs";
2
+ import { fileType } from "../../../file/_shared/fileType.cjs";
1
3
  import { PartitionType } from "./partitionType.cjs";
2
4
  import { BQField } from "./zodToBQDefinition.cjs";
5
+ import { GoogleCloudStorage } from "../../storage/server/GoogleCloudStorage.cjs";
6
+ import { QueryOptions } from "@google-cloud/bigquery";
3
7
  //#region src/googleCloud/bigquery/_shared/types.d.ts
8
+ /** The only load formats this library can actually serialise/pass through for loadTable/loadStreamTable. */
9
+ export type BigqueryLoadFormat = typeof fileType.CSV | typeof fileType.JSON_NEWLINE | typeof fileType.PARQUET;
4
10
  export type TableDefinition = {
5
11
  projectId?: string;
6
12
  datasetId: string;
@@ -17,4 +23,52 @@ export type TableDefinition = {
17
23
  };
18
24
  };
19
25
  };
26
+ export type QueryInput = string | {
27
+ query: string;
28
+ location?: string;
29
+ params: QueryOptions;
30
+ };
31
+ export type Dataset = {
32
+ id: string;
33
+ location: string;
34
+ projectId: string;
35
+ };
36
+ export type Table = {
37
+ id: string;
38
+ };
39
+ export type LoadData<TData> = {
40
+ googleCloudStorage: GoogleCloudStorage;
41
+ file: {
42
+ bucket: string;
43
+ key: string;
44
+ data: TData;
45
+ sourceFormat?: BigqueryLoadFormat;
46
+ region?: string;
47
+ };
48
+ table: {
49
+ datasetId: string;
50
+ tableId?: string;
51
+ region?: string;
52
+ definition: TableDefinition;
53
+ options?: TableDefinition["options"];
54
+ };
55
+ };
56
+ export type LoadTableProps = LoadData<any[]>;
57
+ export type LoadStreamTableProps = LoadData<RowSource<any>>;
58
+ export type MergeTableProps = {
59
+ googleCloudStorage: GoogleCloudStorage;
60
+ file: {
61
+ bucket: string;
62
+ key: string;
63
+ data: any[];
64
+ };
65
+ table: {
66
+ datasetId: string;
67
+ tableId?: string;
68
+ region?: string;
69
+ definition: TableDefinition;
70
+ mergeKey: string;
71
+ updateColumns: string[];
72
+ };
73
+ };
20
74
  //#endregion
@@ -1,6 +1,12 @@
1
+ import { RowSource } from "../../../stream/server/json/logic.mjs";
2
+ import { fileType } from "../../../file/_shared/fileType.mjs";
1
3
  import { PartitionType } from "./partitionType.mjs";
2
4
  import { BQField } from "./zodToBQDefinition.mjs";
5
+ import { GoogleCloudStorage } from "../../storage/server/GoogleCloudStorage.mjs";
6
+ import { QueryOptions } from "@google-cloud/bigquery";
3
7
  //#region src/googleCloud/bigquery/_shared/types.d.ts
8
+ /** The only load formats this library can actually serialise/pass through for loadTable/loadStreamTable. */
9
+ export type BigqueryLoadFormat = typeof fileType.CSV | typeof fileType.JSON_NEWLINE | typeof fileType.PARQUET;
4
10
  export type TableDefinition = {
5
11
  projectId?: string;
6
12
  datasetId: string;
@@ -17,4 +23,52 @@ export type TableDefinition = {
17
23
  };
18
24
  };
19
25
  };
26
+ export type QueryInput = string | {
27
+ query: string;
28
+ location?: string;
29
+ params: QueryOptions;
30
+ };
31
+ export type Dataset = {
32
+ id: string;
33
+ location: string;
34
+ projectId: string;
35
+ };
36
+ export type Table = {
37
+ id: string;
38
+ };
39
+ export type LoadData<TData> = {
40
+ googleCloudStorage: GoogleCloudStorage;
41
+ file: {
42
+ bucket: string;
43
+ key: string;
44
+ data: TData;
45
+ sourceFormat?: BigqueryLoadFormat;
46
+ region?: string;
47
+ };
48
+ table: {
49
+ datasetId: string;
50
+ tableId?: string;
51
+ region?: string;
52
+ definition: TableDefinition;
53
+ options?: TableDefinition["options"];
54
+ };
55
+ };
56
+ export type LoadTableProps = LoadData<any[]>;
57
+ export type LoadStreamTableProps = LoadData<RowSource<any>>;
58
+ export type MergeTableProps = {
59
+ googleCloudStorage: GoogleCloudStorage;
60
+ file: {
61
+ bucket: string;
62
+ key: string;
63
+ data: any[];
64
+ };
65
+ table: {
66
+ datasetId: string;
67
+ tableId?: string;
68
+ region?: string;
69
+ definition: TableDefinition;
70
+ mergeKey: string;
71
+ updateColumns: string[];
72
+ };
73
+ };
20
74
  //#endregion
@@ -17,6 +17,6 @@ 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
- export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, CountryBQRow, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, PartitionType, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
22
+ export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, BigqueryLoadFormat, CountryBQRow, Dataset, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, PartitionType, QueryInput, Table, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
@@ -17,6 +17,6 @@ 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
- export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, CountryBQRow, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, PartitionType, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
22
+ export { BQBool, BQBytes, BQDate, BQDateTime, BQDatetime, BQField, BQFieldMode, BQFieldModeSchema, BQFieldType, BQFieldTypeSchema, BQFloat, BQInt64, BQNumeric, BQString, BQTime, BQTimestamp, BigqueryLoadFormat, CountryBQRow, Dataset, GoogleAdsAccountBQRow, GoogleCloudBQRow, LanguageBQRow, LoadData, LoadStreamTableProps, LoadTableProps, MergeTableProps, PartitionType, QueryInput, Table, TableDefinition, countryBQRow, decodeBQDate, decodeBQDateTime, encodeBQDate, encodeBQDateTime, googleAdsAccountBQRow, googleCloudBQRow, languageBQRow, partitionType, zBQBytes, zBQInt, zBQInt64, zBQNumeric, zBQTime, zLuxonDate, zLuxonDateTime, zodToBQSchema };
@@ -1,7 +1,23 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_lodash__shared_isObject = require("../../../lodash/_shared/isObject.cjs");
3
3
  const require__class__shared_BaseNamespace = require("../../../_class/_shared/BaseNamespace.cjs");
4
+ const require_date__shared_format = require("../../../date/_shared/format.cjs");
5
+ require("../../../date/_shared/index.cjs");
6
+ const require_file__shared_fileType = require("../../../file/_shared/fileType.cjs");
7
+ const require_file__shared_fileMimeType = require("../../../file/_shared/fileMimeType.cjs");
8
+ require("../../../file/_shared/index.cjs");
9
+ const require_json__shared_getJsonNewline = require("../../../json/_shared/getJsonNewline.cjs");
10
+ const require_stream_server_json_logic = require("../../../stream/server/json/logic.cjs");
11
+ const require_stream_server_json_write = require("../../../stream/server/json/write.cjs");
12
+ require("../../../stream/server/index.cjs");
13
+ let node_stream_promises = require("node:stream/promises");
4
14
  //#region src/googleCloud/bigquery/server/GoogleCloudBigquery.ts
15
+ /** Maps this library's generic file-type catalog onto BigQuery's own load-job sourceFormat strings. */
16
+ const bigQuerySourceFormat = {
17
+ [require_file__shared_fileType.fileType.CSV]: "CSV",
18
+ [require_file__shared_fileType.fileType.JSON_NEWLINE]: "NEWLINE_DELIMITED_JSON",
19
+ [require_file__shared_fileType.fileType.PARQUET]: "PARQUET"
20
+ };
5
21
  var GoogleCloudBigquery = class extends require__class__shared_BaseNamespace.BaseNamespace {
6
22
  /**
7
23
  * Either a Google Cloud JSON Config or V10 Auth helper.
@@ -65,7 +81,7 @@ var GoogleCloudBigquery = class extends require__class__shared_BaseNamespace.Bas
65
81
  });
66
82
  return response;
67
83
  };
68
- query = async (props) => {
84
+ buildQueryOptions = (props) => {
69
85
  let options = { query: "" };
70
86
  if ("string" === typeof props) {
71
87
  options.query = props;
@@ -76,7 +92,19 @@ var GoogleCloudBigquery = class extends require__class__shared_BaseNamespace.Bas
76
92
  if (resolvedLocation) options.location = resolvedLocation;
77
93
  if (props?.params) options["params"] = props.params;
78
94
  }
79
- return await this.client.query(options);
95
+ return options;
96
+ };
97
+ /**
98
+ * Make a request to the database and return the object per row.
99
+ */
100
+ query = async (props) => {
101
+ return await this.client.query(this.buildQueryOptions(props));
102
+ };
103
+ /**
104
+ * Return the raw row stream for a query, without buffering the full result set in memory.
105
+ */
106
+ queryStream = (props) => {
107
+ return this.client.createQueryStream(this.buildQueryOptions(props));
80
108
  };
81
109
  /**
82
110
  * Create a Table if it doesn't already exist.
@@ -113,14 +141,137 @@ var GoogleCloudBigquery = class extends require__class__shared_BaseNamespace.Bas
113
141
  return true;
114
142
  };
115
143
  /**
116
- * Load data into this table using Google Cloud Storage.
144
+ * Load a Google Cloud Storage file into a table. BigQuery load jobs default to
145
+ * createDisposition "CREATE_IF_NEEDED"; paired with autodetect, this creates the table itself
146
+ * from the source file's inferred schema if it doesn't already exist, rather than this library
147
+ * pre-checking existence and silently skipping the load if it isn't there.
117
148
  */
118
- loadData = async ({ file, googleCloudStorageClient, table }) => {
119
- 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), {
120
- ...file?.metadata ?? {},
121
- location: file?.region
149
+ loadData = async (props) => {
150
+ const finalTableId = props.table.tableId;
151
+ await this.createTable(props.table.datasetId, {}, finalTableId, props.table.options);
152
+ 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), {
153
+ autodetect: true,
154
+ sourceFormat: bigQuerySourceFormat[props.file.sourceFormat ?? require_file__shared_fileType.fileType.JSON_NEWLINE],
155
+ schemaUpdateOptions: ["ALLOW_FIELD_ADDITION"],
156
+ location: props.table.region
122
157
  });
123
158
  };
159
+ /**
160
+ * Write rows to Google Cloud Storage, then load them into the table - creating the table first
161
+ * if it doesn't already exist. Only JSON_NEWLINE (the default) is actually serialised by this
162
+ * library (getJsonNewline); for PARQUET, `data` is written as-is and must already be encoded -
163
+ * this library has no Parquet encoder.
164
+ */
165
+ loadTable = async (props) => {
166
+ const finalTableId = props.table.tableId ?? props.table.definition.tableId;
167
+ const fileSourceFormat = props.file.sourceFormat ?? require_file__shared_fileType.fileType.JSON_NEWLINE;
168
+ const finalData = require_file__shared_fileType.fileType.JSON_NEWLINE === fileSourceFormat ? require_json__shared_getJsonNewline.getJsonNewline(props.file.data) : props.file.data;
169
+ await props.googleCloudStorage.writeFile(props.file.bucket, props.file.key, finalData);
170
+ await this.loadData({
171
+ ...props,
172
+ table: {
173
+ ...props.table,
174
+ tableId: finalTableId
175
+ }
176
+ });
177
+ };
178
+ /**
179
+ * Same as loadTable, but streams a row source into Google Cloud Storage instead of buffering the
180
+ * full collection in memory first. Writes directly against the Storage client's own write stream
181
+ * (GoogleCloudStorage.writeFile can't stream a Readable source) - creates the table first if it
182
+ * doesn't already exist. For JSON_NEWLINE (the default) `source` is a stream of row objects,
183
+ * stringified one at a time; for PARQUET there is no stringify stage - `source` must already be a
184
+ * byte-level Readable of encoded Parquet content, piped straight through.
185
+ */
186
+ loadStreamTable = async (props) => {
187
+ const finalTableId = props.table.tableId ?? props.table.definition.tableId;
188
+ const fileSourceFormat = props.file.sourceFormat ?? require_file__shared_fileType.fileType.JSON_NEWLINE;
189
+ const destination = props.googleCloudStorage.client.bucket(props.file.bucket).file(props.file.key).createWriteStream({
190
+ contentType: require_file__shared_fileMimeType.fileMimeType[fileSourceFormat],
191
+ resumable: false
192
+ });
193
+ const source = require_stream_server_json_logic.toRowReadable(props.file.data);
194
+ if (require_file__shared_fileType.fileType.JSON_NEWLINE === fileSourceFormat) await (0, node_stream_promises.pipeline)([
195
+ source,
196
+ require_stream_server_json_write.jsonNewLineStringifier(),
197
+ destination
198
+ ]);
199
+ else await (0, node_stream_promises.pipeline)([source, destination]);
200
+ await this.loadData({
201
+ ...props,
202
+ table: {
203
+ ...props.table,
204
+ tableId: finalTableId
205
+ }
206
+ });
207
+ };
208
+ /**
209
+ * Brings an existing table's clustering in line with `definition.options.clustering`, if it differs.
210
+ * Partitioning is immutable on an existing BigQuery table - changing it requires recreating the
211
+ * table and backfilling data, which this method deliberately does not attempt.
212
+ */
213
+ syncTableClustering = async (datasetId, tableId, clustering) => {
214
+ const [metadata] = await this.client.dataset(datasetId).table(tableId).getMetadata();
215
+ const currentFields = metadata?.clustering?.fields ?? [];
216
+ const desiredFields = clustering?.fields ?? [];
217
+ if (currentFields.length === desiredFields.length && currentFields.every((field, index) => field === desiredFields[index])) return;
218
+ await this.client.dataset(datasetId).table(tableId).setMetadata(desiredFields.length > 0 ? { clustering: { fields: desiredFields } } : { clustering: void 0 });
219
+ };
220
+ /**
221
+ * Upsert rows into a table via a staging table + a single MERGE statement.
222
+ *
223
+ * BigQuery has no efficient row-level UPDATE/DELETE - both rewrite the affected partitions and
224
+ * are subject to daily DML mutation quotas. Loading new rows into a disposable staging table and
225
+ * running one MERGE is the standard, quota-friendly way to upsert in BigQuery.
226
+ */
227
+ mergeTable = async (props) => {
228
+ if (0 === props.file.data.length) return;
229
+ const finalTableId = props.table.tableId ?? props.table.definition.tableId;
230
+ if (await this.tableExists(props.table.datasetId, finalTableId)) await this.syncTableClustering(props.table.datasetId, finalTableId, props.table.definition.options?.clustering);
231
+ const stagingTableId = `${finalTableId}_staging_${require_date__shared_format.getYmdHisNumber()}`;
232
+ const stagingTableRef = `\`${props.table.datasetId}.${stagingTableId}\``;
233
+ try {
234
+ const stagingDefinition = {
235
+ ...props.table.definition,
236
+ tableId: stagingTableId,
237
+ options: props.table.definition.options ? {
238
+ ...props.table.definition.options,
239
+ timePartitioning: void 0,
240
+ clustering: void 0
241
+ } : void 0
242
+ };
243
+ await this.loadTable({
244
+ googleCloudStorage: props.googleCloudStorage,
245
+ file: props.file,
246
+ table: {
247
+ datasetId: props.table.datasetId,
248
+ definition: stagingDefinition,
249
+ tableId: stagingTableId,
250
+ region: props.table.region
251
+ }
252
+ });
253
+ const mainTableRef = `\`${props.table.datasetId}.${finalTableId}\``;
254
+ const updateSet = props.table.updateColumns.map((column) => `${column} = S.${column}`).join(", ");
255
+ const allColumns = props.table.definition.options?.schema.map((field) => field.name) ?? [];
256
+ const mergeQuery = `
257
+ MERGE ${mainTableRef} AS T
258
+ USING ${stagingTableRef} AS S
259
+ ON T.${props.table.mergeKey} = S.${props.table.mergeKey}
260
+ WHEN MATCHED THEN
261
+ UPDATE SET ${updateSet}
262
+ WHEN NOT MATCHED THEN
263
+ INSERT (${allColumns.join(", ")})
264
+ VALUES (${allColumns.map((column) => `S.${column}`).join(", ")})
265
+ `;
266
+ await this.query(mergeQuery);
267
+ } finally {
268
+ try {
269
+ await this.query(`DROP TABLE IF EXISTS ${stagingTableRef}`);
270
+ } catch (error) {
271
+ console.error(`mergeTable: failed to drop staging table ${stagingTableRef} - it must be dropped manually.`, error);
272
+ }
273
+ }
274
+ };
124
275
  };
125
276
  //#endregion
126
277
  exports.GoogleCloudBigquery = GoogleCloudBigquery;
@@ -1,34 +1,9 @@
1
1
  import { BaseNamespace } from "../../../_class/_shared/BaseNamespace.cjs";
2
- import { GoogleCloudStorage } from "../../storage/server/GoogleCloudStorage.cjs";
3
- import { BigQuery, DatasetResource, QueryOptions } from "@google-cloud/bigquery";
2
+ import { Dataset, LoadStreamTableProps, LoadTableProps, MergeTableProps, QueryInput, Table } from "../_shared/types.cjs";
3
+ import "../_shared/index.cjs";
4
+ import { ResourceStream } from "../../../node_modules/@google-cloud/paginator/build/src/resource-stream.cjs";
5
+ import { BigQuery, DatasetResource } from "@google-cloud/bigquery";
4
6
  //#region src/googleCloud/bigquery/server/GoogleCloudBigquery.d.ts
5
- type LoadData = {
6
- googleCloudStorageClient: GoogleCloudStorage;
7
- file: {
8
- bucket: string;
9
- key: string;
10
- metadata?: object;
11
- region?: string;
12
- };
13
- table: {
14
- datasetId: string;
15
- region?: string;
16
- tableId: string;
17
- };
18
- };
19
- export type QueryInput = string | {
20
- query: string;
21
- location?: string;
22
- params: QueryOptions;
23
- };
24
- type Dataset = {
25
- id: string;
26
- location: string;
27
- projectId: string;
28
- };
29
- type Table = {
30
- id: string;
31
- };
32
7
  export declare class GoogleCloudBigquery extends BaseNamespace {
33
8
  client: BigQuery;
34
9
  config: any;
@@ -53,7 +28,15 @@ export declare class GoogleCloudBigquery extends BaseNamespace {
53
28
  * Retrieve all the Datasets
54
29
  */
55
30
  getDatasets: () => Promise<Dataset[]>;
31
+ private buildQueryOptions;
32
+ /**
33
+ * Make a request to the database and return the object per row.
34
+ */
56
35
  query: (props: QueryInput) => Promise<any>;
36
+ /**
37
+ * Return the raw row stream for a query, without buffering the full result set in memory.
38
+ */
39
+ queryStream: (props: QueryInput) => ResourceStream<any>;
57
40
  /**
58
41
  * Create a Table if it doesn't already exist.
59
42
  */
@@ -69,8 +52,41 @@ export declare class GoogleCloudBigquery extends BaseNamespace {
69
52
  */
70
53
  tablesExist: (datasetId: string, tableIds: string[]) => Promise<boolean>;
71
54
  /**
72
- * Load data into this table using Google Cloud Storage.
55
+ * Load a Google Cloud Storage file into a table. BigQuery load jobs default to
56
+ * createDisposition "CREATE_IF_NEEDED"; paired with autodetect, this creates the table itself
57
+ * from the source file's inferred schema if it doesn't already exist, rather than this library
58
+ * pre-checking existence and silently skipping the load if it isn't there.
59
+ */
60
+ private loadData;
61
+ /**
62
+ * Write rows to Google Cloud Storage, then load them into the table - creating the table first
63
+ * if it doesn't already exist. Only JSON_NEWLINE (the default) is actually serialised by this
64
+ * library (getJsonNewline); for PARQUET, `data` is written as-is and must already be encoded -
65
+ * this library has no Parquet encoder.
66
+ */
67
+ loadTable: (props: LoadTableProps) => Promise<void>;
68
+ /**
69
+ * Same as loadTable, but streams a row source into Google Cloud Storage instead of buffering the
70
+ * full collection in memory first. Writes directly against the Storage client's own write stream
71
+ * (GoogleCloudStorage.writeFile can't stream a Readable source) - creates the table first if it
72
+ * doesn't already exist. For JSON_NEWLINE (the default) `source` is a stream of row objects,
73
+ * stringified one at a time; for PARQUET there is no stringify stage - `source` must already be a
74
+ * byte-level Readable of encoded Parquet content, piped straight through.
75
+ */
76
+ loadStreamTable: (props: LoadStreamTableProps) => Promise<void>;
77
+ /**
78
+ * Brings an existing table's clustering in line with `definition.options.clustering`, if it differs.
79
+ * Partitioning is immutable on an existing BigQuery table - changing it requires recreating the
80
+ * table and backfilling data, which this method deliberately does not attempt.
81
+ */
82
+ private syncTableClustering;
83
+ /**
84
+ * Upsert rows into a table via a staging table + a single MERGE statement.
85
+ *
86
+ * BigQuery has no efficient row-level UPDATE/DELETE - both rewrite the affected partitions and
87
+ * are subject to daily DML mutation quotas. Loading new rows into a disposable staging table and
88
+ * running one MERGE is the standard, quota-friendly way to upsert in BigQuery.
73
89
  */
74
- loadData: ({ file, googleCloudStorageClient, table }: LoadData) => Promise<void>;
90
+ mergeTable: (props: MergeTableProps) => Promise<void>;
75
91
  }
76
92
  //#endregion
@@ -1,34 +1,9 @@
1
1
  import { BaseNamespace } from "../../../_class/_shared/BaseNamespace.mjs";
2
- import { GoogleCloudStorage } from "../../storage/server/GoogleCloudStorage.mjs";
3
- import { BigQuery, DatasetResource, QueryOptions } from "@google-cloud/bigquery";
2
+ import { Dataset, LoadStreamTableProps, LoadTableProps, MergeTableProps, QueryInput, Table } from "../_shared/types.mjs";
3
+ import "../_shared/index.mjs";
4
+ import { ResourceStream } from "../../../node_modules/@google-cloud/paginator/build/src/resource-stream.mjs";
5
+ import { BigQuery, DatasetResource } from "@google-cloud/bigquery";
4
6
  //#region src/googleCloud/bigquery/server/GoogleCloudBigquery.d.ts
5
- type LoadData = {
6
- googleCloudStorageClient: GoogleCloudStorage;
7
- file: {
8
- bucket: string;
9
- key: string;
10
- metadata?: object;
11
- region?: string;
12
- };
13
- table: {
14
- datasetId: string;
15
- region?: string;
16
- tableId: string;
17
- };
18
- };
19
- export type QueryInput = string | {
20
- query: string;
21
- location?: string;
22
- params: QueryOptions;
23
- };
24
- type Dataset = {
25
- id: string;
26
- location: string;
27
- projectId: string;
28
- };
29
- type Table = {
30
- id: string;
31
- };
32
7
  export declare class GoogleCloudBigquery extends BaseNamespace {
33
8
  client: BigQuery;
34
9
  config: any;
@@ -53,7 +28,15 @@ export declare class GoogleCloudBigquery extends BaseNamespace {
53
28
  * Retrieve all the Datasets
54
29
  */
55
30
  getDatasets: () => Promise<Dataset[]>;
31
+ private buildQueryOptions;
32
+ /**
33
+ * Make a request to the database and return the object per row.
34
+ */
56
35
  query: (props: QueryInput) => Promise<any>;
36
+ /**
37
+ * Return the raw row stream for a query, without buffering the full result set in memory.
38
+ */
39
+ queryStream: (props: QueryInput) => ResourceStream<any>;
57
40
  /**
58
41
  * Create a Table if it doesn't already exist.
59
42
  */
@@ -69,8 +52,41 @@ export declare class GoogleCloudBigquery extends BaseNamespace {
69
52
  */
70
53
  tablesExist: (datasetId: string, tableIds: string[]) => Promise<boolean>;
71
54
  /**
72
- * Load data into this table using Google Cloud Storage.
55
+ * Load a Google Cloud Storage file into a table. BigQuery load jobs default to
56
+ * createDisposition "CREATE_IF_NEEDED"; paired with autodetect, this creates the table itself
57
+ * from the source file's inferred schema if it doesn't already exist, rather than this library
58
+ * pre-checking existence and silently skipping the load if it isn't there.
59
+ */
60
+ private loadData;
61
+ /**
62
+ * Write rows to Google Cloud Storage, then load them into the table - creating the table first
63
+ * if it doesn't already exist. Only JSON_NEWLINE (the default) is actually serialised by this
64
+ * library (getJsonNewline); for PARQUET, `data` is written as-is and must already be encoded -
65
+ * this library has no Parquet encoder.
66
+ */
67
+ loadTable: (props: LoadTableProps) => Promise<void>;
68
+ /**
69
+ * Same as loadTable, but streams a row source into Google Cloud Storage instead of buffering the
70
+ * full collection in memory first. Writes directly against the Storage client's own write stream
71
+ * (GoogleCloudStorage.writeFile can't stream a Readable source) - creates the table first if it
72
+ * doesn't already exist. For JSON_NEWLINE (the default) `source` is a stream of row objects,
73
+ * stringified one at a time; for PARQUET there is no stringify stage - `source` must already be a
74
+ * byte-level Readable of encoded Parquet content, piped straight through.
75
+ */
76
+ loadStreamTable: (props: LoadStreamTableProps) => Promise<void>;
77
+ /**
78
+ * Brings an existing table's clustering in line with `definition.options.clustering`, if it differs.
79
+ * Partitioning is immutable on an existing BigQuery table - changing it requires recreating the
80
+ * table and backfilling data, which this method deliberately does not attempt.
81
+ */
82
+ private syncTableClustering;
83
+ /**
84
+ * Upsert rows into a table via a staging table + a single MERGE statement.
85
+ *
86
+ * BigQuery has no efficient row-level UPDATE/DELETE - both rewrite the affected partitions and
87
+ * are subject to daily DML mutation quotas. Loading new rows into a disposable staging table and
88
+ * running one MERGE is the standard, quota-friendly way to upsert in BigQuery.
73
89
  */
74
- loadData: ({ file, googleCloudStorageClient, table }: LoadData) => Promise<void>;
90
+ mergeTable: (props: MergeTableProps) => Promise<void>;
75
91
  }
76
92
  //#endregion