@byline/cli 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAA2B,MAAM,gBAAgB,CAAA;AAKpE,eAAO,MAAM,SAAS,EAAE,KA+CvB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAA2B,MAAM,gBAAgB,CAAA;AAiBpE,eAAO,MAAM,SAAS,EAAE,KA+CvB,CAAA"}
@@ -1,9 +1,22 @@
1
1
  import { wireRootTsx } from './root-tsx.js';
2
2
  import { wireServerTs } from './server-ts.js';
3
+ import { wireServerUploads } from './server-uploads.js';
3
4
  import { wireStartTs } from './start-ts.js';
4
5
  import { wireTsconfig } from './tsconfig.js';
5
6
  import { wireViteConfig } from './vite-config.js';
6
- const SUB_EDITS = [wireServerTs, wireStartTs, wireRootTsx, wireTsconfig, wireViteConfig];
7
+ // Order matters: `wireServerTs` injects the side-effect import for
8
+ // `byline/server.config` at the top of `src/server.ts`; `wireServerUploads`
9
+ // then runs in the same file to wrap the `fetch` handler with the runtime
10
+ // uploads helper. The two sub-edits are independent, but keeping them
11
+ // adjacent makes the resulting diff easier to read.
12
+ const SUB_EDITS = [
13
+ wireServerTs,
14
+ wireServerUploads,
15
+ wireStartTs,
16
+ wireRootTsx,
17
+ wireTsconfig,
18
+ wireViteConfig,
19
+ ];
7
20
  export const wirePhase = {
8
21
  id: 'wire',
9
22
  title: 'Wire — inject imports + path mappings + verify vite.config.ts',
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SubEdit } from './shared.js';
2
+ export declare const wireServerUploads: SubEdit;
3
+ //# sourceMappingURL=server-uploads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-uploads.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/server-uploads.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAA;AAgBzD,eAAO,MAAM,iBAAiB,EAAE,OAS/B,CAAA"}
@@ -0,0 +1,195 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { Node, Project, SyntaxKind, } from 'ts-morph';
3
+ const REL = 'src/server.ts';
4
+ const SERVE_UPLOADS_NAME = 'serveUploads';
5
+ const SERVE_UPLOADS_MODULE = '@byline/host-tanstack-start/integrations/serve-uploads';
6
+ const SNIPPET = `import { ${SERVE_UPLOADS_NAME} } from '${SERVE_UPLOADS_MODULE}'
7
+
8
+ // Inside createServerEntry({ ... }), replace the fetch handler with:
9
+ async fetch(request) {
10
+ const upload = await ${SERVE_UPLOADS_NAME}(request)
11
+ if (upload) return upload
12
+ return handler.fetch(request)
13
+ },
14
+ `;
15
+ export const wireServerUploads = {
16
+ key: 'server-uploads',
17
+ title: `Wrap fetch with \`${SERVE_UPLOADS_NAME}\` runtime handler in ${REL}`,
18
+ async preview(ctx) {
19
+ return run(ctx, true);
20
+ },
21
+ async apply(ctx) {
22
+ return run(ctx, false);
23
+ },
24
+ };
25
+ async function run(ctx, dryRun) {
26
+ const path = ctx.resolve(REL);
27
+ if (!existsSync(path)) {
28
+ return { status: 'blocked', message: `${REL} not found — host phase should have caught this` };
29
+ }
30
+ // Cheap pre-check: if the helper is already referenced anywhere, we
31
+ // assume it's wired. Avoids a full AST round-trip on the common
32
+ // already-wired case and on any non-trivial server.ts the user has
33
+ // hand-customized to call serveUploads themselves.
34
+ const text = readFileSync(path, 'utf8');
35
+ if (text.includes(SERVE_UPLOADS_NAME)) {
36
+ return { status: 'skipped', message: `${REL}: ${SERVE_UPLOADS_NAME} already wired` };
37
+ }
38
+ const project = new Project({ useInMemoryFileSystem: false, skipAddingFilesFromTsConfig: true });
39
+ let source;
40
+ try {
41
+ source = project.addSourceFileAtPath(path);
42
+ }
43
+ catch {
44
+ return manualBail(`${REL}: could not parse`);
45
+ }
46
+ const createServerEntryCall = findCreateServerEntryCall(source);
47
+ if (!createServerEntryCall) {
48
+ return manualBail(`${REL}: no \`createServerEntry(...)\` call found`);
49
+ }
50
+ const optionsLiteral = getFirstObjectArg(createServerEntryCall);
51
+ if (!optionsLiteral) {
52
+ return manualBail(`${REL}: \`createServerEntry\` argument is not an inline object literal — cannot safely auto-edit`);
53
+ }
54
+ const fetchProp = optionsLiteral.getProperty('fetch');
55
+ if (!fetchProp) {
56
+ return manualBail(`${REL}: no \`fetch\` property on \`createServerEntry\` options`);
57
+ }
58
+ if (!isCanonicalFetchProperty(fetchProp)) {
59
+ return manualBail(`${REL}: existing \`fetch\` does not match the canonical scaffold (\`fetch(request) { return handler.fetch(request) }\`) — manual wire required`);
60
+ }
61
+ if (dryRun) {
62
+ return {
63
+ status: 'done',
64
+ message: `${REL}: will wrap fetch with ${SERVE_UPLOADS_NAME}`,
65
+ };
66
+ }
67
+ ensureImport(source);
68
+ replaceFetchMethod(optionsLiteral);
69
+ source.saveSync();
70
+ return { status: 'done', message: `${REL}: wrapped fetch with ${SERVE_UPLOADS_NAME}` };
71
+ }
72
+ function manualBail(message) {
73
+ return { status: 'manual', message, snippet: SNIPPET };
74
+ }
75
+ function findCreateServerEntryCall(source) {
76
+ // Walk top-level descendants looking for any `createServerEntry(...)`
77
+ // call. The TanStack Start scaffold exports it via `export default`,
78
+ // but we accept any position in the file.
79
+ for (const call of source.getDescendantsOfKind(SyntaxKind.CallExpression)) {
80
+ if (call.getExpression().getText() === 'createServerEntry')
81
+ return call;
82
+ }
83
+ return undefined;
84
+ }
85
+ function getFirstObjectArg(call) {
86
+ const args = call.getArguments();
87
+ if (args.length === 0)
88
+ return undefined;
89
+ const first = args[0];
90
+ if (first && Node.isObjectLiteralExpression(first))
91
+ return first;
92
+ return undefined;
93
+ }
94
+ /**
95
+ * Recognise the canonical TanStack Start scaffold shape so we only edit
96
+ * a `fetch` we fully understand. Three accepted forms (all equivalent
97
+ * in behaviour):
98
+ *
99
+ * fetch(request) { return handler.fetch(request) } // method shorthand
100
+ * fetch: (request) => handler.fetch(request) // arrow w/ expr body
101
+ * fetch: (request) => { return handler.fetch(request) }
102
+ * fetch: function (request) { return handler.fetch(request) }
103
+ *
104
+ * Anything else — extra statements, async, type annotations on the
105
+ * parameter, a different parameter name, a wrapped/intercepted call —
106
+ * forces a manual bail.
107
+ */
108
+ function isCanonicalFetchProperty(prop) {
109
+ const shape = extractFunctionShape(prop);
110
+ if (!shape)
111
+ return false;
112
+ const { parameters, body } = shape;
113
+ if (parameters.length !== 1)
114
+ return false;
115
+ if (parameters[0]?.getName() !== 'request')
116
+ return false;
117
+ if (!body)
118
+ return false;
119
+ // Body should evaluate `handler.fetch(request)` — either as the sole
120
+ // statement of a block (`{ return handler.fetch(request) }`) or as
121
+ // the bare expression of an arrow function.
122
+ let returnExpr;
123
+ if (Node.isBlock(body)) {
124
+ const stmts = body.getStatements();
125
+ if (stmts.length !== 1)
126
+ return false;
127
+ const only = stmts[0];
128
+ if (!only || !Node.isReturnStatement(only))
129
+ return false;
130
+ returnExpr = only.getExpression();
131
+ }
132
+ else {
133
+ returnExpr = body;
134
+ }
135
+ if (!returnExpr || !Node.isCallExpression(returnExpr))
136
+ return false;
137
+ // Callee text, whitespace-stripped, must be exactly `handler.fetch`.
138
+ const callee = returnExpr.getExpression().getText().replace(/\s+/g, '');
139
+ if (callee !== 'handler.fetch')
140
+ return false;
141
+ const callArgs = returnExpr.getArguments();
142
+ if (callArgs.length !== 1)
143
+ return false;
144
+ if (callArgs[0]?.getText() !== 'request')
145
+ return false;
146
+ return true;
147
+ }
148
+ function extractFunctionShape(prop) {
149
+ if (Node.isMethodDeclaration(prop)) {
150
+ return { parameters: prop.getParameters(), body: prop.getBody() };
151
+ }
152
+ if (Node.isPropertyAssignment(prop)) {
153
+ const init = prop.getInitializer();
154
+ if (!init)
155
+ return undefined;
156
+ if (Node.isArrowFunction(init) || Node.isFunctionExpression(init)) {
157
+ return { parameters: init.getParameters(), body: init.getBody() };
158
+ }
159
+ }
160
+ return undefined;
161
+ }
162
+ function ensureImport(source) {
163
+ const existing = source
164
+ .getImportDeclarations()
165
+ .find((d) => d.getModuleSpecifierValue() === SERVE_UPLOADS_MODULE);
166
+ if (existing) {
167
+ const already = existing.getNamedImports().some((n) => n.getName() === SERVE_UPLOADS_NAME);
168
+ if (!already)
169
+ existing.addNamedImport(SERVE_UPLOADS_NAME);
170
+ return;
171
+ }
172
+ // Insert after the last existing import; placement among siblings
173
+ // doesn't matter for behaviour.
174
+ const imports = source.getImportDeclarations();
175
+ source.insertImportDeclaration(imports.length, {
176
+ moduleSpecifier: SERVE_UPLOADS_MODULE,
177
+ namedImports: [SERVE_UPLOADS_NAME],
178
+ });
179
+ }
180
+ function replaceFetchMethod(options) {
181
+ const existing = options.getProperty('fetch');
182
+ if (existing)
183
+ existing.remove();
184
+ options.addMethod({
185
+ name: 'fetch',
186
+ isAsync: true,
187
+ parameters: [{ name: 'request' }],
188
+ statements: [
189
+ `const upload = await ${SERVE_UPLOADS_NAME}(request)`,
190
+ 'if (upload) return upload',
191
+ 'return handler.fetch(request)',
192
+ ],
193
+ });
194
+ }
195
+ //# sourceMappingURL=server-uploads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-uploads.js","sourceRoot":"","sources":["../../../src/phases/wire/server-uploads.ts"],"names":[],"mappings":"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"}
@@ -77,8 +77,15 @@ async function buildBylineCore(): Promise<BylineCore<AdminStore>> {
77
77
  // Local filesystem — suitable for development and self-hosted
78
78
  // deployments. For cloud/production, swap to `@byline/storage-s3`
79
79
  // (see the commented example below).
80
+ //
81
+ // IMPORTANT: `uploadDir` lives OUTSIDE `public/` on purpose. With
82
+ // TanStack Start + Nitro, anything under `public/` is snapshotted
83
+ // into `.output/public/` at build time, and the static handler reads
84
+ // from that snapshot — so newly-uploaded files 404 until the next
85
+ // rebuild. Pair this with a runtime `/uploads/*` handler in
86
+ // `src/server.ts` that streams from `uploadDir` on every request.
80
87
  storage: localStorageProvider({
81
- uploadDir: './public/uploads',
88
+ uploadDir: './uploads',
82
89
  baseUrl: '/uploads',
83
90
  }),
84
91
  // S3-compatible alternative (AWS S3 / Cloudflare R2 / MinIO). Replace
@@ -261,7 +261,7 @@ export function MediaListView({
261
261
  className="group flex flex-col overflow-hidden rounded border border-gray-200 dark:border-gray-700 bg-white dark:bg-canvas-800 hover:border-indigo-400 dark:hover:border-indigo-500 transition-colors no-underline"
262
262
  >
263
263
  {/* Thumbnail */}
264
- <div className="relative aspect-square overflow-hidden bg-gray-100 dark:bg-canvas-700">
264
+ <div className="relative aspect-5/4 overflow-hidden bg-gray-100 dark:bg-canvas-700">
265
265
  {thumbUrl ? (
266
266
  <img
267
267
  src={thumbUrl}
@@ -119,11 +119,16 @@ async function buildBylineCore(): Promise<BylineCore<AdminStore>> {
119
119
  // addition to) this site-wide default.
120
120
  //
121
121
  // Local filesystem is suitable for development and self-hosted
122
- // deployments. The `uploadDir` is served as a static path at `baseUrl`
123
- // by your web server. For cloud/production deployments, swap to
124
- // `@byline/storage-s3` see the commented example below.
122
+ // deployments. The `uploadDir` is served at `baseUrl` by a runtime
123
+ // handler in `src/server.ts` NOT by the framework's static-asset
124
+ // pipeline. Keeping uploads outside `public/` is what lets newly-
125
+ // uploaded files appear without a rebuild: `vite build` snapshots
126
+ // `public/` into `.output/public/`, but the runtime handler reads
127
+ // `uploadDir` directly on every request. For cloud/production
128
+ // deployments, swap to `@byline/storage-s3` — see the commented
129
+ // example below.
125
130
  storage: localStorageProvider({
126
- uploadDir: './public/uploads',
131
+ uploadDir: './uploads',
127
132
  baseUrl: '/uploads',
128
133
  }),
129
134
  // S3-compatible alternative (AWS S3 / Cloudflare R2 / MinIO). Replace
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@byline/cli",
3
3
  "private": false,
4
4
  "license": "MPL-2.0",
5
- "version": "1.7.0",
5
+ "version": "1.7.2",
6
6
  "engines": {
7
7
  "node": ">=20.9.0"
8
8
  },