@heychunky/core 0.8.1 → 0.9.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.map +1 -1
- package/dist/admin/apps.js +10 -1
- package/dist/admin/apps.js.map +1 -1
- package/dist/admin/chunks.d.ts +82 -0
- package/dist/admin/chunks.d.ts.map +1 -1
- package/dist/admin/chunks.js +156 -17
- package/dist/admin/chunks.js.map +1 -1
- package/dist/admin/decommission.d.ts +40 -0
- package/dist/admin/decommission.d.ts.map +1 -0
- package/dist/admin/decommission.js +134 -0
- package/dist/admin/decommission.js.map +1 -0
- package/dist/admin/entrypoints.d.ts +16 -0
- package/dist/admin/entrypoints.d.ts.map +1 -0
- package/dist/admin/entrypoints.js +41 -0
- package/dist/admin/entrypoints.js.map +1 -0
- package/dist/admin/index.d.ts +2 -0
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +2 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/provision.d.ts.map +1 -1
- package/dist/admin/provision.js +116 -4
- package/dist/admin/provision.js.map +1 -1
- package/dist/admin/services/bunny.d.ts +3 -0
- package/dist/admin/services/bunny.d.ts.map +1 -1
- package/dist/admin/services/bunny.js +12 -0
- package/dist/admin/services/bunny.js.map +1 -1
- package/dist/admin/services/cloudflare.d.ts +11 -0
- package/dist/admin/services/cloudflare.d.ts.map +1 -1
- package/dist/admin/services/cloudflare.js +19 -0
- package/dist/admin/services/cloudflare.js.map +1 -1
- package/dist/admin/services/github.d.ts +3 -0
- package/dist/admin/services/github.d.ts.map +1 -1
- package/dist/admin/services/github.js +29 -1
- package/dist/admin/services/github.js.map +1 -1
- package/dist/admin/services/neon.d.ts +3 -0
- package/dist/admin/services/neon.d.ts.map +1 -1
- package/dist/admin/services/neon.js +16 -0
- package/dist/admin/services/neon.js.map +1 -1
- package/dist/admin/services/vercel.d.ts +19 -9
- package/dist/admin/services/vercel.d.ts.map +1 -1
- package/dist/admin/services/vercel.js +40 -7
- package/dist/admin/services/vercel.js.map +1 -1
- package/dist/config/environments.d.ts +41 -1
- package/dist/config/environments.d.ts.map +1 -1
- package/dist/config/environments.js +50 -1
- package/dist/config/environments.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +8 -0
- package/dist/registry.js.map +1 -1
- package/package.json +4 -1
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;AAEjD,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,
|
|
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;AAEjD,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,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
|
@@ -44,7 +44,16 @@ export async function assertCanCreate(owner, register) {
|
|
|
44
44
|
const row = rows[0];
|
|
45
45
|
if (!row)
|
|
46
46
|
throw new Error("No such owner.");
|
|
47
|
-
|
|
47
|
+
// No limit recorded means no ceiling, not a ceiling of zero. Number(null) is
|
|
48
|
+
// 0 and `owned >= 0` is always true, so reading it the other way locks
|
|
49
|
+
// somebody out of their own account — and does it silently, at the moment
|
|
50
|
+
// they try to build something.
|
|
51
|
+
const raw = row["app_limit"];
|
|
52
|
+
if (raw === null || raw === undefined)
|
|
53
|
+
return;
|
|
54
|
+
const limit = Number(raw);
|
|
55
|
+
if (!Number.isFinite(limit))
|
|
56
|
+
return;
|
|
48
57
|
if (Number(row["owned"]) >= limit)
|
|
49
58
|
throw new AppLimitError(String(row["email"]), limit);
|
|
50
59
|
}
|
package/dist/admin/apps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"AA+BA,sEAAsE;AACtE,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,KAAK,CAAS;IACvB,YAAY,KAAa,EAAE,KAAa;QACtC,KAAK,CAAC,GAAG,KAAK,gBAAgB,KAAK,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,CAAC;QAC3F,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAkBD,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAyB,EAAE,QAAkB;IACzE,MAAM,IAAI,GAAG,QAAQ,CAAC;IACtB,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,qDAAqD,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAClG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,kDAAkD,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC;IACD,4EAA4E;IAC5E,0DAA0D;IAC1D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpF,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IAC9E,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;AACpB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa,EAAE,QAAkB;IACrE,MAAM,IAAI,GAAG,QAAQ,CAAC;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;oCAEgC,EAChC,CAAC,KAAK,CAAC,CACR,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"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"}
|
package/dist/admin/chunks.d.ts
CHANGED
|
@@ -25,6 +25,43 @@ export interface ChunkManifest {
|
|
|
25
25
|
tags: string[];
|
|
26
26
|
/** npm packages the chunk needs at runtime. Ours are files; these are not. */
|
|
27
27
|
dependencies: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Other chunks this one will not work without.
|
|
30
|
+
*
|
|
31
|
+
* A real dependency graph — sitenav does not render without coreui's button
|
|
32
|
+
* — and one that is kept shallow on purpose. A deep chunk graph reproduces
|
|
33
|
+
* the dependency hell the copy-and-own model exists to avoid, so a chunk
|
|
34
|
+
* that needs four others is usually one chunk pretending to be five.
|
|
35
|
+
*/
|
|
36
|
+
requires?: {
|
|
37
|
+
chunks?: string[];
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Stylesheets the chunk ships, in the order they should be imported.
|
|
41
|
+
*
|
|
42
|
+
* Declared rather than inferred from the file list: a chunk's CSS has to be
|
|
43
|
+
* imported by something or it lands in the repository and styles nothing,
|
|
44
|
+
* which is exactly what happened to the first chunk on the shelf.
|
|
45
|
+
*/
|
|
46
|
+
styles?: string[];
|
|
47
|
+
/**
|
|
48
|
+
* SQL the chunk needs run against the app's own database, before its code
|
|
49
|
+
* is deployed. Written to be safe to run twice — `create table if not
|
|
50
|
+
* exists`, `add column if not exists` — because a chunk you can ask for
|
|
51
|
+
* twice is the whole point, and half of these will have run already.
|
|
52
|
+
*/
|
|
53
|
+
sql?: string[];
|
|
54
|
+
/**
|
|
55
|
+
* Environment variables the chunk needs, and what each is for.
|
|
56
|
+
*
|
|
57
|
+
* Named, never valued. A chunk cannot know somebody's Resend key, and the
|
|
58
|
+
* useful thing it can do is say which keys are missing rather than deploy an
|
|
59
|
+
* app that boots broken and blames the developer.
|
|
60
|
+
*/
|
|
61
|
+
env?: {
|
|
62
|
+
key: string;
|
|
63
|
+
what: string;
|
|
64
|
+
}[];
|
|
28
65
|
options: ChunkOption[];
|
|
29
66
|
/** Where the config file lands, if it has one. */
|
|
30
67
|
config?: string;
|
|
@@ -33,10 +70,24 @@ export interface ChunkFile {
|
|
|
33
70
|
/** Path in the app, relative to its root. */
|
|
34
71
|
path: string;
|
|
35
72
|
content: string;
|
|
73
|
+
/**
|
|
74
|
+
* Set for files that are not text.
|
|
75
|
+
*
|
|
76
|
+
* A chunk that renders a logo has to ship the logo, and a PNG decoded as
|
|
77
|
+
* UTF-8 and written back is noise. Base64 passes through both ends untouched.
|
|
78
|
+
*/
|
|
79
|
+
encoding?: "base64";
|
|
36
80
|
}
|
|
37
81
|
export interface AddResult {
|
|
38
82
|
chunk: string;
|
|
39
83
|
app: string;
|
|
84
|
+
/** Statements run against the app's database. */
|
|
85
|
+
migrated: number;
|
|
86
|
+
/** Variables the chunk needs that the app does not have. */
|
|
87
|
+
missing: {
|
|
88
|
+
key: string;
|
|
89
|
+
what: string;
|
|
90
|
+
}[];
|
|
40
91
|
/** What was written, in the order it was written. */
|
|
41
92
|
files: string[];
|
|
42
93
|
/** The commit, or undefined when nothing needed doing. */
|
|
@@ -59,6 +110,18 @@ export declare function readChunk(name: string, ctx: RunContext): Promise<{
|
|
|
59
110
|
manifest: ChunkManifest;
|
|
60
111
|
files: ChunkFile[];
|
|
61
112
|
}>;
|
|
113
|
+
/**
|
|
114
|
+
* A chunk and everything it will not work without, dependencies first.
|
|
115
|
+
*
|
|
116
|
+
* Depth-first so a dependency is always written before the chunk that imports
|
|
117
|
+
* it, and cycle-aware because a graph that can be declared can be declared
|
|
118
|
+
* wrong. Returned as one flat list: the caller writes them in a single commit,
|
|
119
|
+
* so an app never exists in a state where half a chunk's imports resolve.
|
|
120
|
+
*/
|
|
121
|
+
export declare function resolveChunk(name: string, ctx: RunContext, seen?: string[]): Promise<{
|
|
122
|
+
manifest: ChunkManifest;
|
|
123
|
+
files: ChunkFile[];
|
|
124
|
+
}[]>;
|
|
62
125
|
/** The config file, written from the chunk's own declared defaults. */
|
|
63
126
|
export declare function configFor(manifest: ChunkManifest): string | undefined;
|
|
64
127
|
export interface AddWatcher {
|
|
@@ -72,9 +135,28 @@ export interface AddWatcher {
|
|
|
72
135
|
* already there with the content it would be given, nothing is written and the
|
|
73
136
|
* run says so. That is what makes it safe to ask twice.
|
|
74
137
|
*/
|
|
138
|
+
/**
|
|
139
|
+
* Register a chunk's stylesheets with the app.
|
|
140
|
+
*
|
|
141
|
+
* A stylesheet that lands in the repository and is imported by nothing styles
|
|
142
|
+
* nothing — the first chunk on the shelf shipped four components and none of
|
|
143
|
+
* their CSS, and no part of the pipeline noticed. `index.css` is where an app
|
|
144
|
+
* collects its imports, and it holds only imports, which is what the CSS rule
|
|
145
|
+
* that `@import` must precede every other rule requires.
|
|
146
|
+
*
|
|
147
|
+
* Returns the file to write, or undefined when every import is already there.
|
|
148
|
+
*/
|
|
149
|
+
export declare function registerStyles(index: {
|
|
150
|
+
path: string;
|
|
151
|
+
content: string;
|
|
152
|
+
}, styles: string[], uiDir: string): ChunkFile | undefined;
|
|
75
153
|
export declare function addChunk(opts: {
|
|
76
154
|
chunk: string;
|
|
77
155
|
repo: string;
|
|
78
156
|
app: string;
|
|
157
|
+
/** Runs one statement against the app's own database. */
|
|
158
|
+
migrate: (sql: string) => Promise<void>;
|
|
159
|
+
/** The names of variables the app already has set. */
|
|
160
|
+
envKeys: () => Promise<string[]>;
|
|
79
161
|
}, ctx: RunContext, watch?: AddWatcher): Promise<AddResult>;
|
|
80
162
|
//# sourceMappingURL=chunks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunks.d.ts","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"chunks.d.ts","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"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"}
|
package/dist/admin/chunks.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import { github } from "./services/github.js";
|
|
20
20
|
import { vercel } from "./services/vercel.js";
|
|
21
21
|
import { KEY_FOR } from "./run.js";
|
|
22
|
+
import { entryPoints } from "./entrypoints.js";
|
|
22
23
|
import { DEFAULT_BRANCH } from "../config/environments.js";
|
|
23
24
|
/**
|
|
24
25
|
* Where the chunks live. Folders in one repository, one per chunk.
|
|
@@ -29,6 +30,14 @@ import { DEFAULT_BRANCH } from "../config/environments.js";
|
|
|
29
30
|
* cannot happen here.
|
|
30
31
|
*/
|
|
31
32
|
export const CHUNKS_REPO = "heychunkydev/chunks";
|
|
33
|
+
/**
|
|
34
|
+
* What must not be decoded on the way through.
|
|
35
|
+
*
|
|
36
|
+
* By extension rather than by sniffing: a chunk's file list is known before
|
|
37
|
+
* anything is fetched, and guessing from content would mean downloading it
|
|
38
|
+
* wrongly first to find out.
|
|
39
|
+
*/
|
|
40
|
+
const BINARY = /\.(png|jpe?g|gif|webp|avif|ico|svgz|woff2?|ttf|otf|eot|mp4|webm|pdf|zip)$/i;
|
|
32
41
|
export class NoSuchChunk extends Error {
|
|
33
42
|
constructor(name) {
|
|
34
43
|
super(`No chunk called "${name}"`);
|
|
@@ -61,13 +70,39 @@ export async function readChunk(name, ctx) {
|
|
|
61
70
|
const manifest = JSON.parse(raw);
|
|
62
71
|
const files = [];
|
|
63
72
|
for (const path of await gh.listFiles(CHUNKS_REPO, `${root}/files`)) {
|
|
73
|
+
const binary = BINARY.test(path);
|
|
64
74
|
files.push({
|
|
65
75
|
path: path.slice(`${root}/files/`.length),
|
|
66
|
-
content: await gh.readFile(CHUNKS_REPO, path),
|
|
76
|
+
content: binary ? await gh.readBinaryFile(CHUNKS_REPO, path) : await gh.readFile(CHUNKS_REPO, path),
|
|
77
|
+
...(binary ? { encoding: "base64" } : {}),
|
|
67
78
|
});
|
|
68
79
|
}
|
|
69
80
|
return { manifest, files };
|
|
70
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* A chunk and everything it will not work without, dependencies first.
|
|
84
|
+
*
|
|
85
|
+
* Depth-first so a dependency is always written before the chunk that imports
|
|
86
|
+
* it, and cycle-aware because a graph that can be declared can be declared
|
|
87
|
+
* wrong. Returned as one flat list: the caller writes them in a single commit,
|
|
88
|
+
* so an app never exists in a state where half a chunk's imports resolve.
|
|
89
|
+
*/
|
|
90
|
+
export async function resolveChunk(name, ctx, seen = []) {
|
|
91
|
+
if (seen.includes(name)) {
|
|
92
|
+
throw new Error(`Chunk dependencies form a cycle: ${[...seen, name].join(" → ")}`);
|
|
93
|
+
}
|
|
94
|
+
const read = await readChunk(name, ctx);
|
|
95
|
+
const out = [];
|
|
96
|
+
for (const required of read.manifest.requires?.chunks ?? []) {
|
|
97
|
+
for (const dep of await resolveChunk(required, ctx, [...seen, name])) {
|
|
98
|
+
// A chunk two others need is read twice and written once.
|
|
99
|
+
if (!out.some((c) => c.manifest.name === dep.manifest.name))
|
|
100
|
+
out.push(dep);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
out.push(read);
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
71
106
|
/** The config file, written from the chunk's own declared defaults. */
|
|
72
107
|
export function configFor(manifest) {
|
|
73
108
|
if (!manifest.config || !manifest.options.length)
|
|
@@ -91,24 +126,97 @@ ${lines.join("\n")}
|
|
|
91
126
|
* already there with the content it would be given, nothing is written and the
|
|
92
127
|
* run says so. That is what makes it safe to ask twice.
|
|
93
128
|
*/
|
|
129
|
+
/**
|
|
130
|
+
* Register a chunk's stylesheets with the app.
|
|
131
|
+
*
|
|
132
|
+
* A stylesheet that lands in the repository and is imported by nothing styles
|
|
133
|
+
* nothing — the first chunk on the shelf shipped four components and none of
|
|
134
|
+
* their CSS, and no part of the pipeline noticed. `index.css` is where an app
|
|
135
|
+
* collects its imports, and it holds only imports, which is what the CSS rule
|
|
136
|
+
* that `@import` must precede every other rule requires.
|
|
137
|
+
*
|
|
138
|
+
* Returns the file to write, or undefined when every import is already there.
|
|
139
|
+
*/
|
|
140
|
+
export function registerStyles(index, styles, uiDir) {
|
|
141
|
+
let content = index.content;
|
|
142
|
+
let added = 0;
|
|
143
|
+
for (const style of styles) {
|
|
144
|
+
// Relative to index.css, which sits at the root of the ui directory.
|
|
145
|
+
const rel = `./${style.startsWith(`${uiDir}/`) ? style.slice(uiDir.length + 1) : style}`;
|
|
146
|
+
const line = `@import "${rel}";`;
|
|
147
|
+
if (content.includes(line))
|
|
148
|
+
continue;
|
|
149
|
+
const imports = [...content.matchAll(/^@import .*;$/gm)];
|
|
150
|
+
const last = imports.at(-1);
|
|
151
|
+
if (last?.index === undefined) {
|
|
152
|
+
content = `${line}\n${content}`;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const at = last.index + last[0].length;
|
|
156
|
+
content = `${content.slice(0, at)}\n${line}${content.slice(at)}`;
|
|
157
|
+
}
|
|
158
|
+
added += 1;
|
|
159
|
+
}
|
|
160
|
+
return added ? { path: index.path, content } : undefined;
|
|
161
|
+
}
|
|
162
|
+
/** Where this app keeps its stylesheets, as its own manifest declares. */
|
|
163
|
+
async function uiDirOf(repo, gh) {
|
|
164
|
+
try {
|
|
165
|
+
const raw = await gh.readFile(repo, "heychunky.json");
|
|
166
|
+
const ui = JSON.parse(raw).ui;
|
|
167
|
+
if (ui?.dir)
|
|
168
|
+
return ui.dir;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// An app without a manifest is one provisioned before the format had one.
|
|
172
|
+
}
|
|
173
|
+
return ".heychunky/ui";
|
|
174
|
+
}
|
|
94
175
|
export async function addChunk(opts, ctx, watch) {
|
|
95
176
|
const { gh, vc } = await clients(ctx);
|
|
96
177
|
watch?.start?.("read chunk");
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
178
|
+
// The chunk and everything it will not work without, dependencies first, so
|
|
179
|
+
// an app never exists in a state where half of an import resolves.
|
|
180
|
+
const resolved = await resolveChunk(opts.chunk, ctx);
|
|
181
|
+
const manifest = resolved.at(-1).manifest;
|
|
182
|
+
const all = [];
|
|
183
|
+
for (const { manifest: m, files } of resolved) {
|
|
184
|
+
all.push(...files);
|
|
185
|
+
// Generated only when the chunk does not ship one of its own. A chunk that
|
|
186
|
+
// hand-writes its config knows something the generator does not, and adding
|
|
187
|
+
// a second file at the same path put it in the list twice.
|
|
188
|
+
const shipped = m.config && files.some((f) => f.path === m.config);
|
|
189
|
+
const config = shipped ? undefined : configFor(m);
|
|
190
|
+
if (config && m.config) {
|
|
191
|
+
// And only if it is not already in the app: this file is the developer's
|
|
192
|
+
// once written, and rewriting it would silently undo their settings.
|
|
193
|
+
const existing = await gh.readFile(opts.repo, m.config).catch(() => undefined);
|
|
194
|
+
if (existing === undefined)
|
|
195
|
+
all.push({ path: m.config, content: config });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Stylesheets have to be imported by something. `index.css` is where an app
|
|
199
|
+
// collects them, and its location is the app's decision rather than ours.
|
|
200
|
+
const styles = resolved.flatMap((c) => c.manifest.styles ?? []);
|
|
201
|
+
if (styles.length) {
|
|
202
|
+
const uiDir = await uiDirOf(opts.repo, gh);
|
|
203
|
+
const path = `${uiDir}/index.css`;
|
|
204
|
+
const content = await gh.readFile(opts.repo, path).catch(() => undefined);
|
|
205
|
+
if (content === undefined) {
|
|
206
|
+
all.push({ path, content: styles.map((s) => `@import "./${s.slice(uiDir.length + 1)}";`).join("\n") + "\n" });
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const updated = registerStyles({ path, content }, styles, uiDir);
|
|
210
|
+
if (updated)
|
|
211
|
+
all.push(updated);
|
|
212
|
+
}
|
|
110
213
|
}
|
|
111
|
-
|
|
214
|
+
// `src/app/` is derived from the manifest, so anything the manifest gained
|
|
215
|
+
// and the target has not is regenerated in the same commit as the chunk.
|
|
216
|
+
// A route that exists in one and not the other is a page nobody can visit.
|
|
217
|
+
all.push(...(await entryPoints(opts.repo, gh)));
|
|
218
|
+
const named = resolved.map((c) => c.manifest.name).join(" → ");
|
|
219
|
+
watch?.done?.("read chunk", `${named} · ${all.length} files`);
|
|
112
220
|
watch?.start?.("check app");
|
|
113
221
|
const unchanged = [];
|
|
114
222
|
for (const file of all) {
|
|
@@ -118,9 +226,23 @@ export async function addChunk(opts, ctx, watch) {
|
|
|
118
226
|
}
|
|
119
227
|
if (unchanged.length === all.length) {
|
|
120
228
|
watch?.done?.("check app", "already there, nothing to do");
|
|
121
|
-
return { chunk: opts.chunk, app: opts.app, files: [], already: true };
|
|
229
|
+
return { chunk: opts.chunk, app: opts.app, files: [], migrated: 0, missing: [], already: true };
|
|
122
230
|
}
|
|
123
231
|
watch?.done?.("check app", `${all.length - unchanged.length} to write`);
|
|
232
|
+
// Before the code that needs them, so a deployment never lands on a schema
|
|
233
|
+
// that has not caught up. Failing here stops the run with nothing written.
|
|
234
|
+
let migrated = 0;
|
|
235
|
+
// In dependency order: a chunk's tables may reference a table its dependency
|
|
236
|
+
// creates, and resolveChunk already put them in that order.
|
|
237
|
+
const statements = resolved.flatMap((c) => c.manifest.sql ?? []);
|
|
238
|
+
if (statements.length) {
|
|
239
|
+
watch?.start?.("database");
|
|
240
|
+
for (const statement of statements) {
|
|
241
|
+
await opts.migrate(statement);
|
|
242
|
+
migrated += 1;
|
|
243
|
+
}
|
|
244
|
+
watch?.done?.("database", `${migrated} statement${migrated === 1 ? "" : "s"}`);
|
|
245
|
+
}
|
|
124
246
|
watch?.start?.("write files");
|
|
125
247
|
const commit = await gh.commitFiles(opts.repo, {
|
|
126
248
|
branch: DEFAULT_BRANCH,
|
|
@@ -128,6 +250,20 @@ export async function addChunk(opts, ctx, watch) {
|
|
|
128
250
|
files: all,
|
|
129
251
|
});
|
|
130
252
|
watch?.done?.("write files", `${all.length} files · ${commit.slice(0, 7)}`);
|
|
253
|
+
// Named, not filled. A chunk cannot know somebody's Resend key; what it can
|
|
254
|
+
// do is say which are missing rather than let the app boot broken.
|
|
255
|
+
const missing = [];
|
|
256
|
+
const wanted = resolved.flatMap((c) => c.manifest.env ?? []);
|
|
257
|
+
if (wanted.length) {
|
|
258
|
+
watch?.start?.("settings");
|
|
259
|
+
const have = new Set(await opts.envKeys());
|
|
260
|
+
for (const e of wanted)
|
|
261
|
+
if (!have.has(e.key) && !missing.some((m) => m.key === e.key))
|
|
262
|
+
missing.push(e);
|
|
263
|
+
watch?.done?.("settings", missing.length
|
|
264
|
+
? `${missing.length} still needed: ${missing.map((m) => m.key).join(", ")}`
|
|
265
|
+
: "everything it needs is set");
|
|
266
|
+
}
|
|
131
267
|
watch?.start?.("deploy");
|
|
132
268
|
const built = await vc.deploy(opts.app, {
|
|
133
269
|
repo: opts.repo,
|
|
@@ -136,6 +272,9 @@ export async function addChunk(opts, ctx, watch) {
|
|
|
136
272
|
teamId: await vc.teamId(),
|
|
137
273
|
});
|
|
138
274
|
watch?.done?.("deploy", `${built.url} · building`);
|
|
139
|
-
return {
|
|
275
|
+
return {
|
|
276
|
+
chunk: opts.chunk, app: opts.app,
|
|
277
|
+
files: all.map((f) => f.path), commit, migrated, missing, already: false,
|
|
278
|
+
};
|
|
140
279
|
}
|
|
141
280
|
//# sourceMappingURL=chunks.js.map
|
package/dist/admin/chunks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunks.js","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"chunks.js","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,GAAG,4EAA4E,CAAC;AAqF5F,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,IAAY;QACtB,KAAK,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,KAAK,UAAU,OAAO,CAAC,GAAe;IACpC,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAE,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAY,EACZ,GAAe;IAEf,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,UAAU,IAAI,EAAE,CAAC;IAE9B,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,IAAI,aAAa,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAElD,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC;YACzC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;YACnG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,GAAe,EACf,OAAiB,EAAE;IAEnB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAsD,EAAE,CAAC;IAClE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;QAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YACrE,0DAA0D;YAC1D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,SAAS,CAAC,QAAuB;IAC/C,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CACzG,CAAC;IACF,OAAO;UACC,QAAQ,CAAC,IAAI;;;;;eAKR,QAAQ,CAAC,IAAI;EAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;;CAEjB,CAAC;AACF,CAAC;AAOD;;;;;;GAMG;AACH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAwC,EACxC,MAAgB,EAChB,KAAa;IAEb,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,qEAAqE;QACrE,MAAM,GAAG,GAAG,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QACzF,MAAM,IAAI,GAAG,YAAY,GAAG,IAAI,CAAC;QACjC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QACrC,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,IAAI,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,GAAG,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACvC,OAAO,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACnE,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED,0EAA0E;AAC1E,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,EAAuD;IAC1F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QACtD,MAAM,EAAE,GAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAA+B,CAAC,EAAE,CAAC;QAC7D,IAAI,EAAE,EAAE,GAAG;YAAE,OAAO,EAAE,CAAC,GAAG,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;IAC5E,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAQC,EACD,GAAe,EACf,KAAkB;IAElB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAEtC,KAAK,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC;IAC7B,4EAA4E;IAC5E,mEAAmE;IACnE,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC;IAC3C,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,KAAK,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC9C,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QACnB,2EAA2E;QAC3E,4EAA4E;QAC5E,2DAA2D;QAC3D,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACvB,yEAAyE;YACzE,qEAAqE;YACrE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC/E,IAAI,QAAQ,KAAK,SAAS;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,0EAA0E;IAC1E,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAChE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,GAAG,KAAK,YAAY,CAAC;QAClC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1E,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QAChH,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YACjE,IAAI,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,yEAAyE;IACzE,2EAA2E;IAC3E,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/D,KAAK,EAAE,IAAI,EAAE,CAAC,YAAY,EAAE,GAAG,KAAK,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,CAAC;IAE9D,KAAK,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC;IAC5B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO;YAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;QACpC,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,8BAA8B,CAAC,CAAC;QAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAClG,CAAC;IACD,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,WAAW,CAAC,CAAC;IAExE,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,6EAA6E;IAC7E,4DAA4D;IAC5D,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACjE,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC;QAC3B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC9B,QAAQ,IAAI,CAAC,CAAC;QAChB,CAAC;QACD,KAAK,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,GAAG,QAAQ,aAAa,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,KAAK,EAAE,KAAK,EAAE,CAAC,aAAa,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,WAAW,QAAQ,CAAC,IAAI,aAAa,QAAQ,CAAC,OAAO,oIAAoI;QAClM,KAAK,EAAE,GAAG;KACX,CAAC,CAAC;IACH,KAAK,EAAE,IAAI,EAAE,CAAC,aAAa,EAAE,GAAG,GAAG,CAAC,MAAM,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAE5E,4EAA4E;IAC5E,mEAAmE;IACnE,MAAM,OAAO,GAAoC,EAAE,CAAC;IACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAC7D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvG,KAAK,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM;YACtC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,kBAAkB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3E,CAAC,CAAC,4BAA4B,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACtC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,cAAc;QACnB,MAAM,EAAE,YAAY;QACpB,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE;KAC1B,CAAC,CAAC;IACH,KAAK,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,GAAG,aAAa,CAAC,CAAC;IAEnD,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG;QAChC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK;KACzE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type RunContext } from "./run.ts";
|
|
2
|
+
import type { StepResult } from "./provision.ts";
|
|
3
|
+
export interface Teardown {
|
|
4
|
+
/** The app's name, as provisioning knew it. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Its organisation. Defaults to the factory's, as provisioning does. */
|
|
7
|
+
org?: string;
|
|
8
|
+
/** The address it was given. Defaults to the apps-zone subdomain. */
|
|
9
|
+
domain?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Remove the repository too.
|
|
12
|
+
*
|
|
13
|
+
* Separate from the rest because it is the only irreversible loss that is
|
|
14
|
+
* not a cost: the infrastructure can be rebuilt from the code, and the code
|
|
15
|
+
* cannot be rebuilt from anything.
|
|
16
|
+
*/
|
|
17
|
+
repo?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface Removal {
|
|
20
|
+
app: string;
|
|
21
|
+
/** True when nothing was removed, because nothing was confirmed. */
|
|
22
|
+
planned: boolean;
|
|
23
|
+
steps: StepResult[];
|
|
24
|
+
/** Every step reached a good state. */
|
|
25
|
+
ok: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface Watcher {
|
|
28
|
+
start?(step: string): void;
|
|
29
|
+
done?(step: string, detail: string): void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* What has to go, and how to find it.
|
|
33
|
+
*
|
|
34
|
+
* Each step looks the resource up before touching it, so an app that was never
|
|
35
|
+
* fully provisioned — or was taken down halfway yesterday — reports "gone"
|
|
36
|
+
* rather than failing on something that was never there.
|
|
37
|
+
*/
|
|
38
|
+
export declare function decommission(spec: Teardown, ctx: RunContext, watch?: Watcher): Promise<Removal>;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=decommission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decommission.d.ts","sourceRoot":"","sources":["../../src/admin/decommission.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,gBAAgB,CAAC;AAE5D,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAC;CACb;AAED,UAAU,OAAO;IACf,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,UAAU,EACf,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,OAAO,CAAC,CAgHlB"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taking an app down.
|
|
3
|
+
*
|
|
4
|
+
* The counterpart to `provision`, and the reason it had to exist: until this
|
|
5
|
+
* did, an app could be created and never removed. Every app ever made kept a
|
|
6
|
+
* Neon project, a Vercel project and a storage zone billing for as long as the
|
|
7
|
+
* account lived, and the only things that could be deleted — a repository and
|
|
8
|
+
* a DNS record — were the two that cost nothing.
|
|
9
|
+
*
|
|
10
|
+
* Order is deliberate and runs the opposite way to creation:
|
|
11
|
+
*
|
|
12
|
+
* 1. the address, so nothing is being served while the rest goes
|
|
13
|
+
* 2. the hosting project
|
|
14
|
+
* 3. the database
|
|
15
|
+
* 4. the storage
|
|
16
|
+
* 5. the repository, last, because the code is the one thing somebody might
|
|
17
|
+
* still want and the one thing nobody can rebuild
|
|
18
|
+
*
|
|
19
|
+
* A failure stops the run where it stands rather than pressing on, so a
|
|
20
|
+
* half-removed app is reported as exactly that and can be asked again.
|
|
21
|
+
*/
|
|
22
|
+
import { github } from "./services/github.js";
|
|
23
|
+
import { vercel } from "./services/vercel.js";
|
|
24
|
+
import { neon } from "./services/neon.js";
|
|
25
|
+
import { cloudflare } from "./services/cloudflare.js";
|
|
26
|
+
import { bunny } from "./services/bunny.js";
|
|
27
|
+
import { KEY_FOR } from "./run.js";
|
|
28
|
+
import { DEFAULT_ORG, defaultDomain, stagingDomain } from "../config/environments.js";
|
|
29
|
+
/**
|
|
30
|
+
* What has to go, and how to find it.
|
|
31
|
+
*
|
|
32
|
+
* Each step looks the resource up before touching it, so an app that was never
|
|
33
|
+
* fully provisioned — or was taken down halfway yesterday — reports "gone"
|
|
34
|
+
* rather than failing on something that was never there.
|
|
35
|
+
*/
|
|
36
|
+
export async function decommission(spec, ctx, watch) {
|
|
37
|
+
const key = (service) => ctx.secrets.get(ctx.reference(KEY_FOR[service]));
|
|
38
|
+
const [g, v, n, c, b] = await Promise.all([
|
|
39
|
+
key("github"), key("vercel"), key("neon"), key("cloudflare"), key("bunny"),
|
|
40
|
+
]);
|
|
41
|
+
const gh = github(g), vc = vercel(v), nn = neon(n), cf = cloudflare(c), bn = bunny(b);
|
|
42
|
+
const domain = spec.domain ?? defaultDomain(spec.name);
|
|
43
|
+
/**
|
|
44
|
+
* Every name this factory pointed at the app.
|
|
45
|
+
*
|
|
46
|
+
* Staging has an address of its own, and a record left behind in Cloudflare
|
|
47
|
+
* after the project it pointed at is gone is precisely the orphan this run
|
|
48
|
+
* exists to prevent — cheaper than a database, and just as much a lie about
|
|
49
|
+
* what still exists.
|
|
50
|
+
*/
|
|
51
|
+
const domains = [domain, stagingDomain(domain)];
|
|
52
|
+
const repo = `${spec.org ?? DEFAULT_ORG}/${spec.name}`;
|
|
53
|
+
const steps = [];
|
|
54
|
+
let ok = true;
|
|
55
|
+
const run = async (step, find, remove) => {
|
|
56
|
+
if (!ok)
|
|
57
|
+
return;
|
|
58
|
+
watch?.start?.(step);
|
|
59
|
+
try {
|
|
60
|
+
const found = await find();
|
|
61
|
+
if (found === undefined) {
|
|
62
|
+
settle(step, "exists", "gone already");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!ctx.confirmed) {
|
|
66
|
+
settle(step, "would-create", `would remove ${found}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
settle(step, "created", await remove());
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
ok = false;
|
|
73
|
+
settle(step, "failed", error instanceof Error ? error.message : String(error));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const settle = (step, state, detail) => {
|
|
77
|
+
steps.push({ step, state, detail });
|
|
78
|
+
watch?.done?.(step, detail);
|
|
79
|
+
};
|
|
80
|
+
// The address first: whatever else fails, nothing is still being served.
|
|
81
|
+
const pointedHere = async () => {
|
|
82
|
+
const here = [];
|
|
83
|
+
for (const name of domains) {
|
|
84
|
+
const zone = await cf.zoneFor(name);
|
|
85
|
+
if (!zone)
|
|
86
|
+
continue;
|
|
87
|
+
if ((await cf.dnsRecords(zone.name)).some((r) => r.name === name))
|
|
88
|
+
here.push(name);
|
|
89
|
+
}
|
|
90
|
+
return here;
|
|
91
|
+
};
|
|
92
|
+
await run("dns record", async () => {
|
|
93
|
+
const here = await pointedHere();
|
|
94
|
+
return here.length ? here.join(", ") : undefined;
|
|
95
|
+
}, async () => {
|
|
96
|
+
let gone = 0;
|
|
97
|
+
const removed = [];
|
|
98
|
+
for (const name of await pointedHere()) {
|
|
99
|
+
const zone = (await cf.zoneFor(name));
|
|
100
|
+
gone += await cf.deleteDnsRecords(zone.name, name, { confirmed: true });
|
|
101
|
+
removed.push(name);
|
|
102
|
+
}
|
|
103
|
+
return `${gone} record${gone === 1 ? "" : "s"} for ${removed.join(", ")}`;
|
|
104
|
+
});
|
|
105
|
+
await run("vercel project", async () => (await vc.findProject(spec.name))?.name, async () => {
|
|
106
|
+
const project = (await vc.findProject(spec.name));
|
|
107
|
+
await vc.deleteProject(project.id, await vc.teamId(), { confirmed: true });
|
|
108
|
+
return project.name;
|
|
109
|
+
});
|
|
110
|
+
await run("neon project", async () => (await nn.projects()).find((p) => p.name === spec.name)?.name, async () => {
|
|
111
|
+
const project = (await nn.projects()).find((p) => p.name === spec.name);
|
|
112
|
+
await nn.deleteProject(project.id, { confirmed: true });
|
|
113
|
+
return `${project.name} · every branch with it`;
|
|
114
|
+
});
|
|
115
|
+
await run("storage zones", async () => {
|
|
116
|
+
const zones = await bn.zonesForApp(spec.name);
|
|
117
|
+
return zones.length ? zones.map((z) => z.Name).join(", ") : undefined;
|
|
118
|
+
}, async () => {
|
|
119
|
+
const zones = await bn.zonesForApp(spec.name);
|
|
120
|
+
for (const zone of zones)
|
|
121
|
+
await bn.deleteStorageZone(zone.Id, { confirmed: true });
|
|
122
|
+
return zones.map((z) => z.Name).join(", ");
|
|
123
|
+
});
|
|
124
|
+
// Last, and only when asked. Everything above can be rebuilt from what is
|
|
125
|
+
// in here; nothing can rebuild what is in here.
|
|
126
|
+
if (spec.repo) {
|
|
127
|
+
await run("github repo", async () => ((await gh.findRepo(repo)) ? repo : undefined), async () => {
|
|
128
|
+
await gh.deleteRepo(repo, { confirmed: true });
|
|
129
|
+
return repo;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return { app: spec.name, planned: !ctx.confirmed, steps, ok };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=decommission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decommission.js","sourceRoot":"","sources":["../../src/admin/decommission.ts"],"names":[],"mappings":"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"}
|