@mcpher/gas-fakes 2.3.5 → 2.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/main.js CHANGED
@@ -1,8 +1,6 @@
1
1
  // testing locally
2
2
  // sync the version with gas fakes code since they share a package.json
3
- import { createRequire } from 'node:module';
4
- const require = createRequire(import.meta.url);
5
- const pjson = require('./package.json');
6
- const VERSION = pjson.version;
7
- console.log (`...gas-fakes version ${VERSION}`)
3
+ import { initMetadata } from './src/support/metadata.js';
4
+ initMetadata();
5
+ console.log (`...gas-fakes version ${globalThis.GasFakes.metadata.version}`)
8
6
  import './src/index.js'
package/package.json CHANGED
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "name": "@mcpher/gas-fakes",
40
40
  "author": "bruce mcpherson",
41
- "version": "2.3.5",
41
+ "version": "2.3.6",
42
42
  "license": "MIT",
43
43
  "main": "main.js",
44
44
  "description": "An implementation of the Google Workspace Apps Script runtime: Run native App Script Code on Node and Cloud Run",
package/src/cli/setup.js CHANGED
@@ -5,9 +5,8 @@ import path from "path";
5
5
  import os from "os";
6
6
  import { randomUUID } from "node:crypto";
7
7
  import { execSync } from "child_process";
8
- import { checkForGcloudCli, checkForAzCli, runCommandSync } from "./utils.js";
8
+ import { checkForGcloudCli, runCommandSync } from "./utils.js";
9
9
  import { getMsGraphToken, mapGasScopesToMsGraph } from "../support/msgraph/msauth.js";
10
- import { Platforms, PlatformDefaults } from "../services/enums/platformenums.js";
11
10
 
12
11
  // --- Utility Functions ---
13
12
 
package/src/cli/utils.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { spawn, execSync } from "child_process";
2
- import { createRequire } from "node:module";
3
- const require = createRequire(import.meta.url);
4
- const pjson = require("../../package.json");
2
+ import { initMetadata } from "../support/metadata.js";
3
+ const GasFakes = initMetadata();
5
4
 
6
- export const VERSION = pjson.version;
5
+ export const VERSION = GasFakes.metadata.version;
7
6
  export const CLI_VERSION = "0.0.20";
8
7
  export const MCP_VERSION = "0.0.7";
9
8
 
