@jd-data-limited/easy-fm 4.0.16 → 4.1.1

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 (64) hide show
  1. package/package.json +16 -7
  2. package/src/FMError.d.ts +2 -2
  3. package/src/FMError.js +507 -508
  4. package/src/FMError.ts +510 -511
  5. package/src/connection/FMHost.d.ts +23 -5
  6. package/src/connection/FMHost.js +42 -26
  7. package/src/connection/FMHost.ts +63 -49
  8. package/src/connection/HostBase.d.ts +3 -3
  9. package/src/connection/HostBase.ts +5 -5
  10. package/src/connection/database.d.ts +53 -20
  11. package/src/connection/database.js +107 -90
  12. package/src/connection/database.ts +133 -121
  13. package/src/connection/databaseBase.d.ts +11 -7
  14. package/src/connection/databaseBase.ts +8 -8
  15. package/src/connection/generateAuthorizationHeaders.d.ts +1 -1
  16. package/src/connection/generateAuthorizationHeaders.js +10 -10
  17. package/src/connection/generateAuthorizationHeaders.ts +21 -21
  18. package/src/databaseStructure.d.ts +2 -4
  19. package/src/databaseStructure.ts +3 -5
  20. package/src/index.d.ts +17 -17
  21. package/src/index.js +13 -13
  22. package/src/index.ts +24 -24
  23. package/src/layouts/layout.d.ts +17 -6
  24. package/src/layouts/layout.js +19 -8
  25. package/src/layouts/layout.ts +33 -23
  26. package/src/layouts/layoutBase.d.ts +5 -5
  27. package/src/layouts/layoutBase.ts +6 -6
  28. package/src/layouts/layoutInterface.d.ts +3 -5
  29. package/src/layouts/layoutInterface.ts +4 -6
  30. package/src/layouts/layoutRecordManager.d.ts +29 -6
  31. package/src/layouts/layoutRecordManager.js +32 -9
  32. package/src/layouts/layoutRecordManager.ts +42 -19
  33. package/src/layouts/recordFieldsMap.d.ts +2 -4
  34. package/src/layouts/recordFieldsMap.ts +2 -4
  35. package/src/models/apiResults.d.ts +7 -13
  36. package/src/models/apiResults.ts +58 -58
  37. package/src/records/field.d.ts +39 -17
  38. package/src/records/field.js +248 -131
  39. package/src/records/field.ts +160 -82
  40. package/src/records/getOperations/recordGetOperation.d.ts +44 -24
  41. package/src/records/getOperations/recordGetOperation.js +88 -61
  42. package/src/records/getOperations/recordGetOperation.ts +128 -108
  43. package/src/records/layoutRecord.d.ts +28 -14
  44. package/src/records/layoutRecord.js +69 -60
  45. package/src/records/layoutRecord.ts +121 -119
  46. package/src/records/layoutRecordBase.d.ts +2 -2
  47. package/src/records/layoutRecordBase.ts +3 -3
  48. package/src/records/portal.d.ts +19 -5
  49. package/src/records/portal.js +19 -5
  50. package/src/records/portal.ts +28 -16
  51. package/src/records/portalBase.d.ts +5 -5
  52. package/src/records/portalBase.ts +6 -6
  53. package/src/records/portalRecord.d.ts +16 -8
  54. package/src/records/portalRecord.js +16 -6
  55. package/src/records/portalRecord.ts +29 -19
  56. package/src/records/recordBase.d.ts +18 -8
  57. package/src/records/recordBase.js +23 -16
  58. package/src/records/recordBase.ts +41 -37
  59. package/src/types.d.ts +23 -30
  60. package/src/types.js +0 -5
  61. package/src/types.ts +55 -64
  62. package/src/utils/query.d.ts +7 -7
  63. package/src/utils/query.js +10 -10
  64. package/src/utils/query.ts +19 -20
