@powerhousedao/switchboard 5.0.0-staging.8 → 5.0.1-staging.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/.env +1 -1
- package/Auth.md +396 -0
- package/CHANGELOG.md +418 -0
- package/README.md +15 -14
- package/dist/src/clients/redis.d.ts +1 -1
- package/dist/src/clients/redis.d.ts.map +1 -1
- package/dist/src/clients/redis.js.map +1 -1
- package/dist/src/config.js +1 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/feature-flags.d.ts +4 -0
- package/dist/src/feature-flags.d.ts.map +1 -0
- package/dist/src/feature-flags.js +17 -0
- package/dist/src/feature-flags.js.map +1 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/server.d.ts +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +89 -33
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +9 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/gen-doc-model-type-defs.d.ts +1 -1
- package/dist/src/utils/gen-doc-model-type-defs.d.ts.map +1 -1
- package/dist/src/utils/gen-doc-model-type-defs.js +14 -13
- package/dist/src/utils/gen-doc-model-type-defs.js.map +1 -1
- package/dist/src/utils.d.ts +2 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +4 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -21
- package/tsconfig.json +16 -2
package/dist/src/server.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { VitePackageLoader, startViteServer, } from "@powerhousedao/reactor-api
|
|
2
|
+
import { EventBus, InMemoryJobTracker, InMemoryQueue, Reactor, ReactorClientBuilder, ReadModelCoordinator, } from "@powerhousedao/reactor";
|
|
3
|
+
import { VitePackageLoader, startAPI, startViteServer, } from "@powerhousedao/reactor-api";
|
|
4
4
|
import * as Sentry from "@sentry/node";
|
|
5
|
-
import { InMemoryCache, ReactorBuilder, driveDocumentModelModule, } from "document-drive";
|
|
6
|
-
import RedisCache from "document-drive/cache/redis";
|
|
7
|
-
import { DocumentAlreadyExistsError } from "document-drive/server/error";
|
|
5
|
+
import { DocumentAlreadyExistsError, InMemoryCache, ReactorBuilder, RedisCache, childLogger, driveDocumentModelModule, } from "document-drive";
|
|
8
6
|
import { FilesystemStorage } from "document-drive/storage/filesystem";
|
|
9
7
|
import { PrismaStorageFactory } from "document-drive/storage/prisma";
|
|
10
|
-
import { documentModelDocumentModelModule
|
|
8
|
+
import { documentModelDocumentModelModule } from "document-model";
|
|
11
9
|
import dotenv from "dotenv";
|
|
12
10
|
import express from "express";
|
|
13
11
|
import path from "path";
|
|
14
12
|
import { initRedis } from "./clients/redis.js";
|
|
13
|
+
import { initFeatureFlags, isDualActionCreateEnabled, isReactorv2Enabled, } from "./feature-flags.js";
|
|
15
14
|
import { initProfilerFromEnv } from "./profiler.js";
|
|
16
|
-
import { addDefaultDrive } from "./utils.js";
|
|
15
|
+
import { addDefaultDrive, isPostgresUrl } from "./utils.js";
|
|
16
|
+
const logger = childLogger(["switchboard"]);
|
|
17
17
|
dotenv.config();
|
|
18
18
|
// Create a monolith express app for all subgraphs
|
|
19
19
|
const app = express();
|
|
20
20
|
if (process.env.SENTRY_DSN) {
|
|
21
|
-
|
|
21
|
+
logger.info("Initialized Sentry with env:", process.env.SENTRY_ENV);
|
|
22
22
|
Sentry.init({
|
|
23
23
|
dsn: process.env.SENTRY_DSN,
|
|
24
24
|
environment: process.env.SENTRY_ENV,
|
|
@@ -26,8 +26,49 @@ if (process.env.SENTRY_DSN) {
|
|
|
26
26
|
Sentry.setupExpressErrorHandler(app);
|
|
27
27
|
}
|
|
28
28
|
const DEFAULT_PORT = process.env.PORT ? Number(process.env.PORT) : 4001;
|
|
29
|
+
async function initPrismaStorage(connectionString, cache) {
|
|
30
|
+
try {
|
|
31
|
+
const prismaFactory = new PrismaStorageFactory(connectionString, cache);
|
|
32
|
+
await prismaFactory.checkConnection();
|
|
33
|
+
return prismaFactory.build();
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
const prismaConnectError = "Can't reach database server at";
|
|
37
|
+
if (e instanceof Error && e.message.includes(prismaConnectError)) {
|
|
38
|
+
const dbUrl = connectionString;
|
|
39
|
+
const safeUrl = `${dbUrl.slice(0, dbUrl.indexOf(":") + 1)}{...}${dbUrl.slice(dbUrl.indexOf("@"), dbUrl.lastIndexOf("?"))}`;
|
|
40
|
+
logger.warn(`Can't reach database server at '${safeUrl}'`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
logger.error(e);
|
|
44
|
+
}
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function initReactorStorage(cache, dbPath = "./.ph/drive-storage") {
|
|
49
|
+
const isPostgres = isPostgresUrl(dbPath);
|
|
50
|
+
try {
|
|
51
|
+
if (isPostgres) {
|
|
52
|
+
const connectionString = dbPath.includes("amazonaws") && !dbPath.includes("sslmode=no-verify")
|
|
53
|
+
? dbPath + "?sslmode=no-verify"
|
|
54
|
+
: dbPath;
|
|
55
|
+
const storage = await initPrismaStorage(connectionString, cache);
|
|
56
|
+
return { storage, storagePath: dbPath };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
logger.warn("Falling back to filesystem storage");
|
|
61
|
+
}
|
|
62
|
+
// if url was postgres and connection failed, fallback to filesystem on default path
|
|
63
|
+
const filesystemPath = isPostgres ? "./.ph/drive-storage" : dbPath;
|
|
64
|
+
return {
|
|
65
|
+
storage: new FilesystemStorage(path.join(process.cwd(), filesystemPath)),
|
|
66
|
+
storagePath: filesystemPath,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
29
69
|
async function initServer(serverPort, options) {
|
|
30
70
|
const { dev, packages = [], remoteDrives = [] } = options;
|
|
71
|
+
const dbPath = options.dbPath ?? process.env.DATABASE_URL;
|
|
31
72
|
// start redis if configured
|
|
32
73
|
const redisUrl = process.env.REDIS_TLS_URL ?? process.env.REDIS_URL;
|
|
33
74
|
let redis;
|
|
@@ -36,40 +77,43 @@ async function initServer(serverPort, options) {
|
|
|
36
77
|
redis = await initRedis(redisUrl);
|
|
37
78
|
}
|
|
38
79
|
catch (e) {
|
|
39
|
-
|
|
80
|
+
logger.error(e);
|
|
40
81
|
}
|
|
41
82
|
}
|
|
42
|
-
const connectionString = process.env.DATABASE_URL ?? "./.ph/drive-storage";
|
|
43
|
-
const dbUrl = connectionString.includes("amazonaws") &&
|
|
44
|
-
!connectionString.includes("sslmode=no-verify")
|
|
45
|
-
? connectionString + "?sslmode=no-verify"
|
|
46
|
-
: connectionString;
|
|
47
83
|
const cache = redis ? new RedisCache(redis) : new InMemoryCache();
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
?
|
|
53
|
-
:
|
|
54
|
-
const
|
|
84
|
+
const { storage, storagePath } = await initReactorStorage(cache, dbPath);
|
|
85
|
+
// if dbPath is not configured, or it was a postgres url but the connection failed,
|
|
86
|
+
// use default path for read model storage
|
|
87
|
+
const readModelPath = !dbPath || (isPostgresUrl(dbPath) && dbPath !== storagePath)
|
|
88
|
+
? ".ph/read-storage"
|
|
89
|
+
: dbPath;
|
|
90
|
+
const driveServer = new ReactorBuilder([
|
|
55
91
|
documentModelDocumentModelModule,
|
|
56
92
|
driveDocumentModelModule,
|
|
57
93
|
])
|
|
58
94
|
.withStorage(storage)
|
|
59
95
|
.withCache(cache)
|
|
96
|
+
.withOptions({
|
|
97
|
+
featureFlags: {
|
|
98
|
+
enableDualActionCreate: options.reactorOptions?.enableDualActionCreate ?? false,
|
|
99
|
+
},
|
|
100
|
+
})
|
|
60
101
|
.build();
|
|
61
102
|
// init drive server
|
|
62
|
-
await
|
|
63
|
-
const
|
|
103
|
+
await driveServer.initialize();
|
|
104
|
+
const eventBus = new EventBus();
|
|
105
|
+
const queue = new InMemoryQueue(eventBus);
|
|
106
|
+
const reactor = new Reactor(driveServer, storage, queue, new InMemoryJobTracker(), new ReadModelCoordinator(eventBus, []));
|
|
107
|
+
const client = new ReactorClientBuilder().withReactor(reactor).build();
|
|
64
108
|
let defaultDriveUrl = undefined;
|
|
65
109
|
// Create default drive if provided
|
|
66
110
|
if (options.drive) {
|
|
67
|
-
defaultDriveUrl = await addDefaultDrive(
|
|
111
|
+
defaultDriveUrl = await addDefaultDrive(driveServer, options.drive, serverPort);
|
|
68
112
|
}
|
|
69
113
|
// start vite server if dev mode is enabled
|
|
70
114
|
const vite = dev ? await startViteServer() : undefined;
|
|
71
115
|
// get paths to local document models
|
|
72
|
-
if (dev) {
|
|
116
|
+
if (dev && !options.disableLocalPackages) {
|
|
73
117
|
// TODO get path from powerhouse config
|
|
74
118
|
const basePath = process.cwd();
|
|
75
119
|
packages.push(basePath);
|
|
@@ -77,15 +121,17 @@ async function initServer(serverPort, options) {
|
|
|
77
121
|
// create loader
|
|
78
122
|
const packageLoader = vite ? await VitePackageLoader.build(vite) : undefined;
|
|
79
123
|
// Start the API with the reactor and options
|
|
80
|
-
const api = await startAPI(
|
|
124
|
+
const api = await startAPI(driveServer, client, {
|
|
81
125
|
express: app,
|
|
82
126
|
port: serverPort,
|
|
83
|
-
dbPath:
|
|
127
|
+
dbPath: readModelPath,
|
|
84
128
|
https: options.https,
|
|
85
129
|
packageLoader,
|
|
86
130
|
packages: packages,
|
|
131
|
+
processorConfig: options.processorConfig,
|
|
87
132
|
configFile: options.configFile ?? path.join(process.cwd(), "powerhouse.config.json"),
|
|
88
133
|
mcp: options.mcp ?? true,
|
|
134
|
+
subgraphs: options.subgraphs,
|
|
89
135
|
});
|
|
90
136
|
// add vite middleware after express app is initialized if applicable
|
|
91
137
|
if (vite) {
|
|
@@ -95,7 +141,7 @@ async function initServer(serverPort, options) {
|
|
|
95
141
|
if (remoteDrives.length > 0) {
|
|
96
142
|
for (const remoteDriveUrl of remoteDrives) {
|
|
97
143
|
try {
|
|
98
|
-
await
|
|
144
|
+
await driveServer.addRemoteDrive(remoteDriveUrl, {
|
|
99
145
|
availableOffline: true,
|
|
100
146
|
sharingType: "public",
|
|
101
147
|
listeners: [],
|
|
@@ -108,14 +154,14 @@ async function initServer(serverPort, options) {
|
|
|
108
154
|
}
|
|
109
155
|
catch (error) {
|
|
110
156
|
if (error instanceof DocumentAlreadyExistsError) {
|
|
111
|
-
|
|
157
|
+
logger.debug(`Remote drive already added: ${remoteDriveUrl}`);
|
|
112
158
|
// Still use this drive URL as default if not already set
|
|
113
159
|
if (!defaultDriveUrl) {
|
|
114
160
|
defaultDriveUrl = remoteDriveUrl;
|
|
115
161
|
}
|
|
116
162
|
}
|
|
117
163
|
else {
|
|
118
|
-
|
|
164
|
+
logger.error(`Failed to connect to remote drive ${remoteDriveUrl}:`, error);
|
|
119
165
|
}
|
|
120
166
|
}
|
|
121
167
|
}
|
|
@@ -123,18 +169,28 @@ async function initServer(serverPort, options) {
|
|
|
123
169
|
return {
|
|
124
170
|
defaultDriveUrl,
|
|
125
171
|
api,
|
|
126
|
-
reactor,
|
|
172
|
+
reactor: driveServer,
|
|
127
173
|
};
|
|
128
174
|
}
|
|
129
175
|
export const startSwitchboard = async (options = {}) => {
|
|
130
176
|
const serverPort = options.port ?? DEFAULT_PORT;
|
|
177
|
+
// Initialize feature flags
|
|
178
|
+
await initFeatureFlags();
|
|
179
|
+
const enabled = await isReactorv2Enabled();
|
|
180
|
+
options.subgraphs = {
|
|
181
|
+
isReactorv2Enabled: enabled,
|
|
182
|
+
};
|
|
183
|
+
const dualActionCreateEnabled = await isDualActionCreateEnabled();
|
|
184
|
+
options.reactorOptions = {
|
|
185
|
+
enableDualActionCreate: dualActionCreateEnabled,
|
|
186
|
+
};
|
|
131
187
|
if (process.env.PYROSCOPE_SERVER_ADDRESS) {
|
|
132
188
|
try {
|
|
133
189
|
await initProfilerFromEnv(process.env);
|
|
134
190
|
}
|
|
135
191
|
catch (e) {
|
|
136
192
|
Sentry.captureException(e);
|
|
137
|
-
|
|
193
|
+
logger.error("Error starting profiler", e);
|
|
138
194
|
}
|
|
139
195
|
}
|
|
140
196
|
try {
|
|
@@ -142,7 +198,7 @@ export const startSwitchboard = async (options = {}) => {
|
|
|
142
198
|
}
|
|
143
199
|
catch (e) {
|
|
144
200
|
Sentry.captureException(e);
|
|
145
|
-
|
|
201
|
+
logger.error("App crashed", e);
|
|
146
202
|
throw e;
|
|
147
203
|
}
|
|
148
204
|
};
|
package/dist/src/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DriveInput, IDocumentDriveServer } from "document-drive";
|
|
2
2
|
export type StorageOptions = {
|
|
3
3
|
type: "filesystem" | "memory" | "postgres" | "browser";
|
|
4
4
|
filesystemPath?: string;
|
|
@@ -23,6 +23,14 @@ export type StartServerOptions = {
|
|
|
23
23
|
admins: string[];
|
|
24
24
|
};
|
|
25
25
|
mcp?: boolean;
|
|
26
|
+
processorConfig?: Map<string, unknown>;
|
|
27
|
+
disableLocalPackages?: boolean;
|
|
28
|
+
subgraphs?: {
|
|
29
|
+
isReactorv2Enabled?: boolean;
|
|
30
|
+
};
|
|
31
|
+
reactorOptions?: {
|
|
32
|
+
enableDualActionCreate?: boolean;
|
|
33
|
+
};
|
|
26
34
|
};
|
|
27
35
|
export type SwitchboardReactor = {
|
|
28
36
|
defaultDriveUrl: string | undefined;
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EACF;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,GACD,OAAO,GACP,SAAS,CAAC;IACd,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE;QACV,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF,cAAc,CAAC,EAAE;QACf,sBAAsB,CAAC,EAAE,OAAO,CAAC;KAClC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,oBAAoB,CAAC;CAC/B,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BaseDocumentDriveServer } from "document-drive";
|
|
2
2
|
export declare const getDocumentModelTypeDefs: (documentDriveServer: BaseDocumentDriveServer, typeDefs: string) => import("graphql").DocumentNode;
|
|
3
3
|
//# sourceMappingURL=gen-doc-model-type-defs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gen-doc-model-type-defs.d.ts","sourceRoot":"","sources":["../../../src/utils/gen-doc-model-type-defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"gen-doc-model-type-defs.d.ts","sourceRoot":"","sources":["../../../src/utils/gen-doc-model-type-defs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,eAAO,MAAM,wBAAwB,GACnC,qBAAqB,uBAAuB,EAC5C,UAAU,MAAM,mCAkEjB,CAAC"}
|
|
@@ -4,20 +4,20 @@ export const getDocumentModelTypeDefs = (documentDriveServer, typeDefs) => {
|
|
|
4
4
|
let dmSchema = "";
|
|
5
5
|
documentModels.forEach(({ documentModel }) => {
|
|
6
6
|
dmSchema += `
|
|
7
|
-
${documentModel.specifications
|
|
7
|
+
${documentModel.global.specifications
|
|
8
8
|
.map((specification) => specification.state.global.schema
|
|
9
|
-
.replaceAll(" Account ", ` ${documentModel.name}Account `)
|
|
10
|
-
.replaceAll(`: Account`, `: ${documentModel.name}Account`)
|
|
11
|
-
.replaceAll(`[Account!]!`, `[${documentModel.name}Account!]!`)
|
|
9
|
+
.replaceAll(" Account ", ` ${documentModel.global.name}Account `)
|
|
10
|
+
.replaceAll(`: Account`, `: ${documentModel.global.name}Account`)
|
|
11
|
+
.replaceAll(`[Account!]!`, `[${documentModel.global.name}Account!]!`)
|
|
12
12
|
.replaceAll("scalar DateTime", "")
|
|
13
13
|
.replaceAll(/input (.*?) {[\s\S]*?}/g, ""))
|
|
14
14
|
.join("\n")};
|
|
15
15
|
|
|
16
|
-
${documentModel.specifications
|
|
16
|
+
${documentModel.global.specifications
|
|
17
17
|
.map((specification) => specification.state.local.schema
|
|
18
|
-
.replaceAll(" Account ", ` ${documentModel.name}Account `)
|
|
19
|
-
.replaceAll(`: Account`, `: ${documentModel.name}Account`)
|
|
20
|
-
.replaceAll(`[Account!]!`, `[${documentModel.name}Account!]!`)
|
|
18
|
+
.replaceAll(" Account ", ` ${documentModel.global.name}Account `)
|
|
19
|
+
.replaceAll(`: Account`, `: ${documentModel.global.name}Account`)
|
|
20
|
+
.replaceAll(`[Account!]!`, `[${documentModel.global.name}Account!]!`)
|
|
21
21
|
.replaceAll("scalar DateTime", "")
|
|
22
22
|
.replaceAll(/input (.*?) {[\s\S]*?}/g, "")
|
|
23
23
|
.replaceAll("type AccountSnapshotLocalState", "")
|
|
@@ -25,14 +25,15 @@ export const getDocumentModelTypeDefs = (documentDriveServer, typeDefs) => {
|
|
|
25
25
|
.replaceAll("type ScopeFrameworkLocalState", ""))
|
|
26
26
|
.join("\n")};
|
|
27
27
|
|
|
28
|
-
type ${documentModel.name} implements IDocument {
|
|
28
|
+
type ${documentModel.global.name} implements IDocument {
|
|
29
29
|
id: ID!
|
|
30
30
|
name: String!
|
|
31
31
|
documentType: String!
|
|
32
32
|
revision: Int!
|
|
33
33
|
created: DateTime!
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
createdAtUtcIso: DateTime!
|
|
35
|
+
lastModifiedAtUtcIso: DateTime!
|
|
36
|
+
${documentModel.global.name !== "DocumentModel" ? `state: ${documentModel.global.name}State!` : ""}
|
|
36
37
|
}\n`;
|
|
37
38
|
});
|
|
38
39
|
// add the mutation and query types
|
|
@@ -43,8 +44,8 @@ export const getDocumentModelTypeDefs = (documentDriveServer, typeDefs) => {
|
|
|
43
44
|
documentType: String!
|
|
44
45
|
revision: Int!
|
|
45
46
|
created: DateTime!
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
createdAtUtcIso: DateTime!
|
|
48
|
+
lastModifiedAtUtcIso: DateTime!
|
|
48
49
|
}
|
|
49
50
|
${dmSchema}
|
|
50
51
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gen-doc-model-type-defs.js","sourceRoot":"","sources":["../../../src/utils/gen-doc-model-type-defs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,mBAA4C,EAC5C,QAAgB,EAChB,EAAE;IACF,MAAM,cAAc,GAAG,mBAAmB,CAAC,uBAAuB,EAAE,CAAC;IACrE,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE;QAC3C,QAAQ,IAAI;UACN,aAAa,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"gen-doc-model-type-defs.js","sourceRoot":"","sources":["../../../src/utils/gen-doc-model-type-defs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,mBAA4C,EAC5C,QAAgB,EAChB,EAAE;IACF,MAAM,cAAc,GAAG,mBAAmB,CAAC,uBAAuB,EAAE,CAAC;IACrE,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE;QAC3C,QAAQ,IAAI;UACN,aAAa,CAAC,MAAM,CAAC,cAAc;aAClC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACrB,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;aAC9B,UAAU,CAAC,WAAW,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC;aAChE,UAAU,CAAC,WAAW,EAAE,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;aAChE,UAAU,CACT,aAAa,EACb,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,YAAY,CAC1C;aACA,UAAU,CAAC,iBAAiB,EAAE,EAAE,CAAC;aACjC,UAAU,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAC7C;aACA,IAAI,CAAC,IAAI,CAAC;;UAEX,aAAa,CAAC,MAAM,CAAC,cAAc;aAClC,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CACrB,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM;aAC7B,UAAU,CAAC,WAAW,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC;aAChE,UAAU,CAAC,WAAW,EAAE,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;aAChE,UAAU,CACT,aAAa,EACb,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,YAAY,CAC1C;aACA,UAAU,CAAC,iBAAiB,EAAE,EAAE,CAAC;aACjC,UAAU,CAAC,yBAAyB,EAAE,EAAE,CAAC;aACzC,UAAU,CAAC,gCAAgC,EAAE,EAAE,CAAC;aAChD,UAAU,CAAC,gCAAgC,EAAE,EAAE,CAAC;aAChD,UAAU,CAAC,+BAA+B,EAAE,EAAE,CAAC,CACnD;aACA,IAAI,CAAC,IAAI,CAAC;;eAEN,aAAa,CAAC,MAAM,CAAC,IAAI;;;;;;;;cAQ1B,aAAa,CAAC,MAAM,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,UAAU,aAAa,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE;YAClG,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,MAAM,MAAM,GAAG;;;;;;;;;;MAUX,QAAQ;;MAER,QAAQ;KACT,CAAC;IAEJ,OAAO,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC"}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DriveInput, IDocumentDriveServer } from "document-drive";
|
|
2
2
|
export declare function addDefaultDrive(driveServer: IDocumentDriveServer, drive: DriveInput, serverPort: number): Promise<string>;
|
|
3
|
+
export declare function isPostgresUrl(url: string): boolean;
|
|
3
4
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAGvE,wBAAsB,eAAe,CACnC,WAAW,EAAE,oBAAoB,EACjC,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,mBAqBnB;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,WAExC"}
|
package/dist/src/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentAlreadyExistsError
|
|
1
|
+
import { DocumentAlreadyExistsError } from "document-drive";
|
|
2
2
|
export async function addDefaultDrive(driveServer, drive, serverPort) {
|
|
3
3
|
let driveId = drive.id;
|
|
4
4
|
if (!driveId || driveId.length === 0) {
|
|
@@ -18,4 +18,7 @@ export async function addDefaultDrive(driveServer, drive, serverPort) {
|
|
|
18
18
|
}
|
|
19
19
|
return `http://localhost:${serverPort}/d/${driveId}`;
|
|
20
20
|
}
|
|
21
|
+
export function isPostgresUrl(url) {
|
|
22
|
+
return url.startsWith("postgresql") || url.startsWith("postgres");
|
|
23
|
+
}
|
|
21
24
|
//# sourceMappingURL=utils.js.map
|
package/dist/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAiC,EACjC,KAAiB,EACjB,UAAkB;IAElB,IAAI,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;IACvB,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC;QACH,oBAAoB;QACpB,MAAM,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,CAAC,CAAC,YAAY,0BAA0B,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,OAAO,oBAAoB,UAAU,MAAM,OAAO,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACpE,CAAC"}
|