@@ -0,0 +1,37 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+
3
+ class FakeJdbcArray {
4
+ constructor(data, baseType, baseTypeName) {
5
+ this.__fakeObjectType = 'JdbcArray';
6
+ this._data = Array.isArray(data) ? data : [data];
7
+ this._baseType = baseType || 12; // VARCHAR
8
+ this._baseTypeName = baseTypeName || 'VARCHAR';
9
+ this._isClosed = false;
10
+ }
11
+
12
+ getArray() {
13
+ if (this._isClosed) throw new Error('Array is closed.');
14
+ return this._data;
15
+ }
16
+
17
+ getBaseType() {
18
+ return this._baseType;
19
+ }
20
+
21
+ getBaseTypeName() {
22
+ return this._baseTypeName;
23
+ }
24
+
25
+ getResultSet() {
26
+ // In actual JDBC this returns a result set with columns INDEX and VALUE
27
+ // For now, returning null as it's rarely used in Apps Script JDBC context
28
+ return null;
29
+ }
30
+
31
+ free() {
32
+ this._isClosed = true;
33
+ this._data = null;
34
+ }
35
+ }
36
+
37
+ export const newFakeJdbcArray = (...args) => Proxies.guard(new FakeJdbcArray(...args));
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Fake implementation of Google Apps Script Jdbc's BigDecimal (java.math.BigDecimal proxy)
3
+ */
4
+ export class FakeJdbcBigDecimal {
5
+ constructor(val) {
6
+ this.val = String(val);
7
+ }
8
+
9
+ /**
10
+ * Returns the string representation of this BigDecimal.
11
+ * This is how it's typically used in Apps Script for comparison or output.
12
+ */
13
+ toString() {
14
+ return this.val;
15
+ }
16
+
17
+ /**
18
+ * Returns the value as a JavaScript number.
19
+ * Corresponds to Java's doubleValue()
20
+ */
21
+ doubleValue() {
22
+ return Number(this.val);
23
+ }
24
+
25
+ /**
26
+ * Returns the value as an integer.
27
+ * Corresponds to Java's intValue()
28
+ */
29
+ intValue() {
30
+ return Math.floor(Number(this.val));
31
+ }
32
+
33
+ /**
34
+ * Returns the value as a long integer.
35
+ * Corresponds to Java's longValue()
36
+ */
37
+ longValue() {
38
+ return Math.floor(Number(this.val));
39
+ }
40
+
41
+ /**
42
+ * Returns the string representation without scientific notation.
43
+ * Corresponds to Java's toPlainString()
44
+ */
45
+ toPlainString() {
46
+ return this.val;
47
+ }
48
+
49
+ /**
50
+ * Returns the scale of this BigDecimal.
51
+ */
52
+ scale() {
53
+ const parts = this.val.split('.');
54
+ return parts.length > 1 ? parts[1].length : 0;
55
+ }
56
+
57
+ /**
58
+ * Returns the precision of this BigDecimal.
59
+ */
60
+ precision() {
61
+ return this.val.replace('.', '').replace('-', '').length;
62
+ }
63
+ }
@@ -0,0 +1,67 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+ import { newFakeInputStream } from '../../support/fakeinputstream.js';
3
+
4
+ class FakeJdbcBlob {
5
+ constructor(data) {
6
+ this.__fakeObjectType = 'JdbcBlob';
7
+ // Ensure we have a Buffer/Uint8Array
8
+ this._data = (data instanceof Uint8Array || Buffer.isBuffer(data))
9
+ ? data
10
+ : Buffer.from(data || '');
11
+ this._isClosed = false;
12
+ }
13
+
14
+ getBinaryStream() {
15
+ if (this._isClosed) throw new Error('Blob is closed.');
16
+ return newFakeInputStream(this._data);
17
+ }
18
+
19
+ getBytes(pos, len) {
20
+ if (this._isClosed) throw new Error('Blob is closed.');
21
+ // pos is 1-indexed in JDBC
22
+ const start = pos - 1;
23
+ const end = start + len;
24
+ return Array.from(this._data.slice(start, end));
25
+ }
26
+
27
+ length() {
28
+ if (this._isClosed) throw new Error('Blob is closed.');
29
+ return this._data.length;
30
+ }
31
+
32
+ position(pattern, start) {
33
+ if (this._isClosed) throw new Error('Blob is closed.');
34
+ // Simple implementation for parity
35
+ const patternBuffer = (pattern instanceof FakeJdbcBlob) ? pattern._data : Buffer.from(pattern);
36
+ const index = this._data.indexOf(patternBuffer, start - 1);
37
+ return index === -1 ? -1 : index + 1;
38
+ }
39
+
40
+ setBinaryStream(pos) {
41
+ // Not fully supported in fake, but allows setting direction
42
+ return this.getBinaryStream();
43
+ }
44
+
45
+ setBytes(pos, bytes) {
46
+ if (this._isClosed) throw new Error('Blob is closed.');
47
+ const start = pos - 1;
48
+ const newBytes = Buffer.from(bytes);
49
+ const newData = Buffer.alloc(Math.max(this._data.length, start + newBytes.length));
50
+ this._data.copy(newData);
51
+ newBytes.copy(newData, start);
52
+ this._data = newData;
53
+ return newBytes.length;
54
+ }
55
+
56
+ truncate(len) {
57
+ if (this._isClosed) throw new Error('Blob is closed.');
58
+ this._data = this._data.slice(0, len);
59
+ }
60
+
61
+ free() {
62
+ this._isClosed = true;
63
+ this._data = null;
64
+ }
65
+ }
66
+
67
+ export const newFakeJdbcBlob = (...args) => Proxies.guard(new FakeJdbcBlob(...args));
@@ -0,0 +1,67 @@
1
+ import { Proxies } from '../../support/proxies.js';
2
+ import { newFakeInputStream, newFakeReader } from '../../support/fakeinputstream.js';
3
+
4
+ class FakeJdbcClob {
5
+ constructor(data) {
6
+ this.__fakeObjectType = 'JdbcClob';
7
+ this._data = String(data || '');
8
+ this._isClosed = false;
9
+ }
10
+
11
+ getAsciiStream() {
12
+ if (this._isClosed) throw new Error('Clob is closed.');
13
+ return newFakeInputStream(Buffer.from(this._data, 'ascii'));
14
+ }
15
+
16
+ getCharacterStream() {
17
+ if (this._isClosed) throw new Error('Clob is closed.');
18
+ return newFakeReader(this._data);
19
+ }
20
+
21
+ getSubString(pos, len) {
22
+ if (this._isClosed) throw new Error('Clob is closed.');
23
+ // pos is 1-indexed
24
+ return this._data.substring(pos - 1, pos - 1 + len);
25
+ }
26
+
27
+ length() {
28
+ if (this._isClosed) throw new Error('Clob is closed.');
29
+ return this._data.length;
30
+ }
31
+
32
+ position(pattern, start) {
33
+ if (this._isClosed) throw new Error('Clob is closed.');
34
+ const searchPattern = (pattern instanceof FakeJdbcClob) ? pattern._data : String(pattern);
35
+ const index = this._data.indexOf(searchPattern, start - 1);
36
+ return index === -1 ? -1 : index + 1;
37
+ }
38
+
39
+ setAsciiStream(pos) {
40
+ return this.getAsciiStream();
41
+ }
42
+
43
+ setCharacterStream(pos) {
44
+ return this.getCharacterStream();
45
+ }
46
+
47
+ setString(pos, str) {
48
+ if (this._isClosed) throw new Error('Clob is closed.');
49
+ const start = pos - 1;
50
+ const prefix = this._data.substring(0, start).padEnd(start, ' ');
51
+ const suffix = this._data.substring(start + str.length);
52
+ this._data = prefix + str + suffix;
53
+ return str.length;
54
+ }
55
+
56
+ truncate(len) {
57
+ if (this._isClosed) throw new Error('Clob is closed.');
58
+ this._data = this._data.substring(0, len);
59
+ }
60
+
61
+ free() {
62
+ this._isClosed = true;
63
+ this._data = null;
64
+ }
65
+ }
66
+
67
+ export const newFakeJdbcClob = (...args) => Proxies.guard(new FakeJdbcClob(...args));
@@ -1,6 +1,8 @@
1
1
  import { Proxies } from '../../support/proxies.js';
