@mastra/pg 1.19.0-alpha.1 → 1.19.0-alpha.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # @mastra/pg
2
2
 
3
+ ## 1.19.0-alpha.2
4
+
5
+ ### Minor Changes
6
+
7
+ - Stored workflow definitions now persist across restarts on every major database backend. ([#20471](https://github.com/mastra-ai/mastra/pull/20471))
8
+
9
+ Implement the `workflowDefinitions` storage domain for libsql, pg, mysql, mssql, mongodb, and spanner. Previously the stored-workflow persistence path (`POST /stored/workflows`, `Mastra.addStoredWorkflow`) only worked against `@mastra/core`'s in-memory store. Persistent adapters returned `undefined` from `storage.getStore('workflowDefinitions')` and threw when the HTTP handler tried to read/write a workflow.
10
+
11
+ ```ts
12
+ const workflowDefinitions = await storage.getStore('workflowDefinitions');
13
+ if (!workflowDefinitions) {
14
+ throw new Error('This storage adapter does not support the workflowDefinitions domain');
15
+ }
16
+
17
+ await workflowDefinitions.upsert({
18
+ id: 'greeting-workflow',
19
+ inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
20
+ outputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'] },
21
+ graph: [{ type: 'agent', id: 'greet', agentId: 'greeter-agent' }],
22
+ });
23
+
24
+ const { definitions, total } = await workflowDefinitions.list({ status: 'active' });
25
+ const definition = await workflowDefinitions.get('greeting-workflow');
26
+ await workflowDefinitions.delete('greeting-workflow');
27
+ ```
28
+
29
+ Each adapter now ships a `WorkflowDefinitions*` domain that:
30
+
31
+ - Creates the shared `mastra_workflow_definitions` table (or Mongo collection) from `WORKFLOW_DEFINITIONS_SCHEMA` during `init()`, plus a default index on `status`.
32
+ - Implements `upsert` / `get` / `list` / `delete` matching `WorkflowDefinitionsStorage` semantics (`list` supports `status` and `authorId` filters and orders by `updatedAt` desc). Partial upserts preserve unspecified fields, including `authorId` updates and `createdAt` / `updatedAt` semantics.
33
+ - Handles concurrent first-writes race-safely: if two callers upsert the same new id simultaneously, the losing insert detects the duplicate key, re-reads the row, and applies the partial-update path instead of failing.
34
+ - Round-trips the JSON columns (`inputSchema`, `outputSchema`, `stateSchema`, `requestContextSchema`, `metadata`, `graph`) through each adapter's JSON handling, so declarative workflow graphs rehydrate identically no matter which backend they were stored in. Malformed persisted JSON surfaces as an actionable error naming the row and column instead of hydrating raw strings.
35
+
36
+ Exported class names by adapter: `WorkflowDefinitionsLibSQL`, `WorkflowDefinitionsPG`, `WorkflowDefinitionsMySQL`, `WorkflowDefinitionsMSSQL`, `MongoDBWorkflowDefinitionsStore`, `WorkflowDefinitionsSpanner`. The composite stores (`LibSQLStore`, `PostgresStore`, `MySQLStore`, `MSSQLStore`, `MongoDBStore`, `SpannerStore`) auto-wire the new domain, so callers do not need to construct it manually — `storage.getStore('workflowDefinitions')` now returns a live handle.
37
+
38
+ The pg adapter reads `createdAt` / `updatedAt` from the auto-added `createdAtZ` / `updatedAtZ` `timestamptz` companion columns to avoid the naive-timestamp / local-TZ drift that a plain `TIMESTAMP` read exhibits under node-pg.
39
+
40
+ `@mastra/clickhouse` and `@mastra/cloudflare` register the new `mastra_workflow_definitions` table in their table/type maps so shared table constants stay exhaustive (no workflow-definitions domain implementation yet).
41
+
42
+ ### Patch Changes
43
+
44
+ - Updated dependencies [[`4844167`](https://github.com/mastra-ai/mastra/commit/4844167cff2d5ec5004e94edd34970833040fa3f), [`5faf93f`](https://github.com/mastra-ai/mastra/commit/5faf93f03e19daea394b9e2a923f2e4f833407f2), [`80ad891`](https://github.com/mastra-ai/mastra/commit/80ad891f8cd10379aa5b5af7510c763783b2ab56), [`a1cb98d`](https://github.com/mastra-ai/mastra/commit/a1cb98d11990b560b98482292a1f34aa1a2d9092), [`598ad82`](https://github.com/mastra-ai/mastra/commit/598ad82d41c41389a686338a1d0e50b7400e1938), [`1fd6aad`](https://github.com/mastra-ai/mastra/commit/1fd6aad1ea4a9d32f65efa832307c35e981a4c0a)]:
45
+ - @mastra/core@1.56.0-alpha.4
46
+
3
47
  ## 1.19.0-alpha.1
4
48
 
5
49
  ### Patch Changes
@@ -3,7 +3,7 @@ name: mastra-pg
3
3
  description: Documentation for @mastra/pg. Use when working with @mastra/pg APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/pg"
6
- version: "1.19.0-alpha.1"
6
+ version: "1.19.0-alpha.2"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.19.0-alpha.1",
2
+ "version": "1.19.0-alpha.2",
3
3
  "package": "@mastra/pg",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -17,7 +17,7 @@ Workers matter when any of these apply:
17
17
  - Different parts of the system need to scale independently (e.g., more orchestration capacity without more API instances)
18
18
  - Background tool calls should run on dedicated compute
19
19
 
20
- If your application handles light traffic and workflows complete quickly, the default in-process setup works fine. Skip the worker infrastructure until you need it.
20
+ If your application handles light traffic and workflows complete fast, the default in-process setup works fine. Skip the worker infrastructure until you need it.
21
21
 
22
22
  ## Worker types
23
23
 
@@ -33,11 +33,11 @@ The orchestration worker requires a PubSub backend that supports pull mode (e.g.
33
33
 
34
34
  ### Scheduler worker
35
35
 
36
- Polls storage for due cron schedules and publishes `workflow.start` events. It is a producer only, meaning it creates work for the orchestration worker to pick up.
36
+ Polls storage for due cron schedules and publishes `workflow.start` events. It's a producer only, meaning it creates work for the orchestration worker to pick up.
37
37
 
38
38
  The scheduler reads declarative `schedule` fields from your workflow definitions automatically. See [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows) for how to declare schedules.
39
39
 
40
- **Do not run more than one scheduler instance.** Multiple schedulers polling the same storage would fire duplicate events for the same schedule.
40
+ **Don't run more than one scheduler instance.** Multiple schedulers polling the same storage would fire duplicate events for the same schedule.
41
41
 
42
42
  ### Background task worker
43
43
 
@@ -47,7 +47,7 @@ The background task worker manages concurrency limits, task lifecycle, and resul
47
47
 
48
48
  ## How workers run
49
49
 
50
- ### In-process (default)
50
+ ### In-process mode (default)
51
51
 
52
52
  With no configuration, Mastra creates and starts workers inside the API process. Events flow through an in-memory PubSub, and everything shares a single Node.js runtime.
53
53
 
@@ -64,7 +64,7 @@ This setup needs no external infrastructure beyond your storage adapter. It does
64
64
 
65
65
  ### Split processes
66
66
 
67
- To run workers separately, configure a distributed [PubSub](https://mastra.ai/docs/server/pubsub) backend and use the `MASTRA_WORKERS` environment variable to control which workers start in each process.
67
+ To run workers in their own processes, configure a distributed [PubSub](https://mastra.ai/docs/server/pubsub) backend and use the `MASTRA_WORKERS` environment variable to control which workers start in each process.
68
68
 
69
69
  **Redis Streams + PostgreSQL**:
70
70
 
@@ -100,38 +100,38 @@ export const mastra = new Mastra({
100
100
  })
101
101
  ```
102
102
 
103
- Any [supported storage backend](https://mastra.ai/reference/workers/overview) works swap the storage adapter for your preferred database.
103
+ Any [supported storage backend](https://mastra.ai/reference/workers/overview) works. Swap the storage adapter for your preferred database.
104
104
 
105
105
  Run the same build artifact in multiple containers, each with a different [`MASTRA_WORKERS`](https://mastra.ai/reference/workers/overview) value to control which worker starts in each process.
106
106
 
107
107
  Split deployments require a distributed PubSub backend ([`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) or [`GoogleCloudPubSub`](https://mastra.ai/reference/pubsub/google-cloud-pubsub)), a shared [storage backend](https://mastra.ai/reference/workers/overview), and network connectivity between the orchestration worker and the API.
108
108
 
109
- The [worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers) walks through this setup with a Docker Compose example.
109
+ The [worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers) walks through this setup with Docker Compose and Kubernetes examples.
110
110
 
111
111
  ## Network architecture
112
112
 
113
- Workers are internal infrastructure. They are not exposed to end users and do not need their own subdomain, public URL, or inbound HTTP route.
113
+ Workers are internal infrastructure. They're not exposed to end users and don't need their own subdomain, public URL, or inbound HTTP route.
114
114
 
115
115
  In a split deployment:
116
116
 
117
- - **The API server is the only public-facing process.** It serves all client HTTP requests REST endpoints, agent interactions, workflow triggers, and any custom routes.
118
- - **Workers connect outbound only.** They pull events from the distributed PubSub backend and read/write to the shared storage database. They do not accept inbound traffic from clients.
119
- - **The orchestration worker calls the API internally.** It sends step execution requests to the API over the container network using `MASTRA_STEP_EXECUTION_URL`. This is internal service-to-service communication, not a public endpoint.
117
+ - **The API server is the only public-facing process**: It serves all client HTTP requests, including REST endpoints, agent interactions, workflow triggers, and any custom routes.
118
+ - **Workers connect outbound only**: They pull events from the distributed PubSub backend and read/write to the shared storage database. They don't accept inbound traffic from clients.
119
+ - **The orchestration worker calls the API internally**: It sends step execution requests to the API over the container network using `MASTRA_STEP_EXECUTION_URL`. This is internal service-to-service communication, not a public endpoint.
120
120
 
121
121
  All three worker types (orchestration, scheduler, background task) sit behind the API on a private network. They share access to the PubSub backend and storage database but never receive traffic directly from clients. If a worker-related feature needs an HTTP route (for example, token minting for a voice integration), that route runs on the API server, not on the worker process.
122
122
 
123
123
  ## Known limitations
124
124
 
125
- - **No dead-letter queue**: Failed events are nacked and retried, but there is no DLQ for events that repeatedly fail.
125
+ - **No dead-letter queue**: Failed events are nacked and retried, but there's no DLQ for events that fail after all retries.
126
126
  - **No built-in health endpoint**: Workers don't expose an HTTP health check. Use container-level liveness probes or process monitoring.
127
127
  - **Scheduler is single-instance**: Running multiple scheduler processes causes duplicate schedule fires.
128
128
  - **Runs stuck in "running" after API crash**: If the API process crashes while executing a workflow step, the run remains in `running` status with no automatic retry. For [durable agents](https://mastra.ai/docs/long-running-agents/durable-agents), set `recovery.durableAgents` to `'auto'` in the Mastra config to automatically re-drive orphaned runs on server restart. See [Crash recovery](https://mastra.ai/docs/long-running-agents/durable-agents) for details.
129
129
 
130
130
  ## Related
131
131
 
132
- - [Worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers): Docker Compose example and topology options
132
+ - [Worker deployment guide](https://mastra.ai/guides/deployment/mastra-workers): Docker Compose and Kubernetes examples
133
133
  - [Worker authentication](https://mastra.ai/docs/server/auth/workers): Secure worker-to-API communication
134
- - [Workers reference](https://mastra.ai/reference/workers/overview): Environment variables, worker types, and storage backends
134
+ - [Workers reference](https://mastra.ai/reference/workers/overview): Details about worker environment variables and types, with a list of supported storage backends
135
135
  - [CLI reference](https://mastra.ai/reference/cli/mastra): `mastra worker build` and `mastra worker start`
136
136
  - [PubSub](https://mastra.ai/docs/server/pubsub): Event delivery backends
137
137
  - [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows): Declare cron schedules on workflows
package/dist/index.cjs CHANGED
@@ -18772,6 +18772,187 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends _mastra_
18772
18772
  }
18773
18773
  };
18774
18774
  //#endregion
18775
+ //#region src/storage/domains/workflow-definitions/index.ts
18776
+ function rowToDefinition(row) {
18777
+ const inputSchema = parseJsonResilient(row.inputSchema);
18778
+ const outputSchema = parseJsonResilient(row.outputSchema);
18779
+ const graph = parseJsonResilient(row.graph);
18780
+ if (inputSchema === void 0 || outputSchema === void 0 || graph === void 0) throw new Error(`Workflow definition row "${String(row.id)}" is missing required JSON columns.`);
18781
+ const def = {
18782
+ id: String(row.id),
18783
+ inputSchema,
18784
+ outputSchema,
18785
+ graph,
18786
+ status: String(row.status),
18787
+ source: String(row.source),
18788
+ createdAt: new Date(row.createdAtZ ?? row.createdAt),
18789
+ updatedAt: new Date(row.updatedAtZ ?? row.updatedAt)
18790
+ };
18791
+ if (row.description != null) def.description = String(row.description);
18792
+ const metadata = parseJsonResilient(row.metadata);
18793
+ if (metadata !== void 0 && metadata !== null) def.metadata = metadata;
18794
+ const stateSchema = parseJsonResilient(row.stateSchema);
18795
+ if (stateSchema !== void 0 && stateSchema !== null) def.stateSchema = stateSchema;
18796
+ const requestContextSchema = parseJsonResilient(row.requestContextSchema);
18797
+ if (requestContextSchema !== void 0 && requestContextSchema !== null) def.requestContextSchema = requestContextSchema;
18798
+ if (row.authorId != null) def.authorId = String(row.authorId);
18799
+ return def;
18800
+ }
18801
+ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends _mastra_core_storage.WorkflowDefinitionsStorage {
18802
+ #db;
18803
+ #schema;
18804
+ #skipDefaultIndexes;
18805
+ #indexes;
18806
+ static MANAGED_TABLES = [_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS];
18807
+ constructor(config) {
18808
+ super();
18809
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18810
+ this.#db = new PgDB({
18811
+ client,
18812
+ schemaName,
18813
+ skipDefaultIndexes
18814
+ });
18815
+ this.#schema = schemaName || "public";
18816
+ this.#skipDefaultIndexes = skipDefaultIndexes;
18817
+ this.#indexes = indexes?.filter((idx) => WorkflowDefinitionsPG.MANAGED_TABLES.includes(idx.table));
18818
+ }
18819
+ static getExportDDL(schemaName) {
18820
+ return [generateTableSQL({
18821
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18822
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS],
18823
+ schemaName,
18824
+ includeAllConstraints: true
18825
+ })];
18826
+ }
18827
+ getDefaultIndexDefinitions() {
18828
+ return [{
18829
+ name: `${this.#schema !== "public" ? `${this.#schema}_` : ""}idx_workflow_definitions_status`,
18830
+ table: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18831
+ columns: ["status"]
18832
+ }];
18833
+ }
18834
+ async createDefaultIndexes() {
18835
+ if (this.#skipDefaultIndexes) return;
18836
+ for (const indexDef of this.getDefaultIndexDefinitions()) try {
18837
+ await this.#db.createIndex(indexDef);
18838
+ } catch (error) {
18839
+ this.logger?.warn?.(`Failed to create index ${indexDef.name}:`, error);
18840
+ }
18841
+ }
18842
+ async createCustomIndexes() {
18843
+ if (!this.#indexes || this.#indexes.length === 0) return;
18844
+ for (const indexDef of this.#indexes) try {
18845
+ await this.#db.createIndex(indexDef);
18846
+ } catch (error) {
18847
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
18848
+ }
18849
+ }
18850
+ async init() {
18851
+ await this.#db.createTable({
18852
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18853
+ schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS]
18854
+ });
18855
+ await this.createDefaultIndexes();
18856
+ await this.createCustomIndexes();
18857
+ }
18858
+ async dangerouslyClearAll() {
18859
+ await this.#db.clearTable({ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS });
18860
+ }
18861
+ async upsert(input) {
18862
+ const now = /* @__PURE__ */ new Date();
18863
+ if (!await this.get(input.id)) {
18864
+ if (!("inputSchema" in input) || !input.inputSchema) throw new Error(`Cannot create workflow definition "${input.id}": inputSchema is required.`);
18865
+ if (!("outputSchema" in input) || !input.outputSchema) throw new Error(`Cannot create workflow definition "${input.id}": outputSchema is required.`);
18866
+ if (!("graph" in input) || !input.graph) throw new Error(`Cannot create workflow definition "${input.id}": graph is required.`);
18867
+ const record = {
18868
+ id: input.id,
18869
+ description: input.description ?? null,
18870
+ metadata: input.metadata ?? null,
18871
+ inputSchema: input.inputSchema,
18872
+ outputSchema: input.outputSchema,
18873
+ stateSchema: input.stateSchema ?? null,
18874
+ requestContextSchema: input.requestContextSchema ?? null,
18875
+ graph: input.graph,
18876
+ status: "active",
18877
+ source: "storage",
18878
+ authorId: "authorId" in input ? input.authorId ?? null : null,
18879
+ createdAt: now,
18880
+ updatedAt: now
18881
+ };
18882
+ try {
18883
+ await this.#db.insert({
18884
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18885
+ record
18886
+ });
18887
+ } catch (error) {
18888
+ if (!await this.get(input.id)) throw error;
18889
+ return this.applyUpdate(input, now);
18890
+ }
18891
+ const created = await this.get(input.id);
18892
+ if (!created) throw new Error(`Failed to persist workflow definition "${input.id}".`);
18893
+ return created;
18894
+ }
18895
+ return this.applyUpdate(input, now);
18896
+ }
18897
+ async applyUpdate(input, now) {
18898
+ const data = { updatedAt: now };
18899
+ if ("description" in input && input.description !== void 0) data.description = input.description;
18900
+ if ("metadata" in input && input.metadata !== void 0) data.metadata = input.metadata;
18901
+ if ("inputSchema" in input && input.inputSchema !== void 0) data.inputSchema = input.inputSchema;
18902
+ if ("outputSchema" in input && input.outputSchema !== void 0) data.outputSchema = input.outputSchema;
18903
+ if ("stateSchema" in input && input.stateSchema !== void 0) data.stateSchema = input.stateSchema;
18904
+ if ("requestContextSchema" in input && input.requestContextSchema !== void 0) data.requestContextSchema = input.requestContextSchema;
18905
+ if ("graph" in input && input.graph !== void 0) data.graph = input.graph;
18906
+ if ("status" in input && input.status !== void 0) data.status = input.status;
18907
+ if ("authorId" in input && input.authorId !== void 0) data.authorId = input.authorId;
18908
+ await this.#db.update({
18909
+ tableName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18910
+ keys: { id: input.id },
18911
+ data
18912
+ });
18913
+ const updated = await this.get(input.id);
18914
+ if (!updated) throw new Error(`Failed to update workflow definition "${input.id}".`);
18915
+ return updated;
18916
+ }
18917
+ async get(id) {
18918
+ const tableName = getTableName$5({
18919
+ indexName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18920
+ schemaName: getSchemaName$5(this.#schema)
18921
+ });
18922
+ const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
18923
+ return row ? rowToDefinition(row) : null;
18924
+ }
18925
+ async list(args) {
18926
+ const tableName = getTableName$5({
18927
+ indexName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18928
+ schemaName: getSchemaName$5(this.#schema)
18929
+ });
18930
+ const conditions = [];
18931
+ const params = [];
18932
+ if (args?.status) {
18933
+ params.push(args.status);
18934
+ conditions.push(`"status" = $${params.length}`);
18935
+ }
18936
+ if (args?.authorId !== void 0) {
18937
+ params.push(args.authorId);
18938
+ conditions.push(`"authorId" = $${params.length}`);
18939
+ }
18940
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
18941
+ const definitions = (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${where} ORDER BY "updatedAt" DESC`, params)).map((row) => rowToDefinition(row));
18942
+ return {
18943
+ definitions,
18944
+ total: definitions.length
18945
+ };
18946
+ }
18947
+ async delete(id) {
18948
+ const tableName = getTableName$5({
18949
+ indexName: _mastra_core_storage.TABLE_WORKFLOW_DEFINITIONS,
18950
+ schemaName: getSchemaName$5(this.#schema)
18951
+ });
18952
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE "id" = $1`, [id]);
18953
+ }
18954
+ };
18955
+ //#endregion
18775
18956
  //#region src/storage/domains/workflows/index.ts
18776
18957
  function getSchemaName(schema) {
18777
18958
  return schema ? `"${schema}"` : "\"public\"";
@@ -20264,6 +20445,7 @@ const ALL_DOMAINS = [
20264
20445
  BlobsPG,
20265
20446
  ToolProviderConnectionsPG,
20266
20447
  WorkflowsPG,
20448
+ WorkflowDefinitionsPG,
20267
20449
  DatasetsPG,
20268
20450
  ExperimentsPG,
20269
20451
  BackgroundTasksPG,
@@ -20345,6 +20527,7 @@ var PostgresStore = class extends _mastra_core_storage.MastraCompositeStore {
20345
20527
  this.stores = {
20346
20528
  scores: new ScoresPG(domainConfig),
20347
20529
  workflows: new WorkflowsPG(domainConfig),
20530
+ workflowDefinitions: new WorkflowDefinitionsPG(domainConfig),
20348
20531
  memory: new MemoryPG(domainConfig),
20349
20532
  notifications: new NotificationsPG(domainConfig),
20350
20533
  observability: new ObservabilityPG(domainConfig),
@@ -20694,6 +20877,7 @@ exports.ScorerDefinitionsPG = ScorerDefinitionsPG;
20694
20877
  exports.ScoresPG = ScoresPG;
20695
20878
  exports.SkillsPG = SkillsPG;
20696
20879
  exports.ToolProviderConnectionsPG = ToolProviderConnectionsPG;
20880
+ exports.WorkflowDefinitionsPG = WorkflowDefinitionsPG;
20697
20881
  exports.WorkflowsPG = WorkflowsPG;
20698
20882
  exports.WorkspacesPG = WorkspacesPG;
20699
20883
  exports.exportSchemas = exportSchemas;