wizards 0.2.2 → 0.2.4
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/apps/runtime/dist/app.js +44 -0
- package/apps/runtime/dist/auth/account.js +16 -2
- package/apps/runtime/dist/auth/index.js +14 -1
- package/apps/runtime/dist/connectors/external.js +5 -0
- package/apps/runtime/dist/db/client.js +24 -3
- package/apps/runtime/dist/db/control-schema.js +12 -3
- package/apps/runtime/dist/db/migrations/control/0005_chilly_oracle.sql +1 -0
- package/apps/runtime/dist/db/migrations/control/0006_sleepy_mojo.sql +1 -0
- package/apps/runtime/dist/db/migrations/control/meta/0005_snapshot.json +358 -0
- package/apps/runtime/dist/db/migrations/control/meta/0006_snapshot.json +365 -0
- package/apps/runtime/dist/db/migrations/control/meta/_journal.json +14 -0
- package/apps/runtime/dist/db/migrations/tenant/0005_reflective_forgotten_one.sql +2 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0005_snapshot.json +1659 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
- package/apps/runtime/dist/db/schema.js +6 -0
- package/apps/runtime/dist/engine/asks.js +2 -0
- package/apps/runtime/dist/engine/push.js +58 -0
- package/apps/runtime/dist/engine/runner.js +6 -0
- package/apps/runtime/dist/env.js +13 -0
- package/apps/runtime/dist/index.js +6 -0
- package/apps/runtime/dist/limits.js +21 -0
- package/apps/runtime/dist/manage.js +16 -3
- package/apps/runtime/dist/mcp/tools.js +4 -2
- package/apps/runtime/dist/routes/api.js +96 -6
- package/apps/runtime/dist/routes/runs.js +68 -2
- package/apps/runtime/dist/routes/studio.js +79 -11
- package/apps/runtime/dist/services/access.js +62 -0
- package/apps/runtime/dist/services/architect.js +3 -2
- package/apps/runtime/dist/services/cloud.js +298 -39
- package/apps/runtime/dist/services/errors.js +1 -0
- package/apps/runtime/dist/services/files.js +53 -4
- package/apps/runtime/dist/services/project-files.js +6 -0
- package/apps/runtime/dist/services/projects.js +38 -14
- package/apps/runtime/dist/services/spaces.js +400 -0
- package/apps/runtime/dist/services/wizards.js +19 -8
- package/apps/runtime/dist/tenants/control.js +47 -0
- package/apps/runtime/dist/update.js +3 -3
- package/apps/web/dist/assets/{ChangelogDialog-4HCt88rf.js → ChangelogDialog-lGa0JKY1.js} +1 -1
- package/apps/web/dist/assets/ChatPanel-Dk_45uca.js +1 -0
- package/apps/web/dist/assets/{CreditsDialog-D3fZRqXH.js → CreditsDialog-BPMWo6tp.js} +1 -1
- package/apps/web/dist/assets/EditorPage-Dt4MCcrU.js +2 -0
- package/apps/web/dist/assets/{FlowPreview-CjUK5046.js → FlowPreview-gwtUv8-X.js} +1 -1
- package/apps/web/dist/assets/HomePage-Bi9FK3_1.js +1 -0
- package/apps/web/dist/assets/ImportWizard-D6y4bKlF.js +1 -0
- package/apps/web/dist/assets/{LocalRuntime-DupxjXff.js → LocalRuntime-BjzPSsHr.js} +10 -10
- package/apps/web/dist/assets/NewWizardPage-2HbCaPSt.js +2 -0
- package/apps/web/dist/assets/PublicRunner-Dac_e6wg.js +1 -0
- package/apps/web/dist/assets/RunnerView-BC6crf1p.js +2 -0
- package/apps/web/dist/assets/SettingsPage-BfXxa4SU.js +2 -0
- package/apps/web/dist/assets/{SetupPage-xiqJMR0J.js → SetupPage-CYKVspBJ.js} +1 -1
- package/apps/web/dist/assets/{SharePage-C8B9BUSU.js → SharePage-DFIHsNS-.js} +1 -1
- package/apps/web/dist/assets/{api-KMi35npD.js → api-BTfKh3La.js} +1 -1
- package/apps/web/dist/assets/changelog-CLmll9By.js +1 -0
- package/apps/web/dist/assets/index-CIwJmOjo.css +1 -0
- package/apps/web/dist/assets/{index-2Ktgo6f1.js → index-DOpyzQiU.js} +3 -3
- package/apps/web/dist/assets/{meta-4R1Lnr25.js → meta-BbVhbYf6.js} +1 -1
- package/apps/web/dist/assets/oss-credits-Hu4LieLA.js +1 -0
- package/apps/web/dist/assets/outputs-n_yhxmMk.js +69 -0
- package/apps/web/dist/assets/{session-B6-6VomQ.js → session-D_Zggq_t.js} +1 -1
- package/apps/web/dist/assets/type-BMJpS6_D.js +1 -0
- package/apps/web/dist/assets/ui-C3bTWmdM.js +1 -0
- package/apps/web/dist/index.html +5 -5
- package/apps/web/dist/mcp/flow.html +54 -54
- package/package.json +1 -1
- package/apps/web/dist/assets/ChatPanel-B91fTrzg.js +0 -1
- package/apps/web/dist/assets/EditorPage-ZZjb9mGV.js +0 -2
- package/apps/web/dist/assets/HomePage-Cn5TCZk7.js +0 -1
- package/apps/web/dist/assets/ImportWizard-DiV62Uno.js +0 -1
- package/apps/web/dist/assets/NewWizardPage-Bz3PIQGp.js +0 -2
- package/apps/web/dist/assets/PublicRunner-Axs1zwqe.js +0 -1
- package/apps/web/dist/assets/RunnerView-Bhv6RNME.js +0 -2
- package/apps/web/dist/assets/SettingsPage-in_RmI8i.js +0 -2
- package/apps/web/dist/assets/changelog-C2LDEzLQ.js +0 -1
- package/apps/web/dist/assets/index-B9YVjvVY.css +0 -1
- package/apps/web/dist/assets/oss-credits-roB62QJu.js +0 -1
- package/apps/web/dist/assets/outputs-Dhqtf-SA.js +0 -69
- package/apps/web/dist/assets/type-Bj9H3eOK.js +0 -1
- package/apps/web/dist/assets/ui-Cs6lpsmj.js +0 -1
package/apps/runtime/dist/app.js
CHANGED
|
@@ -4,6 +4,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
6
6
|
import { Hono } from "hono";
|
|
7
|
+
import { bodyLimit } from "hono/body-limit";
|
|
7
8
|
import { HTTPException } from "hono/http-exception";
|
|
8
9
|
import { ZodError } from "zod";
|
|
9
10
|
import { authRoutes, principalOf } from "./auth/index.js";
|
|
@@ -114,6 +115,38 @@ app.get("/.well-known/oauth-protected-resource/*", async (c) => {
|
|
|
114
115
|
bearer_methods_supported: ["header"],
|
|
115
116
|
});
|
|
116
117
|
});
|
|
118
|
+
// The mobile app opens this runtime's wizard and result links (Universal Links, App Links).
|
|
119
|
+
app.get("/.well-known/apple-app-site-association", (c) => {
|
|
120
|
+
if (!env.mobile.iosAppIds.length) {
|
|
121
|
+
return c.notFound();
|
|
122
|
+
}
|
|
123
|
+
const paths = [`${basePath}/w/*`, `${basePath}/s/*`];
|
|
124
|
+
return c.json({
|
|
125
|
+
applinks: {
|
|
126
|
+
details: [
|
|
127
|
+
{
|
|
128
|
+
appIDs: env.mobile.iosAppIds,
|
|
129
|
+
components: paths.map((path) => ({ "/": path })),
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
app.get("/.well-known/assetlinks.json", (c) => {
|
|
136
|
+
if (!env.mobile.androidCertSha256.length) {
|
|
137
|
+
return c.notFound();
|
|
138
|
+
}
|
|
139
|
+
return c.json([
|
|
140
|
+
{
|
|
141
|
+
relation: ["delegate_permission/common.handle_all_urls"],
|
|
142
|
+
target: {
|
|
143
|
+
namespace: "android_app",
|
|
144
|
+
package_name: env.mobile.androidPackage,
|
|
145
|
+
sha256_cert_fingerprints: env.mobile.androidCertSha256,
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
]);
|
|
149
|
+
});
|
|
117
150
|
/** Studio requests act as the signed-in person, inside that person's tenant. */
|
|
118
151
|
app.use("/api/studio/*", async (c, next) => {
|
|
119
152
|
const user = await principalOf(c);
|
|
@@ -130,6 +163,17 @@ const mcp = mcpHandler();
|
|
|
130
163
|
app.on(["GET", "POST", "DELETE"], "/api/mcp", (c) => mcp(c.req.raw));
|
|
131
164
|
// The tools of one model call, for the installed Claude Code while it answers that call.
|
|
132
165
|
app.on(["GET", "POST", "DELETE"], "/api/mcp/bridge/:token", (c) => bridgeRequest(c.req.param("token"), c.req.raw));
|
|
166
|
+
// What visitors send is read before anyone is known: a body is taken only up to a size. A page's
|
|
167
|
+
// answers are text; an upload is a photo, a recording or a clip from a phone (routes/delivery.ts).
|
|
168
|
+
const tooLarge = (max) => bodyLimit({
|
|
169
|
+
maxSize: max,
|
|
170
|
+
onError: (c) => c.json({ error: "Das ist zu groß.", code: "too_large" }, 413),
|
|
171
|
+
});
|
|
172
|
+
const answers = tooLarge(4 * 1024 * 1024);
|
|
173
|
+
const upload = tooLarge(48 * 1024 * 1024);
|
|
174
|
+
app.use("/api/public/*", answers);
|
|
175
|
+
app.use("/api/shares/*", answers);
|
|
176
|
+
app.use("/api/runs/*", (c, next) => /\/uploads$/.test(c.req.path) ? upload(c, next) : answers(c, next));
|
|
133
177
|
app.route("/api/studio/wizards", wizardStream);
|
|
134
178
|
app.route("/api/studio/marketplace", marketplaceStudio);
|
|
135
179
|
app.route("/api/studio/plugins", pluginRoutes);
|
|
@@ -16,7 +16,11 @@ const SCOPE = "openid profile email offline_access wizards:read wizards:write wi
|
|
|
16
16
|
function redirectUri() {
|
|
17
17
|
return `http://127.0.0.1:${env.port}/api/auth/callback`;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* The address that links an account. `signup`: the person has none yet — the account's sign-up
|
|
21
|
+
* page takes the invitation code (`code` fills it in) and goes on to the same sign-in.
|
|
22
|
+
*/
|
|
23
|
+
export async function startLink(options = {}) {
|
|
20
24
|
const d = await discovery(env.local.accountUrl);
|
|
21
25
|
const verifier = randomBytes(32).toString("base64url");
|
|
22
26
|
const state = { verifier, redirect: redirectUri(), exp: Date.now() + 15 * 60_000 };
|
|
@@ -31,7 +35,17 @@ export async function startLink() {
|
|
|
31
35
|
code_challenge_method: "S256",
|
|
32
36
|
state: seal(state),
|
|
33
37
|
}).toString();
|
|
34
|
-
|
|
38
|
+
if (!options.signup) {
|
|
39
|
+
return url.toString();
|
|
40
|
+
}
|
|
41
|
+
const signUp = new URL("/sign-up", env.local.accountUrl);
|
|
42
|
+
const code = options.code?.trim();
|
|
43
|
+
if (code) {
|
|
44
|
+
signUp.searchParams.set("code", code);
|
|
45
|
+
}
|
|
46
|
+
// The sign-up page goes on only to a path of its own origin.
|
|
47
|
+
signUp.searchParams.set("next", url.pathname + url.search);
|
|
48
|
+
return signUp.toString();
|
|
35
49
|
}
|
|
36
50
|
let cached = null;
|
|
37
51
|
async function keep(tokens) {
|
|
@@ -4,7 +4,7 @@ import { eq, lt } from "drizzle-orm";
|
|
|
4
4
|
import { Hono } from "hono";
|
|
5
5
|
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
6
6
|
import { nanoid } from "nanoid";
|
|
7
|
-
import { control, controlDb } from "../db/client.js";
|
|
7
|
+
import { control, controlDb, withTenant } from "../db/client.js";
|
|
8
8
|
import { basePath, env } from "../env.js";
|
|
9
9
|
import { discovery, managed, tokenRequest, verifyToken, } from "../manage.js";
|
|
10
10
|
import { seal, unseal } from "../secrets/crypto.js";
|
|
@@ -24,6 +24,17 @@ let accessKey = managed
|
|
|
24
24
|
export function localEntryUrl() {
|
|
25
25
|
return accessKey ? `${env.appUrl}/api/local/enter?k=${accessKey}` : null;
|
|
26
26
|
}
|
|
27
|
+
/** Sends everything published here to the cloud of the account that was just linked. */
|
|
28
|
+
async function firstSync() {
|
|
29
|
+
try {
|
|
30
|
+
// Loaded here: the services read the session this module makes.
|
|
31
|
+
const { syncAllToCloud } = await import("../services/cloud.js");
|
|
32
|
+
await withTenant(LOCAL_TENANT, () => syncAllToCloud(localUser().id));
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
console.error("[cloud] first sync failed:", err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
27
38
|
const localUser = () => ({
|
|
28
39
|
id: "local",
|
|
29
40
|
tenantId: LOCAL_TENANT,
|
|
@@ -265,6 +276,8 @@ export const authRoutes = new Hono()
|
|
|
265
276
|
}
|
|
266
277
|
try {
|
|
267
278
|
await finishLink(code, rawState);
|
|
279
|
+
// What is published here goes to the account's cloud, from now on and once for all there is.
|
|
280
|
+
void firstSync();
|
|
268
281
|
return c.html(closePage("Angemeldet. Du kannst dieses Fenster schließen."));
|
|
269
282
|
}
|
|
270
283
|
catch (err) {
|
|
@@ -9,6 +9,7 @@ import { discoverImportableSources, discoverOAuthFacts, registryDiscover, regist
|
|
|
9
9
|
import { resolveRegistrySource } from "../engenty/connections-external/registry-source.js";
|
|
10
10
|
import { encryptToken } from "../engenty/shims/connections-sdk.js";
|
|
11
11
|
import { env } from "../env.js";
|
|
12
|
+
import { requireWritableProject } from "../services/access.js";
|
|
12
13
|
import { ServiceError } from "../services/errors.js";
|
|
13
14
|
import { BUILTIN_CONNECTORS, builtinConnector, missingSetup, usable } from "./builtin.js";
|
|
14
15
|
/**
|
|
@@ -270,6 +271,7 @@ export async function resolveConnector(projectId, id) {
|
|
|
270
271
|
: null;
|
|
271
272
|
}
|
|
272
273
|
export async function importConnector(userId, projectId, input) {
|
|
274
|
+
await requireWritableProject(projectId);
|
|
273
275
|
if (await load(projectId, input.id)) {
|
|
274
276
|
throw new ServiceError("invalid", `Connector "${input.id}" already exists in this project.`);
|
|
275
277
|
}
|
|
@@ -311,6 +313,7 @@ export async function importConnector(userId, projectId, input) {
|
|
|
311
313
|
* an MCP server is the service's own, curated set of actions.
|
|
312
314
|
*/
|
|
313
315
|
export async function importFromRegistry(userId, projectId, input) {
|
|
316
|
+
await requireWritableProject(projectId);
|
|
314
317
|
const service = await registryService(input.domain);
|
|
315
318
|
const order = input.kind ? [input.kind] : ["mcp", "openapi"];
|
|
316
319
|
const source = order
|
|
@@ -334,6 +337,7 @@ export async function importFromRegistry(userId, projectId, input) {
|
|
|
334
337
|
});
|
|
335
338
|
}
|
|
336
339
|
export async function removeConnector(projectId, id) {
|
|
340
|
+
await requireWritableProject(projectId);
|
|
337
341
|
await db.delete(schema.projectConnector).where(where(projectId, id));
|
|
338
342
|
}
|
|
339
343
|
/**
|
|
@@ -341,6 +345,7 @@ export async function removeConnector(projectId, id) {
|
|
|
341
345
|
* tools to a signed-in account needs that account's token.
|
|
342
346
|
*/
|
|
343
347
|
export async function refreshConnector(projectId, id, accessToken) {
|
|
348
|
+
await requireWritableProject(projectId);
|
|
344
349
|
const record = await load(projectId, id);
|
|
345
350
|
if (!record) {
|
|
346
351
|
throw new ServiceError("not_found", "No such connector.");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
1
2
|
import { mkdirSync } from "node:fs";
|
|
2
3
|
import { dirname, join } from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
@@ -117,14 +118,34 @@ export async function withTenant(id, fn) {
|
|
|
117
118
|
await openTenantDb(id);
|
|
118
119
|
return inTenant(id, fn);
|
|
119
120
|
}
|
|
121
|
+
/** The transaction the current context writes in, while `inTransaction()` runs. */
|
|
122
|
+
const transactions = new AsyncLocalStorage();
|
|
120
123
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
124
|
+
* Runs `fn` as one transaction of the current tenant's database: inside it, `db` is the
|
|
125
|
+
* transaction, so every write of the services called there stands or falls with the others.
|
|
126
|
+
* Already inside one, `fn` just joins it. Only this database takes part: the object store and
|
|
127
|
+
* the control database are written as before, so do those first or after.
|
|
128
|
+
*/
|
|
129
|
+
export async function inTransaction(fn) {
|
|
130
|
+
if (transactions.getStore()) {
|
|
131
|
+
return fn();
|
|
132
|
+
}
|
|
133
|
+
const id = currentTenant();
|
|
134
|
+
const target = ready.get(id);
|
|
135
|
+
if (!target) {
|
|
136
|
+
throw new Error(`Tenant database "${id}" is not open: enter it with withTenant().`);
|
|
137
|
+
}
|
|
138
|
+
return target.transaction((tx) => transactions.run(tx, fn));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The current tenant's database, resolved from the context `inTenant()` set — or the
|
|
142
|
+
* transaction `inTransaction()` opened there. Code that reads or writes wizards, runs or files
|
|
143
|
+
* never names a tenant itself.
|
|
123
144
|
*/
|
|
124
145
|
export const db = new Proxy({}, {
|
|
125
146
|
get(_target, prop) {
|
|
126
147
|
const id = currentTenant();
|
|
127
|
-
const target = ready.get(id);
|
|
148
|
+
const target = transactions.getStore() ?? ready.get(id);
|
|
128
149
|
if (!target) {
|
|
129
150
|
throw new Error(`Tenant database "${id}" is not open: enter it with withTenant().`);
|
|
130
151
|
}
|
|
@@ -17,11 +17,14 @@ export const tenant = sqliteTable("tenant", {
|
|
|
17
17
|
export const link = sqliteTable("link", {
|
|
18
18
|
token: text("token").primaryKey(),
|
|
19
19
|
tenantId: text("tenant_id").notNull(),
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* `wizard` = a share link `/w/<token>`, `result` = a shared result `/s/<token>`, `logo` = a
|
|
22
|
+
* brand logo, `code` = a wizard's ID to type in (its `ref` is the wizard's share token).
|
|
23
|
+
*/
|
|
24
|
+
kind: text("kind", { enum: ["wizard", "result", "logo", "code"] }).notNull(),
|
|
22
25
|
ref: text("ref").notNull(),
|
|
23
26
|
createdAt: createdAt(),
|
|
24
|
-
}, (t) => [index("link_tenant").on(t.tenantId)]);
|
|
27
|
+
}, (t) => [index("link_tenant").on(t.tenantId), index("link_ref").on(t.kind, t.ref)]);
|
|
25
28
|
/**
|
|
26
29
|
* One row per run: finds the run's tenant, counts a visitor's runs across all wizards, and
|
|
27
30
|
* marks the runs that are working (resumed after a restart, counted against the tenant's limit).
|
|
@@ -32,6 +35,12 @@ export const runIndex = sqliteTable("run_index", {
|
|
|
32
35
|
visitorId: text("visitor_id"),
|
|
33
36
|
ipHash: text("ip_hash"),
|
|
34
37
|
active: integer("active", { mode: "boolean" }).notNull().default(false),
|
|
38
|
+
/**
|
|
39
|
+
* The mobile app's device for push, set by the app for this run (`POST /api/runs/:id/notify`):
|
|
40
|
+
* `{ token, platform: "ios" | "android", lang }`. Told through the Manage-App when the run is
|
|
41
|
+
* done, failed or waits for the person.
|
|
42
|
+
*/
|
|
43
|
+
push: text("push", { mode: "json" }).$type(),
|
|
35
44
|
createdAt: createdAt(),
|
|
36
45
|
}, (t) => [
|
|
37
46
|
index("run_index_visitor").on(t.visitorId, t.createdAt),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CREATE INDEX `link_ref` ON `link` (`kind`,`ref`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE `run_index` ADD `push` text;
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "6",
|
|
3
|
+
"dialect": "sqlite",
|
|
4
|
+
"id": "52cfe26f-c51b-49b6-abf7-21417f611007",
|
|
5
|
+
"prevId": "ded1f6e4-eee2-4ef4-99b7-171041cbe221",
|
|
6
|
+
"tables": {
|
|
7
|
+
"link": {
|
|
8
|
+
"name": "link",
|
|
9
|
+
"columns": {
|
|
10
|
+
"token": {
|
|
11
|
+
"name": "token",
|
|
12
|
+
"type": "text",
|
|
13
|
+
"primaryKey": true,
|
|
14
|
+
"notNull": true,
|
|
15
|
+
"autoincrement": false
|
|
16
|
+
},
|
|
17
|
+
"tenant_id": {
|
|
18
|
+
"name": "tenant_id",
|
|
19
|
+
"type": "text",
|
|
20
|
+
"primaryKey": false,
|
|
21
|
+
"notNull": true,
|
|
22
|
+
"autoincrement": false
|
|
23
|
+
},
|
|
24
|
+
"kind": {
|
|
25
|
+
"name": "kind",
|
|
26
|
+
"type": "text",
|
|
27
|
+
"primaryKey": false,
|
|
28
|
+
"notNull": true,
|
|
29
|
+
"autoincrement": false
|
|
30
|
+
},
|
|
31
|
+
"ref": {
|
|
32
|
+
"name": "ref",
|
|
33
|
+
"type": "text",
|
|
34
|
+
"primaryKey": false,
|
|
35
|
+
"notNull": true,
|
|
36
|
+
"autoincrement": false
|
|
37
|
+
},
|
|
38
|
+
"created_at": {
|
|
39
|
+
"name": "created_at",
|
|
40
|
+
"type": "integer",
|
|
41
|
+
"primaryKey": false,
|
|
42
|
+
"notNull": true,
|
|
43
|
+
"autoincrement": false,
|
|
44
|
+
"default": "(unixepoch() * 1000)"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"indexes": {
|
|
48
|
+
"link_tenant": {
|
|
49
|
+
"name": "link_tenant",
|
|
50
|
+
"columns": [
|
|
51
|
+
"tenant_id"
|
|
52
|
+
],
|
|
53
|
+
"isUnique": false
|
|
54
|
+
},
|
|
55
|
+
"link_ref": {
|
|
56
|
+
"name": "link_ref",
|
|
57
|
+
"columns": [
|
|
58
|
+
"kind",
|
|
59
|
+
"ref"
|
|
60
|
+
],
|
|
61
|
+
"isUnique": false
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"foreignKeys": {},
|
|
65
|
+
"compositePrimaryKeys": {},
|
|
66
|
+
"uniqueConstraints": {},
|
|
67
|
+
"checkConstraints": {}
|
|
68
|
+
},
|
|
69
|
+
"marketplace_cache": {
|
|
70
|
+
"name": "marketplace_cache",
|
|
71
|
+
"columns": {
|
|
72
|
+
"id": {
|
|
73
|
+
"name": "id",
|
|
74
|
+
"type": "text",
|
|
75
|
+
"primaryKey": true,
|
|
76
|
+
"notNull": true,
|
|
77
|
+
"autoincrement": false
|
|
78
|
+
},
|
|
79
|
+
"hash": {
|
|
80
|
+
"name": "hash",
|
|
81
|
+
"type": "text",
|
|
82
|
+
"primaryKey": false,
|
|
83
|
+
"notNull": true,
|
|
84
|
+
"autoincrement": false
|
|
85
|
+
},
|
|
86
|
+
"entry": {
|
|
87
|
+
"name": "entry",
|
|
88
|
+
"type": "text",
|
|
89
|
+
"primaryKey": false,
|
|
90
|
+
"notNull": true,
|
|
91
|
+
"autoincrement": false
|
|
92
|
+
},
|
|
93
|
+
"fetched_at": {
|
|
94
|
+
"name": "fetched_at",
|
|
95
|
+
"type": "integer",
|
|
96
|
+
"primaryKey": false,
|
|
97
|
+
"notNull": true,
|
|
98
|
+
"autoincrement": false,
|
|
99
|
+
"default": "(unixepoch() * 1000)"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"indexes": {},
|
|
103
|
+
"foreignKeys": {},
|
|
104
|
+
"compositePrimaryKeys": {},
|
|
105
|
+
"uniqueConstraints": {},
|
|
106
|
+
"checkConstraints": {}
|
|
107
|
+
},
|
|
108
|
+
"run_index": {
|
|
109
|
+
"name": "run_index",
|
|
110
|
+
"columns": {
|
|
111
|
+
"run_id": {
|
|
112
|
+
"name": "run_id",
|
|
113
|
+
"type": "text",
|
|
114
|
+
"primaryKey": true,
|
|
115
|
+
"notNull": true,
|
|
116
|
+
"autoincrement": false
|
|
117
|
+
},
|
|
118
|
+
"tenant_id": {
|
|
119
|
+
"name": "tenant_id",
|
|
120
|
+
"type": "text",
|
|
121
|
+
"primaryKey": false,
|
|
122
|
+
"notNull": true,
|
|
123
|
+
"autoincrement": false
|
|
124
|
+
},
|
|
125
|
+
"visitor_id": {
|
|
126
|
+
"name": "visitor_id",
|
|
127
|
+
"type": "text",
|
|
128
|
+
"primaryKey": false,
|
|
129
|
+
"notNull": false,
|
|
130
|
+
"autoincrement": false
|
|
131
|
+
},
|
|
132
|
+
"ip_hash": {
|
|
133
|
+
"name": "ip_hash",
|
|
134
|
+
"type": "text",
|
|
135
|
+
"primaryKey": false,
|
|
136
|
+
"notNull": false,
|
|
137
|
+
"autoincrement": false
|
|
138
|
+
},
|
|
139
|
+
"active": {
|
|
140
|
+
"name": "active",
|
|
141
|
+
"type": "integer",
|
|
142
|
+
"primaryKey": false,
|
|
143
|
+
"notNull": true,
|
|
144
|
+
"autoincrement": false,
|
|
145
|
+
"default": false
|
|
146
|
+
},
|
|
147
|
+
"created_at": {
|
|
148
|
+
"name": "created_at",
|
|
149
|
+
"type": "integer",
|
|
150
|
+
"primaryKey": false,
|
|
151
|
+
"notNull": true,
|
|
152
|
+
"autoincrement": false,
|
|
153
|
+
"default": "(unixepoch() * 1000)"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"indexes": {
|
|
157
|
+
"run_index_visitor": {
|
|
158
|
+
"name": "run_index_visitor",
|
|
159
|
+
"columns": [
|
|
160
|
+
"visitor_id",
|
|
161
|
+
"created_at"
|
|
162
|
+
],
|
|
163
|
+
"isUnique": false
|
|
164
|
+
},
|
|
165
|
+
"run_index_ip": {
|
|
166
|
+
"name": "run_index_ip",
|
|
167
|
+
"columns": [
|
|
168
|
+
"ip_hash",
|
|
169
|
+
"created_at"
|
|
170
|
+
],
|
|
171
|
+
"isUnique": false
|
|
172
|
+
},
|
|
173
|
+
"run_index_active": {
|
|
174
|
+
"name": "run_index_active",
|
|
175
|
+
"columns": [
|
|
176
|
+
"active",
|
|
177
|
+
"tenant_id"
|
|
178
|
+
],
|
|
179
|
+
"isUnique": false
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"foreignKeys": {},
|
|
183
|
+
"compositePrimaryKeys": {},
|
|
184
|
+
"uniqueConstraints": {},
|
|
185
|
+
"checkConstraints": {}
|
|
186
|
+
},
|
|
187
|
+
"session": {
|
|
188
|
+
"name": "session",
|
|
189
|
+
"columns": {
|
|
190
|
+
"id": {
|
|
191
|
+
"name": "id",
|
|
192
|
+
"type": "text",
|
|
193
|
+
"primaryKey": true,
|
|
194
|
+
"notNull": true,
|
|
195
|
+
"autoincrement": false
|
|
196
|
+
},
|
|
197
|
+
"user_id": {
|
|
198
|
+
"name": "user_id",
|
|
199
|
+
"type": "text",
|
|
200
|
+
"primaryKey": false,
|
|
201
|
+
"notNull": true,
|
|
202
|
+
"autoincrement": false
|
|
203
|
+
},
|
|
204
|
+
"tenant_id": {
|
|
205
|
+
"name": "tenant_id",
|
|
206
|
+
"type": "text",
|
|
207
|
+
"primaryKey": false,
|
|
208
|
+
"notNull": true,
|
|
209
|
+
"autoincrement": false
|
|
210
|
+
},
|
|
211
|
+
"role": {
|
|
212
|
+
"name": "role",
|
|
213
|
+
"type": "text",
|
|
214
|
+
"primaryKey": false,
|
|
215
|
+
"notNull": true,
|
|
216
|
+
"autoincrement": false
|
|
217
|
+
},
|
|
218
|
+
"name": {
|
|
219
|
+
"name": "name",
|
|
220
|
+
"type": "text",
|
|
221
|
+
"primaryKey": false,
|
|
222
|
+
"notNull": true,
|
|
223
|
+
"autoincrement": false
|
|
224
|
+
},
|
|
225
|
+
"email": {
|
|
226
|
+
"name": "email",
|
|
227
|
+
"type": "text",
|
|
228
|
+
"primaryKey": false,
|
|
229
|
+
"notNull": true,
|
|
230
|
+
"autoincrement": false
|
|
231
|
+
},
|
|
232
|
+
"image": {
|
|
233
|
+
"name": "image",
|
|
234
|
+
"type": "text",
|
|
235
|
+
"primaryKey": false,
|
|
236
|
+
"notNull": false,
|
|
237
|
+
"autoincrement": false
|
|
238
|
+
},
|
|
239
|
+
"refresh_token": {
|
|
240
|
+
"name": "refresh_token",
|
|
241
|
+
"type": "text",
|
|
242
|
+
"primaryKey": false,
|
|
243
|
+
"notNull": false,
|
|
244
|
+
"autoincrement": false
|
|
245
|
+
},
|
|
246
|
+
"claims_expire_at": {
|
|
247
|
+
"name": "claims_expire_at",
|
|
248
|
+
"type": "integer",
|
|
249
|
+
"primaryKey": false,
|
|
250
|
+
"notNull": true,
|
|
251
|
+
"autoincrement": false
|
|
252
|
+
},
|
|
253
|
+
"expires_at": {
|
|
254
|
+
"name": "expires_at",
|
|
255
|
+
"type": "integer",
|
|
256
|
+
"primaryKey": false,
|
|
257
|
+
"notNull": true,
|
|
258
|
+
"autoincrement": false
|
|
259
|
+
},
|
|
260
|
+
"created_at": {
|
|
261
|
+
"name": "created_at",
|
|
262
|
+
"type": "integer",
|
|
263
|
+
"primaryKey": false,
|
|
264
|
+
"notNull": true,
|
|
265
|
+
"autoincrement": false,
|
|
266
|
+
"default": "(unixepoch() * 1000)"
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
"indexes": {
|
|
270
|
+
"session_expires": {
|
|
271
|
+
"name": "session_expires",
|
|
272
|
+
"columns": [
|
|
273
|
+
"expires_at"
|
|
274
|
+
],
|
|
275
|
+
"isUnique": false
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"foreignKeys": {},
|
|
279
|
+
"compositePrimaryKeys": {},
|
|
280
|
+
"uniqueConstraints": {},
|
|
281
|
+
"checkConstraints": {}
|
|
282
|
+
},
|
|
283
|
+
"setting": {
|
|
284
|
+
"name": "setting",
|
|
285
|
+
"columns": {
|
|
286
|
+
"key": {
|
|
287
|
+
"name": "key",
|
|
288
|
+
"type": "text",
|
|
289
|
+
"primaryKey": true,
|
|
290
|
+
"notNull": true,
|
|
291
|
+
"autoincrement": false
|
|
292
|
+
},
|
|
293
|
+
"value": {
|
|
294
|
+
"name": "value",
|
|
295
|
+
"type": "text",
|
|
296
|
+
"primaryKey": false,
|
|
297
|
+
"notNull": true,
|
|
298
|
+
"autoincrement": false
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"indexes": {},
|
|
302
|
+
"foreignKeys": {},
|
|
303
|
+
"compositePrimaryKeys": {},
|
|
304
|
+
"uniqueConstraints": {},
|
|
305
|
+
"checkConstraints": {}
|
|
306
|
+
},
|
|
307
|
+
"tenant": {
|
|
308
|
+
"name": "tenant",
|
|
309
|
+
"columns": {
|
|
310
|
+
"id": {
|
|
311
|
+
"name": "id",
|
|
312
|
+
"type": "text",
|
|
313
|
+
"primaryKey": true,
|
|
314
|
+
"notNull": true,
|
|
315
|
+
"autoincrement": false
|
|
316
|
+
},
|
|
317
|
+
"status": {
|
|
318
|
+
"name": "status",
|
|
319
|
+
"type": "text",
|
|
320
|
+
"primaryKey": false,
|
|
321
|
+
"notNull": true,
|
|
322
|
+
"autoincrement": false,
|
|
323
|
+
"default": "'active'"
|
|
324
|
+
},
|
|
325
|
+
"db_url": {
|
|
326
|
+
"name": "db_url",
|
|
327
|
+
"type": "text",
|
|
328
|
+
"primaryKey": false,
|
|
329
|
+
"notNull": false,
|
|
330
|
+
"autoincrement": false
|
|
331
|
+
},
|
|
332
|
+
"created_at": {
|
|
333
|
+
"name": "created_at",
|
|
334
|
+
"type": "integer",
|
|
335
|
+
"primaryKey": false,
|
|
336
|
+
"notNull": true,
|
|
337
|
+
"autoincrement": false,
|
|
338
|
+
"default": "(unixepoch() * 1000)"
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
"indexes": {},
|
|
342
|
+
"foreignKeys": {},
|
|
343
|
+
"compositePrimaryKeys": {},
|
|
344
|
+
"uniqueConstraints": {},
|
|
345
|
+
"checkConstraints": {}
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
"views": {},
|
|
349
|
+
"enums": {},
|
|
350
|
+
"_meta": {
|
|
351
|
+
"schemas": {},
|
|
352
|
+
"tables": {},
|
|
353
|
+
"columns": {}
|
|
354
|
+
},
|
|
355
|
+
"internal": {
|
|
356
|
+
"indexes": {}
|
|
357
|
+
}
|
|
358
|
+
}
|