2
2
  import { Syncit } from '../../support/syncit.js';
3
3
  import { newFakeJdbcStatement } from './fakejdbcstatement.js';
4
+ import { newFakeJdbcPreparedStatement } from './fakejdbcpreparedstatement.js';
5
+ import { newFakeJdbcDatabaseMetaData } from './fakejdbcdatabasemetadata.js';
4
6
 
5
7
  class FakeJdbcConnection {
6
8
  constructor(url, user, password) {
@@ -17,16 +19,35 @@ class FakeJdbcConnection {
17
19
  this._connectionId = result.id;
18
20
  }
19
21
 
20
- createStatement() {
21
- return newFakeJdbcStatement(this._connectionId);
22
+ // GAS overload: createStatement() or createStatement(resultSetType, resultSetConcurrency)
23
+ // resultSetType/Concurrency parameters are advisory in the fake since results are buffered in memory.
24
+ createStatement(resultSetType, resultSetConcurrency) {
25
+ return newFakeJdbcStatement(this, this._connectionId);
26
+ }
27
+
28
+ prepareStatement(sql) {
29
+ return newFakeJdbcPreparedStatement(this, this._connectionId, sql);
30
+ }
31
+
32
+ commit() {
33
+ Syncit.fxJdbcCommit(this._connectionId);
34
+ }
35
+
36
+ rollback() {
37
+ Syncit.fxJdbcRollback(this._connectionId);
38
+ }
39
+
40
+ setAutoCommit(autoCommit) {
41
+ Syncit.fxJdbcSetAutoCommit(this._connectionId, autoCommit);
42
+ }
43
+
44
+ getAutoCommit() {
45
+ // We don't currently track this in the proxy, but GAS default is true
46
+ return true;
22
47
  }
23
48
 
24
49
  getMetaData() {
25
- // Return an object that mimics DatabaseMetaData
26
- return Proxies.guard({
27
- __fakeObjectType: 'JdbcDatabaseMetaData',
28
- getURL: () => this._url
29
- });
50
+ return newFakeJdbcDatabaseMetaData(this, this._connectionId, this._url);
30
51
  }
31
52
 
32
53
  // To match GAS JdbcConnection basic capabilities