@heychunky/core 0.11.0 → 0.13.0
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/dist/admin/apps.d.ts +21 -0
- package/dist/admin/apps.d.ts.map +1 -1
- package/dist/admin/apps.js +28 -0
- package/dist/admin/apps.js.map +1 -1
- package/dist/admin/index.d.ts +1 -0
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/runs.d.ts +98 -0
- package/dist/admin/runs.d.ts.map +1 -0
- package/dist/admin/runs.js +66 -0
- package/dist/admin/runs.js.map +1 -0
- package/dist/admin/users.d.ts +18 -0
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +21 -0
- package/dist/admin/users.js.map +1 -1
- package/package.json +1 -1
package/dist/admin/apps.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { Register } from "./master.ts";
|
|
17
17
|
import type { StepResult } from "./provision.ts";
|
|
18
|
+
import type { User } from "./users.ts";
|
|
18
19
|
export interface App {
|
|
19
20
|
id: string;
|
|
20
21
|
name: string;
|
|
@@ -70,5 +71,25 @@ export declare function assertCanCreate(owner: string, register: Register): Prom
|
|
|
70
71
|
*/
|
|
71
72
|
export declare function recordApp(app: AppRecord, register: Register): Promise<App>;
|
|
72
73
|
/** Apps an owner has, or every app when none is named. */
|
|
74
|
+
/**
|
|
75
|
+
* One app, if this operator may have it.
|
|
76
|
+
*
|
|
77
|
+
* The tenancy rule asked of a single row: a developer reaching for somebody
|
|
78
|
+
* else's app by name gets nothing, which is the same answer as an app that
|
|
79
|
+
* does not exist. Telling those apart would confirm what other people have
|
|
80
|
+
* named their apps, and the caller is expected to answer both the same way.
|
|
81
|
+
*
|
|
82
|
+
* This is what replaces a configured target repository. A run does not hold a
|
|
83
|
+
* repo; it resolves one — from who is asking and which app they named — and
|
|
84
|
+
* `repo` on the row it returns is the answer. Which means the authorisation
|
|
85
|
+
* and the lookup are the same call, and a caller cannot perform the second
|
|
86
|
+
* while forgetting the first.
|
|
87
|
+
*
|
|
88
|
+
* In the Core rather than in a caller because there are now three: the pages,
|
|
89
|
+
* the API, and the superagent working on somebody's app on their behalf. A
|
|
90
|
+
* tenancy rule that lives in one of them is a rule the other two can differ
|
|
91
|
+
* from.
|
|
92
|
+
*/
|
|
93
|
+
export declare function appFor(user: Pick<User, "id" | "role">, name: string, register: Register): Promise<App | undefined>;
|
|
73
94
|
export declare function listApps(owner: string | undefined, register: Register): Promise<App[]>;
|
|
74
95
|
//# sourceMappingURL=apps.d.ts.map
|
package/dist/admin/apps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;CAClC;AAED,sEAAsE;AACtE,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAKzC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC;CACxC;AAED,2EAA2E;AAC3E,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAc5F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtF;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAiBhF;AAED,0DAA0D;AAC1D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAQ1B;AAED,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAU5F"}
|
package/dist/admin/apps.js
CHANGED
|
@@ -80,6 +80,34 @@ export async function recordApp(app, register) {
|
|
|
80
80
|
return rows[0];
|
|
81
81
|
}
|
|
82
82
|
/** Apps an owner has, or every app when none is named. */
|
|
83
|
+
/**
|
|
84
|
+
* One app, if this operator may have it.
|
|
85
|
+
*
|
|
86
|
+
* The tenancy rule asked of a single row: a developer reaching for somebody
|
|
87
|
+
* else's app by name gets nothing, which is the same answer as an app that
|
|
88
|
+
* does not exist. Telling those apart would confirm what other people have
|
|
89
|
+
* named their apps, and the caller is expected to answer both the same way.
|
|
90
|
+
*
|
|
91
|
+
* This is what replaces a configured target repository. A run does not hold a
|
|
92
|
+
* repo; it resolves one — from who is asking and which app they named — and
|
|
93
|
+
* `repo` on the row it returns is the answer. Which means the authorisation
|
|
94
|
+
* and the lookup are the same call, and a caller cannot perform the second
|
|
95
|
+
* while forgetting the first.
|
|
96
|
+
*
|
|
97
|
+
* In the Core rather than in a caller because there are now three: the pages,
|
|
98
|
+
* the API, and the superagent working on somebody's app on their behalf. A
|
|
99
|
+
* tenancy rule that lives in one of them is a rule the other two can differ
|
|
100
|
+
* from.
|
|
101
|
+
*/
|
|
102
|
+
export async function appFor(user, name, register) {
|
|
103
|
+
const select = `select a.*, u.email as owner_email from apps a
|
|
104
|
+
join users u on u.id = a.owner_id
|
|
105
|
+
where lower(a.name) = lower($1)`;
|
|
106
|
+
const { rows } = user.role === "superadmin"
|
|
107
|
+
? await register.query(select, [name])
|
|
108
|
+
: await register.query(`${select} and a.owner_id = $2`, [name, user.id]);
|
|
109
|
+
return rows[0];
|
|
110
|
+
}
|
|
83
111
|
export async function listApps(owner, register) {
|
|
84
112
|
const conn = register;
|
|
85
113
|
const { rows } = owner
|
package/dist/admin/apps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"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"}
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from "./provision.ts";
|
|
|
14
14
|
export * from "./decommission.ts";
|
|
15
15
|
export * from "./migrations.ts";
|
|
16
16
|
export * from "./promote.ts";
|
|
17
|
+
export * from "./runs.ts";
|
|
17
18
|
export * from "./entrypoints.ts";
|
|
18
19
|
export * from "./chunks.ts";
|
|
19
20
|
export * from "./services/github.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAG5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAG5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
|
package/dist/admin/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export * from "./provision.js";
|
|
|
14
14
|
export * from "./decommission.js";
|
|
15
15
|
export * from "./migrations.js";
|
|
16
16
|
export * from "./promote.js";
|
|
17
|
+
export * from "./runs.js";
|
|
17
18
|
export * from "./entrypoints.js";
|
|
18
19
|
export * from "./chunks.js";
|
|
19
20
|
// One file per service, matching the registry.
|
package/dist/admin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAE5B,+CAA+C;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAE5B,+CAA+C;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the factory did, and on whose behalf.
|
|
3
|
+
*
|
|
4
|
+
* Provisioning has always returned a `Run` and never cared where it went; the
|
|
5
|
+
* CLI writes one to `~/.heychunky/runs` and says in its own header that the
|
|
6
|
+
* shape was settled and a table would take it eventually. This is that table.
|
|
7
|
+
*
|
|
8
|
+
* It matters more now than it did, because a superagent works unattended. A
|
|
9
|
+
* provisioning run had a person watching it who could say what happened; a run
|
|
10
|
+
* that classified, planned, implemented and reviewed while nobody was looking
|
|
11
|
+
* leaves nothing behind but comments on an issue and a log that ages out. The
|
|
12
|
+
* question "what has chunky been doing, and what did it cost" has had no answer
|
|
13
|
+
* anywhere.
|
|
14
|
+
*
|
|
15
|
+
* Two things are deliberately separate here:
|
|
16
|
+
*
|
|
17
|
+
* who may *start* a run on a target — `appFor` for an app, role for the
|
|
18
|
+
* factory's own repositories
|
|
19
|
+
* who may *see* a run afterwards — the operator who asked, and superadmin
|
|
20
|
+
*
|
|
21
|
+
* The second is what this file answers, and it keys on the operator rather than
|
|
22
|
+
* on the app precisely so a decommissioned app does not take its history with
|
|
23
|
+
* it.
|
|
24
|
+
*/
|
|
25
|
+
import type { Register } from "./master.ts";
|
|
26
|
+
import type { StepResult } from "./provision.ts";
|
|
27
|
+
import type { User } from "./users.ts";
|
|
28
|
+
/** Where the work came from: `github:heychunkydev/x#12`, `email`, `cli`. */
|
|
29
|
+
export type RunSource = string;
|
|
30
|
+
export interface FactoryRun {
|
|
31
|
+
id: string;
|
|
32
|
+
/** Always known. `heychunkydev/heychunky-core`. */
|
|
33
|
+
repo: string;
|
|
34
|
+
/**
|
|
35
|
+
* The app this repository belongs to, when it is one.
|
|
36
|
+
*
|
|
37
|
+
* Null means no app row — either a factory repository, which is machinery
|
|
38
|
+
* rather than somebody's app, or an app that has since been taken down. Both
|
|
39
|
+
* are read the same way on purpose: neither has an owner to answer to, so
|
|
40
|
+
* neither is a developer's to see.
|
|
41
|
+
*/
|
|
42
|
+
app_id: string | null;
|
|
43
|
+
/** Whose behalf it ran on. Never chunky's own: every run traces to a human. */
|
|
44
|
+
operator_id: string;
|
|
45
|
+
source: RunSource;
|
|
46
|
+
title: string | null;
|
|
47
|
+
/** The same shape provisioning reports, so one renderer serves both. */
|
|
48
|
+
steps: StepResult[];
|
|
49
|
+
/** What the models cost, when the caller knows. */
|
|
50
|
+
cost: string | null;
|
|
51
|
+
outcome: "running" | "done" | "failed";
|
|
52
|
+
created_at: string;
|
|
53
|
+
finished_at: string | null;
|
|
54
|
+
}
|
|
55
|
+
/** What a caller supplies. The id is theirs to choose, so a run can be updated. */
|
|
56
|
+
export interface RunRecord {
|
|
57
|
+
id: string;
|
|
58
|
+
repo: string;
|
|
59
|
+
appId?: string | null;
|
|
60
|
+
operatorId: string;
|
|
61
|
+
source: RunSource;
|
|
62
|
+
title?: string | null;
|
|
63
|
+
steps: StepResult[];
|
|
64
|
+
cost?: string | null;
|
|
65
|
+
outcome: FactoryRun["outcome"];
|
|
66
|
+
finishedAt?: string | null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Make sure the table is there.
|
|
70
|
+
*
|
|
71
|
+
* `create table if not exists`, called before a write, which is the same way
|
|
72
|
+
* the migration ledger arrives in an app's database. The register has no
|
|
73
|
+
* migration mechanism of its own — `apps` and `users` were made by hand — and
|
|
74
|
+
* inventing one to add a single table would be a larger decision than this
|
|
75
|
+
* file is entitled to make. This at least leaves the schema written down in
|
|
76
|
+
* the repository rather than only in the database.
|
|
77
|
+
*/
|
|
78
|
+
export declare function ensureRuns(register: Register): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Write a run, or bring an existing one up to date.
|
|
81
|
+
*
|
|
82
|
+
* One call rather than start/step/finish, because a station boundary is the
|
|
83
|
+
* only moment worth recording and the caller already holds the whole list by
|
|
84
|
+
* then. Upserting on the id also means a run interrupted halfway leaves the
|
|
85
|
+
* steps it did reach rather than nothing at all — the same property the
|
|
86
|
+
* migration ledger has, and for the same reason.
|
|
87
|
+
*/
|
|
88
|
+
export declare function recordRun(run: RunRecord, register: Register): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* The runs a person may see, newest first.
|
|
91
|
+
*
|
|
92
|
+
* Scoped on who asked rather than on which app, so a developer keeps the
|
|
93
|
+
* history of work they requested even after the app it touched is gone, and so
|
|
94
|
+
* runs against the factory's own repositories — which have no app and no owner
|
|
95
|
+
* — are visible to the superadmin who started them and to nobody else.
|
|
96
|
+
*/
|
|
97
|
+
export declare function listRuns(user: Pick<User, "id" | "role">, register: Register, limit?: number): Promise<FactoryRun[]>;
|
|
98
|
+
//# sourceMappingURL=runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/admin/runs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wEAAwE;IACxE,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,mDAAmD;IACnD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjF;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,EAC/B,QAAQ,EAAE,QAAQ,EAClB,KAAK,SAAK,GACT,OAAO,CAAC,UAAU,EAAE,CAAC,CAQvB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make sure the table is there.
|
|
3
|
+
*
|
|
4
|
+
* `create table if not exists`, called before a write, which is the same way
|
|
5
|
+
* the migration ledger arrives in an app's database. The register has no
|
|
6
|
+
* migration mechanism of its own — `apps` and `users` were made by hand — and
|
|
7
|
+
* inventing one to add a single table would be a larger decision than this
|
|
8
|
+
* file is entitled to make. This at least leaves the schema written down in
|
|
9
|
+
* the repository rather than only in the database.
|
|
10
|
+
*/
|
|
11
|
+
export async function ensureRuns(register) {
|
|
12
|
+
await register.write(`create table if not exists runs (
|
|
13
|
+
id uuid primary key,
|
|
14
|
+
repo text not null,
|
|
15
|
+
app_id uuid references apps(id) on delete set null,
|
|
16
|
+
operator_id uuid not null references users(id),
|
|
17
|
+
source text not null,
|
|
18
|
+
title text,
|
|
19
|
+
steps jsonb not null default '[]'::jsonb,
|
|
20
|
+
cost numeric,
|
|
21
|
+
outcome text not null default 'running',
|
|
22
|
+
created_at timestamptz not null default now(),
|
|
23
|
+
finished_at timestamptz
|
|
24
|
+
)`);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Write a run, or bring an existing one up to date.
|
|
28
|
+
*
|
|
29
|
+
* One call rather than start/step/finish, because a station boundary is the
|
|
30
|
+
* only moment worth recording and the caller already holds the whole list by
|
|
31
|
+
* then. Upserting on the id also means a run interrupted halfway leaves the
|
|
32
|
+
* steps it did reach rather than nothing at all — the same property the
|
|
33
|
+
* migration ledger has, and for the same reason.
|
|
34
|
+
*/
|
|
35
|
+
export async function recordRun(run, register) {
|
|
36
|
+
await ensureRuns(register);
|
|
37
|
+
await register.write(`insert into runs (id, repo, app_id, operator_id, source, title, steps, cost, outcome, finished_at)
|
|
38
|
+
values ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $9, $10)
|
|
39
|
+
on conflict (id) do update set
|
|
40
|
+
steps = excluded.steps,
|
|
41
|
+
cost = coalesce(excluded.cost, runs.cost),
|
|
42
|
+
outcome = excluded.outcome,
|
|
43
|
+
title = coalesce(excluded.title, runs.title),
|
|
44
|
+
finished_at = coalesce(excluded.finished_at, runs.finished_at)`, [
|
|
45
|
+
run.id, run.repo, run.appId ?? null, run.operatorId, run.source,
|
|
46
|
+
run.title ?? null, JSON.stringify(run.steps), run.cost ?? null,
|
|
47
|
+
run.outcome, run.finishedAt ?? null,
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The runs a person may see, newest first.
|
|
52
|
+
*
|
|
53
|
+
* Scoped on who asked rather than on which app, so a developer keeps the
|
|
54
|
+
* history of work they requested even after the app it touched is gone, and so
|
|
55
|
+
* runs against the factory's own repositories — which have no app and no owner
|
|
56
|
+
* — are visible to the superadmin who started them and to nobody else.
|
|
57
|
+
*/
|
|
58
|
+
export async function listRuns(user, register, limit = 50) {
|
|
59
|
+
await ensureRuns(register);
|
|
60
|
+
const select = `select * from runs`;
|
|
61
|
+
const { rows } = user.role === "superadmin"
|
|
62
|
+
? await register.query(`${select} order by created_at desc limit $1`, [limit])
|
|
63
|
+
: await register.query(`${select} where operator_id = $1 order by created_at desc limit $2`, [user.id, limit]);
|
|
64
|
+
return rows;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/admin/runs.ts"],"names":[],"mappings":"AAuEA;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAkB;IACjD,MAAM,QAAQ,CAAC,KAAK,CAClB;;;;;;;;;;;;OAYG,CACJ,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAc,EAAE,QAAkB;IAChE,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,QAAQ,CAAC,KAAK,CAClB;;;;;;;sEAOkE,EAClE;QACE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM;QAC/D,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;QAC9D,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,IAAI,IAAI;KACpC,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAA+B,EAC/B,QAAkB,EAClB,KAAK,GAAG,EAAE;IAEV,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,oBAAoB,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,YAAY;QACzC,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,MAAM,oCAAoC,EAAE,CAAC,KAAK,CAAC,CAAC;QAC9E,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAClB,GAAG,MAAM,2DAA2D,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9F,OAAO,IAA+B,CAAC;AACzC,CAAC"}
|
package/dist/admin/users.d.ts
CHANGED
|
@@ -20,6 +20,24 @@ export interface User {
|
|
|
20
20
|
role: Role;
|
|
21
21
|
created_at: string;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* The account an address belongs to, if any.
|
|
25
|
+
*
|
|
26
|
+
* The join between an inbound message and an operator. Chunky receives mail,
|
|
27
|
+
* a webhook, a form — each carries an address and nothing else, and this is
|
|
28
|
+
* what turns that into somebody the register has heard of and knows the apps
|
|
29
|
+
* of. Without it there is no answer to "on whose behalf".
|
|
30
|
+
*
|
|
31
|
+
* Matched without case, the same way `inviteUser` stores it and the unique
|
|
32
|
+
* index on `lower(email)` enforces: one person, one account, however they
|
|
33
|
+
* typed it.
|
|
34
|
+
*
|
|
35
|
+
* An address nobody owns returns undefined rather than throwing. A stranger
|
|
36
|
+
* writing to the factory is an ordinary event, not an exception — and the
|
|
37
|
+
* caller must be free to ignore it silently rather than answer a question
|
|
38
|
+
* that confirms who does and does not have an account here.
|
|
39
|
+
*/
|
|
40
|
+
export declare function userByEmail(email: string, register: Register): Promise<User | undefined>;
|
|
23
41
|
export declare class DuplicateUserError extends Error {
|
|
24
42
|
constructor(email: string);
|
|
25
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/admin/users.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG,WAAW,CAAC;AAE9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,KAAK,EAAE,MAAM;CAI1B;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,EACjE,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAef;AAED,+DAA+D;AAC/D,wBAAsB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAMnE"}
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/admin/users.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,IAAI,GAAG,YAAY,GAAG,WAAW,CAAC;AAE9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAM3B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,KAAK,EAAE,MAAM;CAI1B;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,EACjE,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,IAAI,CAAC,CAef;AAED,+DAA+D;AAC/D,wBAAsB,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAMnE"}
|
package/dist/admin/users.js
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The account an address belongs to, if any.
|
|
3
|
+
*
|
|
4
|
+
* The join between an inbound message and an operator. Chunky receives mail,
|
|
5
|
+
* a webhook, a form — each carries an address and nothing else, and this is
|
|
6
|
+
* what turns that into somebody the register has heard of and knows the apps
|
|
7
|
+
* of. Without it there is no answer to "on whose behalf".
|
|
8
|
+
*
|
|
9
|
+
* Matched without case, the same way `inviteUser` stores it and the unique
|
|
10
|
+
* index on `lower(email)` enforces: one person, one account, however they
|
|
11
|
+
* typed it.
|
|
12
|
+
*
|
|
13
|
+
* An address nobody owns returns undefined rather than throwing. A stranger
|
|
14
|
+
* writing to the factory is an ordinary event, not an exception — and the
|
|
15
|
+
* caller must be free to ignore it silently rather than answer a question
|
|
16
|
+
* that confirms who does and does not have an account here.
|
|
17
|
+
*/
|
|
18
|
+
export async function userByEmail(email, register) {
|
|
19
|
+
const { rows } = await register.query("select id, email, name, role, created_at from users where lower(email) = lower($1)", [email]);
|
|
20
|
+
return rows[0];
|
|
21
|
+
}
|
|
1
22
|
export class DuplicateUserError extends Error {
|
|
2
23
|
constructor(email) {
|
|
3
24
|
super(`${email} already has an account`);
|
package/dist/admin/users.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/admin/users.ts"],"names":[],"mappings":"AAyBA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,KAAa;QACvB,KAAK,CAAC,GAAG,KAAK,yBAAyB,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAiE,EACjE,QAAkB;IAElB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;IAE5E,MAAM,IAAI,GAAG,QAAQ,CAAC;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;iDAE6C,EAC7C,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC,CACzD,CAAC;IACF,6EAA6E;IAC7E,wDAAwD;IACxD,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,CAAC,CAAoB,CAAC;AACpC,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB;IAChD,MAAM,IAAI,GAAG,QAAQ,CAAC;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B,yEAAyE,CAC1E,CAAC;IACF,OAAO,IAAyB,CAAC;AACnC,CAAC"}
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/admin/users.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAa,EACb,QAAkB;IAElB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC,KAAK,CACnC,oFAAoF,EACpF,CAAC,KAAK,CAAC,CACR,CAAC;IACF,OAAO,IAAI,CAAC,CAAC,CAAgC,CAAC;AAChD,CAAC;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,KAAa;QACvB,KAAK,CAAC,GAAG,KAAK,yBAAyB,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAiE,EACjE,QAAkB;IAElB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;IAE5E,MAAM,IAAI,GAAG,QAAQ,CAAC;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;iDAE6C,EAC7C,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC,CACzD,CAAC;IACF,6EAA6E;IAC7E,wDAAwD;IACxD,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,CAAC,CAAoB,CAAC;AACpC,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAkB;IAChD,MAAM,IAAI,GAAG,QAAQ,CAAC;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B,yEAAyE,CAC1E,CAAC;IACF,OAAO,IAAyB,CAAC;AACnC,CAAC"}
|