@@ -1,8 +1,12 @@
1
- import { Database } from "./database.js";
2
- import { HostBase } from "./HostBase.js";
3
- import { databaseOptionsWithExternalSources, FMHostMetadata, loginOptionsClaris, loginOptionsFileMaker, loginOptionsOAuth } from "../types.js";
4
- import { DatabaseStructure } from "../databaseStructure.js";
5
- import { Moment } from "moment";
1
+ import { Database } from './database.js';
2
+ import { type HostBase } from './HostBase.js';
3
+ import { type databaseOptionsWithExternalSources, type FMHostMetadata, type loginOptionsClaris, type loginOptionsFileMaker, type loginOptionsOAuth } from '../types.js';
4
+ import { type DatabaseStructure } from '../databaseStructure.js';
5
+ import { type Moment } from 'moment';
6
+ /**
7
+ * Represents a FileMaker host.
8
+ * @implements {HostBase}
9
+ */
6
10
  export default class FMHost implements HostBase {
7
11
  readonly hostname: string;
8
12
  readonly timezoneOffsetFunc: (moment: Moment) => number;
@@ -13,7 +17,21 @@ export default class FMHost implements HostBase {
13
17
  get dateFormat(): string;
14
18
  get timeFormat(): string;
15
19
  get timeStampFormat(): string;
20
+ /**
21
+ * Retrieves a list of databases from the FileMaker Server.
22
+ *
23
+ * @param {loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris} [credentials] - Optional credentials required for authentication.
24
+ * @throws {FMError} If the request to the FileMaker Server fails or if the response contains an error.
25
+ * @returns {Promise<any[]>} A promise that resolves to an array of database objects if successful.
26
+ */
16
27
  listDatabases(credentials?: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris): Promise<any>;
28
+ /**
29
+ * Creates a new database connection with the specified options.
30
+ *
31
+ * @template T - The type of the database structure.
32
+ * @param {databaseOptionsWithExternalSources} data - The options for the database, including external sources.
33
+ * @return {Database<T>} A new Database instance.
34
+ */
17
35
  database<T extends DatabaseStructure>(data: databaseOptionsWithExternalSources): Database<T>;
18
36
  getMetadata(): Promise<FMHostMetadata>;
19
37
  }
@@ -1,9 +1,13 @@
1
1
  /*
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
- import { generateAuthorizationHeaders } from "./generateAuthorizationHeaders.js";
5
- import { FMError } from "../FMError.js";
6
- import { Database } from "./database.js";
4
+ import { generateAuthorizationHeaders } from './generateAuthorizationHeaders.js';
5
+ import { FMError } from '../FMError.js';
6
+ import { Database } from './database.js';
7
+ /**
8
+ * Represents a FileMaker host.
9
+ * @implements {HostBase}
10
+ */
7
11
  export default class FMHost {
8
12
  hostname;
9
13
  timezoneOffsetFunc;
@@ -11,71 +15,83 @@ export default class FMHost {
11
15
  _metadata = null;
12
16
  constructor(_hostname, timezoneOffset = (moment) => 0 - (new Date()).getTimezoneOffset(), verify = true) {
13
17
  if (!(/^https?:\/\//).test(_hostname))
14
- throw "hostname MUST begin with either http:// or https://";
18
+ throw new Error('hostname MUST begin with either http:// or https://');
15
19
  this.hostname = _hostname;
16
20
  this.timezoneOffsetFunc = timezoneOffset;
17
21
  this.verify = verify;
18
22
  }
19
23
  get metadata() {
20
- return this._metadata || {
24
+ return this._metadata ?? {
21
25
  productInfo: {
22
26
  buildDate: new Date(),
23
- name: "",
24
- version: "",
25
- dateFormat: "MM/dd/yyyy",
26
- timeFormat: "HH:mm:ss",
27
- timeStampFormat: "MM/dd/yyyy HH:mm:ss"
27
+ name: '',
28
+ version: '',
29
+ dateFormat: 'MM/dd/yyyy',
30
+ timeFormat: 'HH:mm:ss',
31
+ timeStampFormat: 'MM/dd/yyyy HH:mm:ss'
28
32
  }
29
33
  };
30
34
  }
31
35
  get dateFormat() {
32
36
  return this.metadata.productInfo.dateFormat
33
- .replace("dd", "DD")
34
- .replace("yyyy", "YYYY");
37
+ .replace('dd', 'DD')
38
+ .replace('yyyy', 'YYYY');
35
39
  }
36
40
  get timeFormat() { return this.metadata.productInfo.timeFormat; }
37
41
  get timeStampFormat() {
38
42
  return this.metadata.productInfo.timeStampFormat
39
- .replace("dd", "DD")
40
- .replace("yyyy", "YYYY");
43
+ .replace('dd', 'DD')
44
+ .replace('yyyy', 'YYYY');
41
45
  }
46
+ /**
47
+ * Retrieves a list of databases from the FileMaker Server.
48
+ *
49
+ * @param {loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris} [credentials] - Optional credentials required for authentication.
50
+ * @throws {FMError} If the request to the FileMaker Server fails or if the response contains an error.
51
+ * @returns {Promise<any[]>} A promise that resolves to an array of database objects if successful.
52
+ */
42
53
  async listDatabases(credentials) {
43
54
  let headers = {};
44
55
  if (credentials) {
45
56
  headers = generateAuthorizationHeaders(credentials);
46
57
  }
47
- let _fetch = await fetch(`${this.hostname}/fmi/data/v2/databases`, {
48
- method: "GET",
58
+ const _fetch = await fetch(`${this.hostname}/fmi/data/v2/databases`, {
59
+ method: 'GET',
49
60
  headers
50
61
  });
51
- let data = await _fetch.json();
62
+ const data = await _fetch.json();
52
63
  // console.log(data.messages[0])
53
- if (data.messages[0].code === "0" && data.response) {
64
+ if (data.messages[0].code === '0' && data.response) {
54
65
  return data.response.databases;
55
66
  }
56
67
  else {
57
- // @ts-ignore
58
- throw new FMError(data.messages[0].code, data.status, data);
68
+ throw new FMError(data.messages[0].code, _fetch.status, data);
59
69
  }
60
70
  }
71
+ /**
72
+ * Creates a new database connection with the specified options.
73
+ *
74
+ * @template T - The type of the database structure.
75
+ * @param {databaseOptionsWithExternalSources} data - The options for the database, including external sources.
76
+ * @return {Database<T>} A new Database instance.
77
+ */
61
78
  database(data) {
62
79
  return new Database(this, data);
63
80
  }
64
81
  async getMetadata() {
65
82
  if (this._metadata)
66
83
  return this._metadata;
67
- let _fetch = await fetch(`${this.hostname}/fmi/data/v2/productInfo`, {
68
- method: "GET",
84
+ const _fetch = await fetch(`${this.hostname}/fmi/data/v2/productInfo`, {
85
+ method: 'GET'
69
86
  });
70
- let data = await _fetch.json();
87
+ const data = await _fetch.json();
71
88
  // console.log(data.messages[0])
72
- if (data.messages[0].code === "0" && data.response) {
89
+ if (data.messages[0].code === '0' && data.response) {
73
90
  this._metadata = data.response;
74
91
  return data.response;
75
92
  }
76
93
  else {
77
- // @ts-ignore
78
- throw new FMError(data.messages[0].code, data.status, data);
94
+ throw new FMError(data.messages[0].code, _fetch.status, data);
79
95
  }
80
96
  }
81
97
  }
@@ -2,106 +2,120 @@
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import {generateAuthorizationHeaders} from "./generateAuthorizationHeaders.js";
6
- import {FMError} from "../FMError.js";
7
- import {Database} from "./database.js";
8
- import {HostBase} from "./HostBase.js"
5
+ import {generateAuthorizationHeaders} from './generateAuthorizationHeaders.js'
6
+ import {FMError} from '../FMError.js'
7
+ import {Database} from './database.js'
8
+ import {type HostBase} from './HostBase.js'
9
9
  import {
10
- databaseOptionsWithExternalSources,
11
- FMHostMetadata,
12
- loginOptionsClaris,
13
- loginOptionsFileMaker,
14
- loginOptionsOAuth
15
- } from "../types.js";
16
- import {ApiResults} from "../models/apiResults.js";
17
- import {DatabaseStructure} from "../databaseStructure.js";
18
- import {Moment} from "moment";
10
+ type databaseOptionsWithExternalSources,
11
+ type FMHostMetadata,
12
+ type loginOptionsClaris,
13
+ type loginOptionsFileMaker,
14
+ type loginOptionsOAuth
15
+ } from '../types.js'
16
+ import {type ApiResults} from '../models/apiResults.js'
17
+ import {type DatabaseStructure} from '../databaseStructure.js'
18
+ import {type Moment} from 'moment'
19
19
 
20
+ /**
21
+ * Represents a FileMaker host.
22
+ * @implements {HostBase}
23
+ */
20
24
  export default class FMHost implements HostBase {
21
25
  readonly hostname: string
22
26
  readonly timezoneOffsetFunc: (moment: Moment) => number
23
27
  readonly verify: boolean
24
28
  _metadata: FMHostMetadata | null = null
25
29
 
26
- constructor(
30
+ constructor (
27
31
  _hostname: string,
28
32
  timezoneOffset = (moment: Moment) => 0 - (new Date()).getTimezoneOffset(),
29
33
  verify = true
30
34
  ) {
31
- if (!(/^https?:\/\//).test(_hostname)) throw "hostname MUST begin with either http:// or https://"
35
+ if (!(/^https?:\/\//).test(_hostname)) throw new Error('hostname MUST begin with either http:// or https://')
32
36
  this.hostname = _hostname
33
37
  this.timezoneOffsetFunc = timezoneOffset
34
38
  this.verify = verify
35
39
  }
36
40
 
37
- get metadata(): FMHostMetadata {
38
- return this._metadata || {
41
+ get metadata (): FMHostMetadata {
42
+ return this._metadata ?? {
39
43
  productInfo: {
40
44
  buildDate: new Date(),
41
- name: "",
42
- version: "",
43
- dateFormat: "MM/dd/yyyy",
44
- timeFormat: "HH:mm:ss",
45
- timeStampFormat: "MM/dd/yyyy HH:mm:ss"
45
+ name: '',
46
+ version: '',
47
+ dateFormat: 'MM/dd/yyyy',
48
+ timeFormat: 'HH:mm:ss',
49
+ timeStampFormat: 'MM/dd/yyyy HH:mm:ss'
46
50
  }
47
- };
51
+ }
48
52
  }
49
53
 
50
- get dateFormat() {
54
+ get dateFormat () {
51
55
  return this.metadata.productInfo.dateFormat
52
- .replace("dd", "DD")
53
- .replace("yyyy", "YYYY")
56
+ .replace('dd', 'DD')
57
+ .replace('yyyy', 'YYYY')
54
58
  }
55
59
 
56
- get timeFormat() {return this.metadata.productInfo.timeFormat}
57
- get timeStampFormat() {
60
+ get timeFormat () { return this.metadata.productInfo.timeFormat }
61
+ get timeStampFormat () {
58
62
  return this.metadata.productInfo.timeStampFormat
59
- .replace("dd", "DD")
60
- .replace("yyyy", "YYYY")
63
+ .replace('dd', 'DD')
64
+ .replace('yyyy', 'YYYY')
61
65
  }
62
66
 
63
- async listDatabases(credentials?: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris) {
67
+ /**
68
+ * Retrieves a list of databases from the FileMaker Server.
69
+ *
70
+ * @param {loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris} [credentials] - Optional credentials required for authentication.
71
+ * @throws {FMError} If the request to the FileMaker Server fails or if the response contains an error.
72
+ * @returns {Promise<any[]>} A promise that resolves to an array of database objects if successful.
73
+ */
74
+ async listDatabases (credentials?: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris) {
64
75
  let headers = {}
65
76
  if (credentials) {
66
77
  headers = generateAuthorizationHeaders(credentials)
67
78
  }
68
79
 
69
- let _fetch = await fetch(`${this.hostname}/fmi/data/v2/databases`, {
70
- method: "GET",
80
+ const _fetch = await fetch(`${this.hostname}/fmi/data/v2/databases`, {
81
+ method: 'GET',
71
82
  headers
72
83
  })
73
- let data = await _fetch.json() as ApiResults<{databases: any}>
84
+ const data = await _fetch.json() as ApiResults<{ databases: any }>
74
85
  // console.log(data.messages[0])
75
86
 
76
- if (data.messages[0].code === "0" && data.response) {
87
+ if (data.messages[0].code === '0' && data.response) {
77
88
  return data.response.databases
78
- }
79
- else {
80
- // @ts-ignore
81
- throw new FMError(data.messages[0].code, data.status, data)
89
+ } else {
90
+ throw new FMError(data.messages[0].code, _fetch.status, data)
82
91
  }
83
92
  }
84
93
 
94
+ /**
95
+ * Creates a new database connection with the specified options.
96
+ *
97
+ * @template T - The type of the database structure.
98
+ * @param {databaseOptionsWithExternalSources} data - The options for the database, including external sources.
99
+ * @return {Database<T>} A new Database instance.
100
+ */
85
101
  database<T extends DatabaseStructure>(data: databaseOptionsWithExternalSources) {
86
102
  return new Database<T>(this, data)
87
103
  }
88
104
 
89
- async getMetadata() {
105
+ async getMetadata () {
90
106
  if (this._metadata) return this._metadata
91
107
 
92
- let _fetch = await fetch(`${this.hostname}/fmi/data/v2/productInfo`, {
93
- method: "GET",
108
+ const _fetch = await fetch(`${this.hostname}/fmi/data/v2/productInfo`, {
109
+ method: 'GET'
94
110
  })
95
- let data = await _fetch.json() as ApiResults<FMHostMetadata>
111
+ const data = await _fetch.json() as ApiResults<FMHostMetadata>
96
112
  // console.log(data.messages[0])
97
113
 
98
- if (data.messages[0].code === "0" && data.response) {
114
+ if (data.messages[0].code === '0' && data.response) {
99
115
  this._metadata = data.response
100
116
  return data.response
101
- }
102
- else {
103
- // @ts-ignore
104
- throw new FMError(data.messages[0].code, data.status, data)
117
+ } else {
118
+ throw new FMError(data.messages[0].code, _fetch.status, data)
105
119
  }
106
120
  }
107
- }
121
+ }
@@ -1,11 +1,11 @@
1
- import { FMHostMetadata } from "../types.js";
2
- import { Moment } from "moment";
1
+ import { type FMHostMetadata } from '../types.js';
2
+ import { type Moment } from 'moment';
3
3
  export interface HostBase {
4
4
  readonly hostname: string;
5
5
  readonly timezoneOffsetFunc: (moment: Moment) => number;
6
6
  readonly verify: boolean;
7
7
  metadata: FMHostMetadata;
8
- getMetadata(): PromiseLike<any>;
8
+ getMetadata: () => PromiseLike<any>;
9
9
  timeFormat: string;
10
10
  dateFormat: string;
11
11
  timeStampFormat: string;
@@ -2,16 +2,16 @@
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import {FMHostMetadata} from "../types.js";
6
- import {Moment} from "moment";
5
+ import {type FMHostMetadata} from '../types.js'
6
+ import {type Moment} from 'moment'
7
7
 
8
8
  export interface HostBase {
9
9
  readonly hostname: string
10
- readonly timezoneOffsetFunc: (moment: Moment) => number,
10
+ readonly timezoneOffsetFunc: (moment: Moment) => number
11
11
  readonly verify: boolean
12
12
  metadata: FMHostMetadata
13
- getMetadata(): PromiseLike<any>
13
+ getMetadata: () => PromiseLike<any>
14
14
  timeFormat: string
15
15
  dateFormat: string
16
16
  timeStampFormat: string
17
- }
17
+ }
@@ -1,33 +1,66 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- import { EventEmitter } from "events";
4
- import { LayoutInterface } from "../layouts/layoutInterface.js";
5
- import { Layout } from "../layouts/layout.js";
6
- import { databaseOptionsWithExternalSources, Script } from "../types.js";
7
- import { HostBase } from "./HostBase.js";
8
- import { DatabaseBase } from "./databaseBase.js";
9
- import { ApiResults } from "../models/apiResults.js";
10
- import { DatabaseStructure } from "../databaseStructure.js";
11
- import { IncomingMessage } from "http";
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import { type LayoutInterface } from '../layouts/layoutInterface.js';
4
+ import { Layout } from '../layouts/layout.js';
5
+ import { type databaseOptionsWithExternalSources, type Script } from '../types.js';
6
+ import { type HostBase } from './HostBase.js';
7
+ import { type DatabaseBase } from './databaseBase.js';
8
+ import { type ApiResults } from '../models/apiResults.js';
9
+ import { type DatabaseStructure } from '../databaseStructure.js';
10
+ import { RequestInfo, RequestInit, Response } from 'node-fetch';
11
+ /**
12
+ * Represents a database connection.
13
+ * @template T - The structure of the database.
14
+ */
12
15
  export declare class Database<T extends DatabaseStructure> extends EventEmitter implements DatabaseBase {
13
16
  private _token;
14
17
  readonly host: HostBase;
15
- private connection_details;
18
+ private readonly connection_details;
16
19
  private cookies;
17
20
  readonly name: string;
18
21
  readonly debug: boolean;
19
22
  constructor(host: HostBase, conn: databaseOptionsWithExternalSources);
20
23
  private generateExternalSourceLogin;
24
+ /**
25
+ * Logs out the user by deleting the current session token.
26
+ * Throws an error if the user is not logged in.
27
+ *
28
+ * @returns {Promise<void>} A promise that resolves with no value once the logout is successful.
29
+ * @throws {Error} Throws an error if the user is not logged in.
30
+ */
21
31
  logout(): Promise<void>;
22
- login(forceLogin?: boolean): Promise<any>;
23
- get token(): any;
32
+ /**
33
+ * Logs in to the database. Not required, as this is often done automatically
34
+ *
35
+ * @param {boolean} [forceLogin=false] - Whether to force login even if already logged in.
36
+ * @throws {Error} - Throws an error if already logged in and forceLogin is false.
37
+ * @throws {FMError} - Throws an FMError if login fails.
38
+ * @return {Promise<string>} - Returns a promise that resolves to the access token upon successful login.
39
+ */
40
+ login(forceLogin?: boolean): Promise<string | undefined>;
41
+ get token(): string;
42
+ /**
43
+ * Returns the endpoint URL for the database connection.
44
+ *
45
+ * @returns {string} The endpoint URL.
46
+ */
24
47
  get endpoint(): string;
25
- apiRequestRaw(url: string | Request, options?: any, autoRelogin?: boolean): Promise<Response>;
26
- apiRequestJSON<T = any>(url: string | Request, options?: any): Promise<ApiResults<T>>;
48
+ _apiRequestRaw(url: URL | RequestInfo, options?: RequestInit & {
49
+ headers?: Record<string, string>;
50
+ useCookieJar?: boolean;
51
+ }, autoRelogin?: boolean): Promise<Response>;
52
+ private _generateCookieHeader;
53
+ _apiRequestJSON<T = any>(url: URL | RequestInfo, options?: RequestInit & {
54
+ headers?: Record<string, string>;
55
+ }): Promise<ApiResults<T>>;
56
+ /**
57
+ * Retrieves a list of layouts in the current FileMaker database.
58
+ *
59
+ * @returns {Promise<Layout[]>} A promise that resolves to an array of Layout objects.
60
+ * @throws {FMError} If there was an error retrieving the layouts.
61
+ */
27
62
  listLayouts(): Promise<Layout<LayoutInterface>[]>;
28
- getLayout<R extends keyof T["layouts"]>(name: R): Layout<T["layouts"][R]>;
29
- getLayout<R extends LayoutInterface>(name: string): Layout<R>;
63
+ layout<R extends keyof T['layouts']>(name: R): Layout<T['layouts'][R]>;
64
+ layout<R extends LayoutInterface>(name: string): Layout<R>;
30
65
  script(name: string, parameter?: string): Script;
31
- _tokenExpired(): void;
32
- streamURL(url: string): Promise<IncomingMessage>;
33
66
  }