@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.
Files changed (50) hide show
  1. package/dist/admin/apps.d.ts.map +1 -1
  2. package/dist/admin/apps.js +10 -1
  3. package/dist/admin/apps.js.map +1 -1
  4. package/dist/admin/chunks.d.ts +82 -0
  5. package/dist/admin/chunks.d.ts.map +1 -1
  6. package/dist/admin/chunks.js +156 -17
  7. package/dist/admin/chunks.js.map +1 -1
  8. package/dist/admin/decommission.d.ts +40 -0
  9. package/dist/admin/decommission.d.ts.map +1 -0
  10. package/dist/admin/decommission.js +134 -0
  11. package/dist/admin/decommission.js.map +1 -0
  12. package/dist/admin/entrypoints.d.ts +16 -0
  13. package/dist/admin/entrypoints.d.ts.map +1 -0
  14. package/dist/admin/entrypoints.js +41 -0
  15. package/dist/admin/entrypoints.js.map +1 -0
  16. package/dist/admin/index.d.ts +2 -0
  17. package/dist/admin/index.d.ts.map +1 -1
  18. package/dist/admin/index.js +2 -0
  19. package/dist/admin/index.js.map +1 -1
  20. package/dist/admin/provision.d.ts.map +1 -1
  21. package/dist/admin/provision.js +116 -4
  22. package/dist/admin/provision.js.map +1 -1
  23. package/dist/admin/services/bunny.d.ts +3 -0
  24. package/dist/admin/services/bunny.d.ts.map +1 -1
  25. package/dist/admin/services/bunny.js +12 -0
  26. package/dist/admin/services/bunny.js.map +1 -1
  27. package/dist/admin/services/cloudflare.d.ts +11 -0
  28. package/dist/admin/services/cloudflare.d.ts.map +1 -1
  29. package/dist/admin/services/cloudflare.js +19 -0
  30. package/dist/admin/services/cloudflare.js.map +1 -1
  31. package/dist/admin/services/github.d.ts +3 -0
  32. package/dist/admin/services/github.d.ts.map +1 -1
  33. package/dist/admin/services/github.js +29 -1
  34. package/dist/admin/services/github.js.map +1 -1
  35. package/dist/admin/services/neon.d.ts +3 -0
  36. package/dist/admin/services/neon.d.ts.map +1 -1
  37. package/dist/admin/services/neon.js +16 -0
  38. package/dist/admin/services/neon.js.map +1 -1
  39. package/dist/admin/services/vercel.d.ts +19 -9
  40. package/dist/admin/services/vercel.d.ts.map +1 -1
  41. package/dist/admin/services/vercel.js +40 -7
  42. package/dist/admin/services/vercel.js.map +1 -1
  43. package/dist/config/environments.d.ts +41 -1
  44. package/dist/config/environments.d.ts.map +1 -1
  45. package/dist/config/environments.js +50 -1
  46. package/dist/config/environments.js.map +1 -1
  47. package/dist/registry.d.ts.map +1 -1
  48. package/dist/registry.js +8 -0
  49. package/dist/registry.js.map +1 -1
  50. package/package.json +4 -1
@@ -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,CAYtF;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"}
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"}
@@ -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
- const limit = Number(row["app_limit"]);
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"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"}
@@ -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;AAGpD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,wBAAwB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,8EAA8E;IAC9E,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,WAAY,SAAQ,KAAK;gBACxB,IAAI,EAAE,MAAM;CAIzB;AAQD;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,UAAU,GACd,OAAO,CAAC;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC,CAoB1D;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAerE;AAED,MAAM,WAAW,UAAU;IACzB,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,QAAQ,CAC5B,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAClD,GAAG,EAAE,UAAU,EACf,KAAK,CAAC,EAAE,UAAU,GACjB,OAAO,CAAC,SAAS,CAAC,CAiDpB"}
1
+ {"version":3,"file":"chunks.d.ts","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"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"}
@@ -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
- const { manifest, files } = await readChunk(opts.chunk, ctx);
98
- const all = [...files];
99
- // Generated only when the chunk does not ship one of its own. A chunk that
100
- // hand-writes its config knows something the generator does not, and adding
101
- // a second file at the same path put it in the list twice.
102
- const shipped = manifest.config && files.some((f) => f.path === manifest.config);
103
- const config = shipped ? undefined : configFor(manifest);
104
- if (config && manifest.config) {
105
- // And only if it is not already in the app: this file is the developer's
106
- // once written, and rewriting it would silently undo their settings.
107
- const existing = await gh.readFile(opts.repo, manifest.config).catch(() => undefined);
108
- if (existing === undefined)
109
- all.push({ path: manifest.config, content: config });
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
- watch?.done?.("read chunk", `${manifest.name} ${manifest.version} · ${all.length} files`);
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 { chunk: opts.chunk, app: opts.app, files: all.map((f) => f.path), commit, already: false };
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
@@ -1 +1 @@
1
- {"version":3,"file":"chunks.js","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chunks.js","sourceRoot":"","sources":["../../src/admin/chunks.ts"],"names":[],"mappings":"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"}
@@ -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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"}