@jay-framework/wix-deploy 0.18.3 → 0.19.1
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/artifact-store.js +201 -233
- package/dist/index.d.ts +112 -7
- package/dist/index.js +7362 -6
- package/package.json +5 -5
- package/dist/artifact-store.d.ts +0 -71
- package/dist/commands/build-entry.d.ts +0 -15
- package/dist/commands/build-entry.js +0 -448
- package/dist/commands/deploy-baas.d.ts +0 -14
- package/dist/commands/deploy-baas.js +0 -250
- package/dist/commands/deploy.d.ts +0 -19
- package/dist/commands/deploy.js +0 -87
- package/dist/commands/upload-backend.d.ts +0 -14
- package/dist/commands/upload-backend.js +0 -122
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/setup.d.ts +0 -19
- package/dist/setup.js +0 -101
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/wix-deploy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Wix BaaS deployment adapter for Jay Framework — WixDataArtifactStore and entry builder",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"test": ":"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@jay-framework/fullstack-component": "^0.
|
|
29
|
-
"@jay-framework/production-server": "^0.
|
|
30
|
-
"@jay-framework/stack-server-runtime": "^0.
|
|
31
|
-
"@jay-framework/wix-server-client": "^0.
|
|
28
|
+
"@jay-framework/fullstack-component": "^0.19.1",
|
|
29
|
+
"@jay-framework/production-server": "^0.19.1",
|
|
30
|
+
"@jay-framework/stack-server-runtime": "^0.19.1",
|
|
31
|
+
"@jay-framework/wix-server-client": "^0.19.1",
|
|
32
32
|
"@wix/data": "^1.0.433",
|
|
33
33
|
"@wix/sdk": "^1.21.5",
|
|
34
34
|
"esbuild": "^0.21.0",
|
package/dist/artifact-store.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WixDataArtifactStore — implements ArtifactStore for Wix BaaS deployments.
|
|
3
|
-
*
|
|
4
|
-
* Manages both reads (for serving) and writes (for upload/renderer) of
|
|
5
|
-
* backend build artifacts in a Wix data collection. All items are versioned
|
|
6
|
-
* so that a new version can be uploaded while the current version serves.
|
|
7
|
-
*
|
|
8
|
-
* Data collection schema:
|
|
9
|
-
* _id: string — "{version}__{path}" (unique key)
|
|
10
|
-
* version: string — build version (semver)
|
|
11
|
-
* path: string — relative file path within backend dir
|
|
12
|
-
* content: string — file content (text)
|
|
13
|
-
* fileType: string — extension (js, json)
|
|
14
|
-
* sizeBytes: number — content byte length
|
|
15
|
-
* category: string — 'eager' | 'lazy'
|
|
16
|
-
*/
|
|
17
|
-
import type { WixClient } from '@wix/sdk';
|
|
18
|
-
import type { ArtifactStore, RouteManifest, CacheEntry, ServerElementModule } from '@jay-framework/production-server/serve';
|
|
19
|
-
export type { ArtifactStore, RouteManifest, CacheEntry, ServerElementModule };
|
|
20
|
-
export interface BackendFileItem {
|
|
21
|
-
_id: string;
|
|
22
|
-
version: string;
|
|
23
|
-
path: string;
|
|
24
|
-
content: string;
|
|
25
|
-
fileType: string;
|
|
26
|
-
sizeBytes: number;
|
|
27
|
-
category: 'eager' | 'lazy';
|
|
28
|
-
}
|
|
29
|
-
export declare function makeItemId(version: string, relativePath: string): string;
|
|
30
|
-
export interface WixDataArtifactStoreOptions {
|
|
31
|
-
wixClient: WixClient;
|
|
32
|
-
collectionId: string;
|
|
33
|
-
cacheDir: string;
|
|
34
|
-
version: string;
|
|
35
|
-
moduleRegistry?: Record<string, any>;
|
|
36
|
-
}
|
|
37
|
-
export declare class WixDataArtifactStore implements ArtifactStore {
|
|
38
|
-
readonly collectionId: string;
|
|
39
|
-
readonly version: string;
|
|
40
|
-
private readonly cacheDir;
|
|
41
|
-
private readonly dataClient;
|
|
42
|
-
private readonly moduleRegistry;
|
|
43
|
-
private manifestCache?;
|
|
44
|
-
private moduleCache;
|
|
45
|
-
private fetchPromises;
|
|
46
|
-
constructor(options: WixDataArtifactStoreOptions);
|
|
47
|
-
readManifest(): Promise<RouteManifest>;
|
|
48
|
-
readCacheData(relativePath: string): Promise<CacheEntry>;
|
|
49
|
-
readPagePartsConfig(relativePath: string): Promise<any>;
|
|
50
|
-
loadServerElement(relativePath: string): Promise<ServerElementModule>;
|
|
51
|
-
loadModule(modulePath: string, _local?: boolean): Promise<any>;
|
|
52
|
-
getAssetPath(relativePath: string): string;
|
|
53
|
-
getBuildDir(): string;
|
|
54
|
-
loadEagerFiles(): Promise<void>;
|
|
55
|
-
/**
|
|
56
|
-
* Write a single file to the data collection.
|
|
57
|
-
*/
|
|
58
|
-
writeFile(relativePath: string, content: string, category: 'eager' | 'lazy'): Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
* Write a batch of files to the data collection.
|
|
61
|
-
* Returns the number of successfully written files.
|
|
62
|
-
*/
|
|
63
|
-
writeFiles(files: Array<{
|
|
64
|
-
path: string;
|
|
65
|
-
content: string;
|
|
66
|
-
category: 'eager' | 'lazy';
|
|
67
|
-
}>): Promise<number>;
|
|
68
|
-
private ensureFile;
|
|
69
|
-
private fetchFromCollection;
|
|
70
|
-
private writeToCache;
|
|
71
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* jay-stack run wix-deploy/build-entry
|
|
3
|
-
*
|
|
4
|
-
* Reads route-manifest.json from the build backend dir, generates an entry
|
|
5
|
-
* source with pre-imported plugins/actions + WixDataArtifactStore, and
|
|
6
|
-
* bundles it with esbuild into a single entry.mjs (~3-5 MB).
|
|
7
|
-
*/
|
|
8
|
-
import type { ConsoleContext } from '@jay-framework/fullstack-component';
|
|
9
|
-
interface BuildEntryInput {
|
|
10
|
-
collectionId?: string;
|
|
11
|
-
staticBaseUrl?: string;
|
|
12
|
-
excludePlugins?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare const buildEntry: import("@jay-framework/fullstack-component").JayCliCommand<BuildEntryInput> & import("@jay-framework/fullstack-component").JayCliCommandDefinition<BuildEntryInput, [ConsoleContext]>;
|
|
15
|
-
export {};
|
|
@@ -1,448 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* jay-stack run wix-deploy/build-entry
|
|
3
|
-
*
|
|
4
|
-
* Reads route-manifest.json from the build backend dir, generates an entry
|
|
5
|
-
* source with pre-imported plugins/actions + WixDataArtifactStore, and
|
|
6
|
-
* bundles it with esbuild into a single entry.mjs (~3-5 MB).
|
|
7
|
-
*/
|
|
8
|
-
import { makeCliCommand, CONSOLE_CONTEXT } from '@jay-framework/fullstack-component';
|
|
9
|
-
import { DEFAULT_COLLECTION_ID, DEFAULT_CACHE_DIR } from '../constants.js';
|
|
10
|
-
const DEFAULT_EXCLUDE_PLUGINS = ['aiditor', 'ui-kit', 'wix-deploy'];
|
|
11
|
-
function sortPluginsByDeps(plugins) {
|
|
12
|
-
const priorityPackages = ['@jay-framework/wix-server-client'];
|
|
13
|
-
const sorted = [];
|
|
14
|
-
for (const pkg of priorityPackages) {
|
|
15
|
-
const p = plugins.find((p) => p.packageName === pkg);
|
|
16
|
-
if (p)
|
|
17
|
-
sorted.push(p);
|
|
18
|
-
}
|
|
19
|
-
for (const p of plugins) {
|
|
20
|
-
if (!sorted.includes(p))
|
|
21
|
-
sorted.push(p);
|
|
22
|
-
}
|
|
23
|
-
return sorted;
|
|
24
|
-
}
|
|
25
|
-
function generateStubContents(modulePath) {
|
|
26
|
-
const throwStub = '() => { throw new Error("build-time only"); }';
|
|
27
|
-
const stubs = {
|
|
28
|
-
'@jay-framework/compiler-jay-html': [
|
|
29
|
-
'export default {};',
|
|
30
|
-
`export const parseJayFile = ${throwStub};`,
|
|
31
|
-
`export const JAY_IMPORT_RESOLVER = {};`,
|
|
32
|
-
`export const generateServerElementFile = ${throwStub};`,
|
|
33
|
-
`export const injectHeadfullFSTemplates = ${throwStub};`,
|
|
34
|
-
`export const discoverHeadlessInstances = ${throwStub};`,
|
|
35
|
-
`export const assignCoordinatesToJayHtml = ${throwStub};`,
|
|
36
|
-
`export const parseAction = ${throwStub};`,
|
|
37
|
-
`export const parseContract = ${throwStub};`,
|
|
38
|
-
].join('\n'),
|
|
39
|
-
'@jay-framework/compiler-shared': [
|
|
40
|
-
'export default {};',
|
|
41
|
-
`export const checkValidationErrors = (x) => x;`,
|
|
42
|
-
`export const formatCode = (code) => code;`,
|
|
43
|
-
].join('\n'),
|
|
44
|
-
'@jay-framework/compiler-jay-stack': [
|
|
45
|
-
'export default {};',
|
|
46
|
-
`export const jayStackCompiler = ${throwStub};`,
|
|
47
|
-
].join('\n'),
|
|
48
|
-
'@jay-framework/compiler-analyze-exported-types': [
|
|
49
|
-
'export default {};',
|
|
50
|
-
`export const extractActionsFromSource = ${throwStub};`,
|
|
51
|
-
].join('\n'),
|
|
52
|
-
'@jay-framework/compiler': [
|
|
53
|
-
'export default {};',
|
|
54
|
-
`export const jayRuntime = ${throwStub};`,
|
|
55
|
-
].join('\n'),
|
|
56
|
-
};
|
|
57
|
-
return stubs[modulePath] || 'export default {};';
|
|
58
|
-
}
|
|
59
|
-
function generateEntrySource(plugins, actionPackages, serverElements, collectionId, staticBaseUrl, version) {
|
|
60
|
-
const pluginImports = plugins.map((p, i) => `import { init as pluginInit_${i} } from '${p.packageName}';`);
|
|
61
|
-
const moduleImports = plugins.map((p, i) => `import * as pluginModule_${i} from '${p.packageName}';`);
|
|
62
|
-
const seImports = serverElements.map((se, i) => `import * as serverElement_${i} from '${se.absolutePath}';`);
|
|
63
|
-
const pluginsArray = plugins.map((p, i) => ` { name: '${p.name}', init: pluginInit_${i} },`);
|
|
64
|
-
const registryEntries = [
|
|
65
|
-
...plugins.map((p, i) => ` '${p.packageName}': pluginModule_${i},`),
|
|
66
|
-
...serverElements.map((se, i) => ` '${se.relativePath}': serverElement_${i},`),
|
|
67
|
-
];
|
|
68
|
-
const actionsArray = actionPackages.map((pkg) => {
|
|
69
|
-
const idx = plugins.findIndex((p) => p.packageName === pkg);
|
|
70
|
-
return ` { module: pluginModule_${idx}, name: '${pkg}' },`;
|
|
71
|
-
});
|
|
72
|
-
return `// Auto-generated BaaS entry — do not edit
|
|
73
|
-
// Generated by @jay-framework/wix-deploy build-entry
|
|
74
|
-
|
|
75
|
-
// Plugin imports (init + full modules for page-parts resolution)
|
|
76
|
-
${pluginImports.join('\n')}
|
|
77
|
-
${moduleImports.join('\n')}
|
|
78
|
-
|
|
79
|
-
// Server element imports (bundled with ssr-runtime)
|
|
80
|
-
${seImports.join('\n')}
|
|
81
|
-
|
|
82
|
-
// Framework imports
|
|
83
|
-
import {
|
|
84
|
-
matchRequest,
|
|
85
|
-
fetchPageRequest,
|
|
86
|
-
fetchActionRequest,
|
|
87
|
-
isActionRequest,
|
|
88
|
-
initializeServicesFromModules,
|
|
89
|
-
registerActionsFromModules,
|
|
90
|
-
FilesystemArtifactStore,
|
|
91
|
-
} from '@jay-framework/production-server/serve';
|
|
92
|
-
import { parseCookies, getService } from '@jay-framework/stack-server-runtime';
|
|
93
|
-
import { WIX_CLIENT_SERVICE } from '@jay-framework/wix-server-client';
|
|
94
|
-
import { WixDataArtifactStore } from '@jay-framework/wix-deploy/artifact-store';
|
|
95
|
-
|
|
96
|
-
// Module registry — npm packages + server elements (all bundled by esbuild)
|
|
97
|
-
const MODULE_REGISTRY = {
|
|
98
|
-
${registryEntries.join('\n')}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
// Configuration
|
|
102
|
-
const COLLECTION_ID = process.env.JAY_COLLECTION_ID || '${collectionId}';
|
|
103
|
-
const STATIC_BASE_URL = process.env.STATIC_BASE_URL || '${staticBaseUrl}';
|
|
104
|
-
const VERSION = process.env.JAY_BUILD_VERSION || '${version}';
|
|
105
|
-
const LOCAL_BACKEND_DIR = process.env.JAY_BACKEND_DIR || '';
|
|
106
|
-
|
|
107
|
-
let artifacts;
|
|
108
|
-
let initialized = false;
|
|
109
|
-
let initError = null;
|
|
110
|
-
|
|
111
|
-
async function initialize() {
|
|
112
|
-
if (initialized) return;
|
|
113
|
-
|
|
114
|
-
// Set CWD to entry.mjs dir so config/.wix.yaml is found by wix-server-client
|
|
115
|
-
const entryDir = new URL('.', import.meta.url).pathname;
|
|
116
|
-
if (entryDir && process.cwd() !== entryDir) {
|
|
117
|
-
try { process.chdir(entryDir); } catch {}
|
|
118
|
-
}
|
|
119
|
-
console.log('[BaaS] CWD:', process.cwd());
|
|
120
|
-
|
|
121
|
-
// BaaS skips dotfiles during upload — copy wix.yaml to .wix.yaml if needed
|
|
122
|
-
const fs = await import('node:fs');
|
|
123
|
-
const configDir = process.cwd() + '/config';
|
|
124
|
-
const dotYaml = configDir + '/.wix.yaml';
|
|
125
|
-
const plainYaml = configDir + '/wix.yaml';
|
|
126
|
-
if (!fs.existsSync(dotYaml) && fs.existsSync(plainYaml)) {
|
|
127
|
-
fs.copyFileSync(plainYaml, dotYaml);
|
|
128
|
-
console.log('[BaaS] Copied config/wix.yaml to config/.wix.yaml');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Initialize plugins first — wix-server-client reads config/.wix.yaml and creates WixClient
|
|
132
|
-
console.log('[BaaS] Initializing plugins...');
|
|
133
|
-
await initializeServicesFromModules([
|
|
134
|
-
${pluginsArray.join('\n')}
|
|
135
|
-
], 'BaaS');
|
|
136
|
-
|
|
137
|
-
// Register actions
|
|
138
|
-
console.log('[BaaS] Registering actions...');
|
|
139
|
-
await registerActionsFromModules([
|
|
140
|
-
${actionsArray.join('\n')}
|
|
141
|
-
]);
|
|
142
|
-
|
|
143
|
-
// Create artifact store — uses the WixClient that wix-server-client just initialized
|
|
144
|
-
if (LOCAL_BACKEND_DIR) {
|
|
145
|
-
console.log('[BaaS] Using filesystem artifact store:', LOCAL_BACKEND_DIR);
|
|
146
|
-
artifacts = new FilesystemArtifactStore(LOCAL_BACKEND_DIR);
|
|
147
|
-
} else {
|
|
148
|
-
console.log('[BaaS] Creating WixDataArtifactStore...');
|
|
149
|
-
const wixClientService = getService(WIX_CLIENT_SERVICE);
|
|
150
|
-
console.log('[BaaS] WixClientService:', wixClientService ? 'found' : 'MISSING');
|
|
151
|
-
artifacts = new WixDataArtifactStore({
|
|
152
|
-
wixClient: wixClientService,
|
|
153
|
-
collectionId: COLLECTION_ID,
|
|
154
|
-
version: VERSION,
|
|
155
|
-
cacheDir: '${DEFAULT_CACHE_DIR}',
|
|
156
|
-
moduleRegistry: MODULE_REGISTRY,
|
|
157
|
-
});
|
|
158
|
-
console.log('[BaaS] Loading eager files...');
|
|
159
|
-
await artifacts.loadEagerFiles();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
initialized = true;
|
|
163
|
-
console.log('[BaaS] Initialization complete');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function errorPage(title, err, path) {
|
|
167
|
-
const html = '<!doctype html><html><head><meta charset="UTF-8"><title>' + title + '</title>'
|
|
168
|
-
+ '<style>body{font-family:monospace;max-width:800px;margin:40px auto;padding:0 20px}'
|
|
169
|
-
+ 'h1{color:#c00}pre{background:#f5f5f5;padding:16px;overflow-x:auto;border-radius:4px}'
|
|
170
|
-
+ '.path{color:#666}</style></head><body>'
|
|
171
|
-
+ '<h1>' + title + '</h1>'
|
|
172
|
-
+ '<p class="path">' + path + '</p>'
|
|
173
|
-
+ '<p><strong>' + (err.message || '') + '</strong></p>'
|
|
174
|
-
+ '<pre>' + (err.stack || '') + '</pre>'
|
|
175
|
-
+ '</body></html>';
|
|
176
|
-
return new Response(html, { status: 500, headers: { 'Content-Type': 'text/html' } });
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async function handler(request) {
|
|
180
|
-
const url = new URL(request.url);
|
|
181
|
-
|
|
182
|
-
// Diagnostic endpoint — runs before init
|
|
183
|
-
if (url.pathname === '/_jay/debug') {
|
|
184
|
-
const fs = await import('node:fs');
|
|
185
|
-
const entryDir = new URL('.', import.meta.url).pathname;
|
|
186
|
-
const info = {
|
|
187
|
-
cwd: process.cwd(),
|
|
188
|
-
entryUrl: import.meta.url,
|
|
189
|
-
entryDir,
|
|
190
|
-
initialized,
|
|
191
|
-
hasArtifacts: !!artifacts,
|
|
192
|
-
initError: initError?.message || null,
|
|
193
|
-
};
|
|
194
|
-
try { info.cwdFiles = fs.readdirSync(process.cwd()); } catch (e) { info.cwdFiles = e.message; }
|
|
195
|
-
try { info.configDirFiles = fs.readdirSync(process.cwd() + '/config'); } catch (e) { info.configDirFiles = e.message; }
|
|
196
|
-
try { info.entryDirFiles = fs.readdirSync(entryDir); } catch (e) { info.entryDirFiles = e.message; }
|
|
197
|
-
try { info.entryConfigFiles = fs.readdirSync(entryDir + '/config'); } catch (e) { info.entryConfigFiles = e.message; }
|
|
198
|
-
try { info.userCodeFiles = fs.readdirSync('/user-code'); } catch (e) { info.userCodeFiles = e.message; }
|
|
199
|
-
try { info.userCodeConfigFiles = fs.readdirSync('/user-code/config'); } catch (e) { info.userCodeConfigFiles = e.message; }
|
|
200
|
-
return new Response(JSON.stringify(info, null, 2), { headers: { 'Content-Type': 'application/json' } });
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
await initialize();
|
|
205
|
-
} catch (e) {
|
|
206
|
-
if (!initError) {
|
|
207
|
-
initError = e;
|
|
208
|
-
console.error('[BaaS] INIT FAILED:', e.message, e.stack);
|
|
209
|
-
}
|
|
210
|
-
return errorPage('Initialization Failed', e, url.pathname);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
if (isActionRequest(url.pathname)) return fetchActionRequest(request);
|
|
215
|
-
|
|
216
|
-
const manifest = await artifacts.readManifest();
|
|
217
|
-
const match = matchRequest(manifest, url.pathname);
|
|
218
|
-
if (!match) return new Response('Not Found', { status: 404 });
|
|
219
|
-
|
|
220
|
-
const cookies = parseCookies(request.headers.get('cookie') || '');
|
|
221
|
-
return fetchPageRequest(match, manifest, url, artifacts, STATIC_BASE_URL, cookies);
|
|
222
|
-
} catch (e) {
|
|
223
|
-
console.error('[BaaS] REQUEST FAILED:', url.pathname, e.message, e.stack);
|
|
224
|
-
return errorPage('Request Failed', e, url.pathname);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export default { fetch: handler };
|
|
229
|
-
export { handler as fetch };
|
|
230
|
-
`;
|
|
231
|
-
}
|
|
232
|
-
function generateServeSource(frontendDir, backendDir) {
|
|
233
|
-
const lines = [
|
|
234
|
-
'#!/usr/bin/env node',
|
|
235
|
-
'// Local test server for the BaaS entry — run with: node dist/serve.mjs',
|
|
236
|
-
'import http from "node:http";',
|
|
237
|
-
'import fs from "node:fs";',
|
|
238
|
-
'import path from "node:path";',
|
|
239
|
-
'import { Readable } from "node:stream";',
|
|
240
|
-
'',
|
|
241
|
-
'process.env.STATIC_BASE_URL = process.env.STATIC_BASE_URL || "/";',
|
|
242
|
-
`process.env.JAY_BACKEND_DIR = process.env.JAY_BACKEND_DIR || "${backendDir}";`,
|
|
243
|
-
'const entry = await import("./entry.mjs");',
|
|
244
|
-
'const handler = entry.default?.fetch || entry.fetch;',
|
|
245
|
-
'const PORT = parseInt(process.env.PORT || "4000", 10);',
|
|
246
|
-
`const FRONTEND_DIR = "${frontendDir}";`,
|
|
247
|
-
'',
|
|
248
|
-
'const MIME = {',
|
|
249
|
-
' ".js": "application/javascript", ".mjs": "application/javascript",',
|
|
250
|
-
' ".css": "text/css", ".html": "text/html", ".json": "application/json",',
|
|
251
|
-
' ".png": "image/png", ".jpg": "image/jpeg", ".svg": "image/svg+xml",',
|
|
252
|
-
' ".woff2": "font/woff2", ".woff": "font/woff",',
|
|
253
|
-
'};',
|
|
254
|
-
'',
|
|
255
|
-
'function serveStatic(pathname, res) {',
|
|
256
|
-
' const fp = path.join(FRONTEND_DIR, pathname);',
|
|
257
|
-
' if (!fs.existsSync(fp) || !fs.statSync(fp).isFile()) return false;',
|
|
258
|
-
' res.writeHead(200, { "Content-Type": MIME[path.extname(fp)] || "application/octet-stream" });',
|
|
259
|
-
' fs.createReadStream(fp).pipe(res);',
|
|
260
|
-
' return true;',
|
|
261
|
-
'}',
|
|
262
|
-
'',
|
|
263
|
-
'http.createServer(async (req, res) => {',
|
|
264
|
-
' const url = new URL(req.url, "http://" + req.headers.host);',
|
|
265
|
-
' if (serveStatic(url.pathname, res)) return;',
|
|
266
|
-
' const headers = new Headers();',
|
|
267
|
-
' for (const [k, v] of Object.entries(req.headers)) {',
|
|
268
|
-
' if (v) headers.set(k, Array.isArray(v) ? v.join(", ") : v);',
|
|
269
|
-
' }',
|
|
270
|
-
' const init = { method: req.method, headers };',
|
|
271
|
-
' if (req.method !== "GET" && req.method !== "HEAD") {',
|
|
272
|
-
' init.body = Readable.toWeb(req); init.duplex = "half";',
|
|
273
|
-
' }',
|
|
274
|
-
' try {',
|
|
275
|
-
' const response = await handler(new Request(url, init));',
|
|
276
|
-
' const rh = {}; response.headers.forEach((v, k) => { rh[k] = v; });',
|
|
277
|
-
' res.writeHead(response.status, rh);',
|
|
278
|
-
' if (response.body) {',
|
|
279
|
-
' const reader = response.body.getReader();',
|
|
280
|
-
' while (true) { const { done, value } = await reader.read(); if (done) break; res.write(value); }',
|
|
281
|
-
' }',
|
|
282
|
-
' res.end();',
|
|
283
|
-
' } catch (err) { console.error("Handler error:", err); res.writeHead(500); res.end("Internal Server Error"); }',
|
|
284
|
-
'}).listen(PORT, () => {',
|
|
285
|
-
' console.log("Local test server at http://localhost:" + PORT);',
|
|
286
|
-
' console.log("Frontend: " + FRONTEND_DIR);',
|
|
287
|
-
'});',
|
|
288
|
-
];
|
|
289
|
-
return lines.join('\n') + '\n';
|
|
290
|
-
}
|
|
291
|
-
export const buildEntry = makeCliCommand('build-entry')
|
|
292
|
-
.withServices(CONSOLE_CONTEXT)
|
|
293
|
-
.withHandler(async (input, ctx) => {
|
|
294
|
-
const fs = await import('node:fs');
|
|
295
|
-
const path = await import('node:path');
|
|
296
|
-
const { createRequire } = await import('node:module');
|
|
297
|
-
const buildDir = ctx.build.backend;
|
|
298
|
-
const outFile = path.resolve(ctx.projectRoot, 'dist/entry.mjs');
|
|
299
|
-
const collectionId = input.collectionId || DEFAULT_COLLECTION_ID;
|
|
300
|
-
const staticBaseUrl = input.staticBaseUrl || '/';
|
|
301
|
-
const userExcludes = input.excludePlugins?.split(',') || [];
|
|
302
|
-
const excludePlugins = [...DEFAULT_EXCLUDE_PLUGINS, ...userExcludes];
|
|
303
|
-
ctx.log(`Build dir: ${buildDir}`);
|
|
304
|
-
ctx.log(`Output: ${outFile}`);
|
|
305
|
-
const manifestPath = path.join(buildDir, 'route-manifest.json');
|
|
306
|
-
if (!fs.existsSync(manifestPath)) {
|
|
307
|
-
ctx.error(`route-manifest.json not found at ${manifestPath}`);
|
|
308
|
-
ctx.error('Run jay-stack build first.');
|
|
309
|
-
return { success: false };
|
|
310
|
-
}
|
|
311
|
-
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
312
|
-
// Read version from build-metadata.json
|
|
313
|
-
const metadataPath = path.join(buildDir, 'build-metadata.json');
|
|
314
|
-
let version = '1.0.0';
|
|
315
|
-
if (fs.existsSync(metadataPath)) {
|
|
316
|
-
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
|
317
|
-
version = String(metadata.version || '1.0.0');
|
|
318
|
-
}
|
|
319
|
-
const filteredPlugins = manifest.plugins.filter((p) => !excludePlugins.includes(p.name) && !excludePlugins.includes(p.packageName));
|
|
320
|
-
// wix-server-client must init before plugins that depend on it
|
|
321
|
-
const plugins = sortPluginsByDeps(filteredPlugins);
|
|
322
|
-
const pluginPackages = new Set(plugins.map((p) => p.packageName));
|
|
323
|
-
const actionPackages = manifest.actions
|
|
324
|
-
.filter((a) => a.isPlugin && a.packageName && pluginPackages.has(a.packageName))
|
|
325
|
-
.map((a) => a.packageName)
|
|
326
|
-
.filter((v, i, arr) => arr.indexOf(v) === i);
|
|
327
|
-
// Collect unique server element paths from routes
|
|
328
|
-
const seSet = new Set();
|
|
329
|
-
for (const route of manifest.routes) {
|
|
330
|
-
if (route.serverElementPath)
|
|
331
|
-
seSet.add(route.serverElementPath);
|
|
332
|
-
}
|
|
333
|
-
const serverElements = [...seSet].map((rel) => ({
|
|
334
|
-
relativePath: rel,
|
|
335
|
-
absolutePath: path.join(buildDir, rel),
|
|
336
|
-
}));
|
|
337
|
-
ctx.log(`Version: ${version}`);
|
|
338
|
-
ctx.log(`Plugins: ${plugins.map((p) => p.name).join(', ')}`);
|
|
339
|
-
ctx.log(`Action packages: ${actionPackages.join(', ')}`);
|
|
340
|
-
ctx.log(`Server elements: ${serverElements.length} routes`);
|
|
341
|
-
const entrySource = generateEntrySource(plugins, actionPackages, serverElements, collectionId, staticBaseUrl, version);
|
|
342
|
-
const entryDir = path.dirname(outFile);
|
|
343
|
-
fs.mkdirSync(entryDir, { recursive: true });
|
|
344
|
-
const tempEntryPath = path.join(entryDir, '.entry.generated.mjs');
|
|
345
|
-
fs.writeFileSync(tempEntryPath, entrySource, 'utf8');
|
|
346
|
-
// Build-time-only dep stubs
|
|
347
|
-
const stubs = [
|
|
348
|
-
'@jay-framework/compiler-jay-html',
|
|
349
|
-
'@jay-framework/compiler-shared',
|
|
350
|
-
'@jay-framework/compiler-analyze-exported-types',
|
|
351
|
-
'@jay-framework/compiler-jay-stack',
|
|
352
|
-
'@jay-framework/compiler',
|
|
353
|
-
'@jay-framework/rollup-plugin',
|
|
354
|
-
'@jay-framework/vite-plugin',
|
|
355
|
-
'typescript',
|
|
356
|
-
'prettier',
|
|
357
|
-
'vite',
|
|
358
|
-
'lightningcss',
|
|
359
|
-
'fsevents',
|
|
360
|
-
];
|
|
361
|
-
const stubFilter = new RegExp('^(' + stubs.map((s) => s.replace(/[/.]/g, '\\$&')).join('|') + ')$');
|
|
362
|
-
const stubBuildDepsPlugin = {
|
|
363
|
-
name: 'stub-build-deps',
|
|
364
|
-
setup(build) {
|
|
365
|
-
build.onResolve({ filter: stubFilter }, (args) => ({
|
|
366
|
-
path: args.path,
|
|
367
|
-
namespace: 'stub',
|
|
368
|
-
}));
|
|
369
|
-
build.onLoad({ filter: /.*/, namespace: 'stub' }, (args) => ({
|
|
370
|
-
contents: generateStubContents(args.path),
|
|
371
|
-
loader: 'js',
|
|
372
|
-
}));
|
|
373
|
-
},
|
|
374
|
-
};
|
|
375
|
-
// Resolve sub-path imports
|
|
376
|
-
const require = createRequire(import.meta.url);
|
|
377
|
-
const resolveAliasPlugin = {
|
|
378
|
-
name: 'resolve-aliases',
|
|
379
|
-
setup(build) {
|
|
380
|
-
build.onResolve({ filter: /^@jay-framework\/production-server\/serve$/ }, () => {
|
|
381
|
-
return { path: require.resolve('@jay-framework/production-server/serve') };
|
|
382
|
-
});
|
|
383
|
-
build.onResolve({ filter: /^@jay-framework\/wix-deploy\/artifact-store$/ }, () => {
|
|
384
|
-
return { path: require.resolve('@jay-framework/wix-deploy/artifact-store') };
|
|
385
|
-
});
|
|
386
|
-
},
|
|
387
|
-
};
|
|
388
|
-
const esbuild = await import('esbuild');
|
|
389
|
-
const result = await esbuild.build({
|
|
390
|
-
entryPoints: [tempEntryPath],
|
|
391
|
-
bundle: true,
|
|
392
|
-
format: 'esm',
|
|
393
|
-
platform: 'node',
|
|
394
|
-
target: 'node20',
|
|
395
|
-
outfile: outFile,
|
|
396
|
-
external: ['node:*'],
|
|
397
|
-
banner: {
|
|
398
|
-
js: 'import { createRequire as __bundleCreateRequire } from "node:module";const require = __bundleCreateRequire(import.meta.url);',
|
|
399
|
-
},
|
|
400
|
-
plugins: [resolveAliasPlugin, stubBuildDepsPlugin],
|
|
401
|
-
minify: false,
|
|
402
|
-
treeShaking: true,
|
|
403
|
-
logLevel: 'warning',
|
|
404
|
-
metafile: true,
|
|
405
|
-
});
|
|
406
|
-
fs.rmSync(tempEntryPath, { force: true });
|
|
407
|
-
// Patch runtime require() calls for build-time-only modules
|
|
408
|
-
// These use createRequire(import.meta.url)("typescript") which bypasses esbuild stubs
|
|
409
|
-
const runtimeStubs = ['typescript', 'prettier', 'lightningcss'];
|
|
410
|
-
let patched = fs.readFileSync(outFile, 'utf8');
|
|
411
|
-
let patchCount = 0;
|
|
412
|
-
for (const mod of runtimeStubs) {
|
|
413
|
-
const pattern = new RegExp(`(\\w+)\\("${mod}"\\)`, 'g');
|
|
414
|
-
const before = patched;
|
|
415
|
-
patched = patched.replace(pattern, '({})');
|
|
416
|
-
if (patched !== before)
|
|
417
|
-
patchCount++;
|
|
418
|
-
}
|
|
419
|
-
if (patchCount > 0) {
|
|
420
|
-
fs.writeFileSync(outFile, patched);
|
|
421
|
-
ctx.log(`Patched ${patchCount} runtime require() calls for build-time modules`);
|
|
422
|
-
}
|
|
423
|
-
const stat = fs.statSync(outFile);
|
|
424
|
-
const sizeMB = (stat.size / 1024 / 1024).toFixed(1);
|
|
425
|
-
ctx.log(`Done: ${outFile} (${sizeMB} MB)`);
|
|
426
|
-
if (result.metafile) {
|
|
427
|
-
ctx.log(`Bundled ${Object.keys(result.metafile.inputs).length} input files`);
|
|
428
|
-
fs.writeFileSync(outFile.replace(/\.mjs$/, '.meta.json'), JSON.stringify(result.metafile));
|
|
429
|
-
}
|
|
430
|
-
// Copy config/.wix.yaml to dist/ so wix-server-client can find it on BaaS
|
|
431
|
-
// Also copy as wix.yaml (without dot) in case the CLI skips dotfiles
|
|
432
|
-
const wixConfigSrc = path.join(ctx.projectRoot, 'config', '.wix.yaml');
|
|
433
|
-
if (fs.existsSync(wixConfigSrc)) {
|
|
434
|
-
const configDir = path.join(entryDir, 'config');
|
|
435
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
436
|
-
fs.copyFileSync(wixConfigSrc, path.join(configDir, '.wix.yaml'));
|
|
437
|
-
fs.copyFileSync(wixConfigSrc, path.join(configDir, 'wix.yaml'));
|
|
438
|
-
ctx.log(`Copied config/.wix.yaml to dist/config/`);
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
ctx.warn(`config/.wix.yaml not found — wix-server-client init will fail on BaaS unless WIX_API_KEY env vars are set`);
|
|
442
|
-
}
|
|
443
|
-
// Generate serve.mjs in project root (not dist/) to avoid BaaS uploading it
|
|
444
|
-
const serveFile = path.join(ctx.projectRoot, 'serve.mjs');
|
|
445
|
-
fs.writeFileSync(serveFile, generateServeSource(ctx.build.frontend, buildDir));
|
|
446
|
-
ctx.log(`Generated ${serveFile} — run with: node serve.mjs`);
|
|
447
|
-
return { success: true, outFile, sizeMB };
|
|
448
|
-
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* jay-stack run wix-deploy/deploy-baas
|
|
3
|
-
*
|
|
4
|
-
* Deploys the dist/ folder to Wix BaaS using ambassador SDK packages.
|
|
5
|
-
* Uploads ALL files including node_modules/.
|
|
6
|
-
*
|
|
7
|
-
* Reads appId from wix.config.json and auth from ~/.wix/auth/.
|
|
8
|
-
*/
|
|
9
|
-
import type { ConsoleContext } from '@jay-framework/fullstack-component';
|
|
10
|
-
interface DeployBaasInput {
|
|
11
|
-
dryRun?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export declare const deployBaas: import("@jay-framework/fullstack-component").JayCliCommand<DeployBaasInput> & import("@jay-framework/fullstack-component").JayCliCommandDefinition<DeployBaasInput, [ConsoleContext]>;
|
|
14
|
-
export {};
|