@jay-framework/wix-deploy 0.18.3 → 0.18.4

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,246 +1,214 @@
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 { items } from '@wix/data';
18
- import crypto from 'node:crypto';
19
- import fs from 'node:fs';
20
- import path from 'node:path';
21
- export function makeItemId(version, relativePath) {
22
- return crypto
23
- .createHash('sha256')
24
- .update(`v${version}/${relativePath}`)
25
- .digest('hex')
26
- .slice(0, 32);
1
+ import { items } from "@wix/data";
2
+ import crypto from "node:crypto";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ function makeItemId(version, relativePath) {
6
+ return crypto.createHash("sha256").update(`v${version}/${relativePath}`).digest("hex").slice(0, 32);
27
7
  }
28
- // ============================================================================
29
- // Read + Write artifact store
30
- // ============================================================================
31
- export class WixDataArtifactStore {
32
- collectionId;
33
- version;
34
- cacheDir;
35
- dataClient;
36
- moduleRegistry;
37
- manifestCache;
38
- moduleCache = new Map();
39
- fetchPromises = new Map();
40
- constructor(options) {
41
- this.collectionId = options.collectionId;
42
- this.version = options.version;
43
- this.cacheDir = options.cacheDir;
44
- this.dataClient = options.wixClient.use({ items });
45
- this.moduleRegistry = options.moduleRegistry || {};
46
- fs.mkdirSync(this.cacheDir, { recursive: true });
8
+ class WixDataArtifactStore {
9
+ collectionId;
10
+ version;
11
+ cacheDir;
12
+ dataClient;
13
+ moduleRegistry;
14
+ manifestCache;
15
+ moduleCache = /* @__PURE__ */ new Map();
16
+ fetchPromises = /* @__PURE__ */ new Map();
17
+ constructor(options) {
18
+ this.collectionId = options.collectionId;
19
+ this.version = options.version;
20
+ this.cacheDir = options.cacheDir;
21
+ this.dataClient = options.wixClient.use({ items });
22
+ this.moduleRegistry = options.moduleRegistry || {};
23
+ fs.mkdirSync(this.cacheDir, { recursive: true });
24
+ }
25
+ // ========================================================================
26
+ // ArtifactStore interface (reads)
27
+ // ========================================================================
28
+ async readManifest() {
29
+ if (this.manifestCache) return this.manifestCache;
30
+ const content = await this.ensureFile("route-manifest.json");
31
+ this.manifestCache = JSON.parse(content);
32
+ return this.manifestCache;
33
+ }
34
+ async readCacheData(relativePath) {
35
+ const cacheContent = await this.ensureFile(relativePath);
36
+ try {
37
+ const cacheData = JSON.parse(cacheContent);
38
+ return {
39
+ slowViewState: cacheData.slowViewState || {},
40
+ carryForward: cacheData.carryForward || {}
41
+ };
42
+ } catch {
43
+ return { slowViewState: {}, carryForward: {} };
47
44
  }
48
- // ========================================================================
49
- // ArtifactStore interface (reads)
50
- // ========================================================================
51
- async readManifest() {
52
- if (this.manifestCache)
53
- return this.manifestCache;
54
- const content = await this.ensureFile('route-manifest.json');
55
- this.manifestCache = JSON.parse(content);
56
- return this.manifestCache;
45
+ }
46
+ async readPagePartsConfig(relativePath) {
47
+ const content = await this.ensureFile(relativePath);
48
+ return JSON.parse(content);
49
+ }
50
+ async loadServerElement(relativePath) {
51
+ return this.loadModule(relativePath, true);
52
+ }
53
+ async loadModule(modulePath, _local) {
54
+ if (this.moduleRegistry[modulePath]) {
55
+ return this.moduleRegistry[modulePath];
57
56
  }
58
- async readCacheData(relativePath) {
59
- const cacheContent = await this.ensureFile(relativePath);
57
+ const cached = this.moduleCache.get(modulePath);
58
+ if (cached) return cached;
59
+ await this.ensureFile(modulePath);
60
+ const fullPath = path.join(this.cacheDir, modulePath);
61
+ const mod = await import(
62
+ /* @vite-ignore */
63
+ fullPath
64
+ );
65
+ this.moduleCache.set(modulePath, mod);
66
+ return mod;
67
+ }
68
+ getAssetPath(relativePath) {
69
+ return path.join(this.cacheDir, relativePath);
70
+ }
71
+ getBuildDir() {
72
+ return this.cacheDir;
73
+ }
74
+ // ========================================================================
75
+ // Eager loading (cold start)
76
+ // ========================================================================
77
+ async loadEagerFiles() {
78
+ console.log(
79
+ `[WixDataArtifactStore] Loading eager files v${this.version} from "${this.collectionId}"...`
80
+ );
81
+ let totalLoaded = 0;
82
+ let hasMore = true;
83
+ let offset = 0;
84
+ const limit = 50;
85
+ while (hasMore) {
86
+ const result = await this.dataClient.items.query(this.collectionId).eq("category", "eager").eq("version", this.version).skip(offset).limit(limit).find();
87
+ for (const item of result.items) {
88
+ this.writeToCache(item.path, item.content);
89
+ totalLoaded++;
90
+ }
91
+ hasMore = result.items.length === limit;
92
+ offset += limit;
93
+ }
94
+ console.log(`[WixDataArtifactStore] Loaded ${totalLoaded} eager files`);
95
+ }
96
+ // ========================================================================
97
+ // Writes (for upload-backend and renderer)
98
+ // ========================================================================
99
+ /**
100
+ * Write a single file to the data collection.
101
+ */
102
+ async writeFile(relativePath, content, category) {
103
+ const ext = path.extname(relativePath).slice(1);
104
+ const item = {
105
+ _id: makeItemId(this.version, relativePath),
106
+ version: this.version,
107
+ path: relativePath,
108
+ content,
109
+ fileType: ext || "unknown",
110
+ sizeBytes: Buffer.byteLength(content),
111
+ category
112
+ };
113
+ await this.dataClient.items.save(this.collectionId, item);
114
+ }
115
+ /**
116
+ * Write a batch of files to the data collection.
117
+ * Returns the number of successfully written files.
118
+ */
119
+ async writeFiles(files) {
120
+ const dataItems = files.map((f) => ({
121
+ _id: makeItemId(this.version, f.path),
122
+ version: this.version,
123
+ path: f.path,
124
+ content: f.content,
125
+ fileType: path.extname(f.path).slice(1) || "unknown",
126
+ sizeBytes: Buffer.byteLength(f.content),
127
+ category: f.category
128
+ }));
129
+ try {
130
+ await this.dataClient.items.bulkSave(this.collectionId, dataItems);
131
+ return dataItems.length;
132
+ } catch {
133
+ let count = 0;
134
+ for (const item of dataItems) {
60
135
  try {
61
- const cacheData = JSON.parse(cacheContent);
62
- return {
63
- slowViewState: cacheData.slowViewState || {},
64
- carryForward: cacheData.carryForward || {},
65
- };
66
- }
67
- catch {
68
- return { slowViewState: {}, carryForward: {} };
136
+ await this.dataClient.items.save(this.collectionId, item);
137
+ count++;
138
+ } catch {
69
139
  }
140
+ }
141
+ return count;
70
142
  }
71
- async readPagePartsConfig(relativePath) {
72
- const content = await this.ensureFile(relativePath);
73
- return JSON.parse(content);
143
+ }
144
+ // ========================================================================
145
+ // Internal: lazy file fetching
146
+ // ========================================================================
147
+ async ensureFile(relativePath) {
148
+ const fullPath = path.join(this.cacheDir, relativePath);
149
+ if (fs.existsSync(fullPath)) {
150
+ return fs.readFileSync(fullPath, "utf8");
74
151
  }
75
- async loadServerElement(relativePath) {
76
- return this.loadModule(relativePath, true);
77
- }
78
- async loadModule(modulePath, _local) {
79
- if (this.moduleRegistry[modulePath]) {
80
- return this.moduleRegistry[modulePath];
81
- }
82
- const cached = this.moduleCache.get(modulePath);
83
- if (cached)
84
- return cached;
85
- await this.ensureFile(modulePath);
86
- const fullPath = path.join(this.cacheDir, modulePath);
87
- const mod = await import(/* @vite-ignore */ fullPath);
88
- this.moduleCache.set(modulePath, mod);
89
- return mod;
152
+ const existing = this.fetchPromises.get(relativePath);
153
+ if (existing) return existing;
154
+ const promise = this.fetchFromCollection(relativePath);
155
+ this.fetchPromises.set(relativePath, promise);
156
+ try {
157
+ return await promise;
158
+ } finally {
159
+ this.fetchPromises.delete(relativePath);
90
160
  }
91
- getAssetPath(relativePath) {
92
- return path.join(this.cacheDir, relativePath);
161
+ }
162
+ async fetchFromCollection(relativePath) {
163
+ const id = makeItemId(this.version, relativePath);
164
+ const t0 = Date.now();
165
+ const item = await this.dataClient.items.get(
166
+ this.collectionId,
167
+ id
168
+ );
169
+ const t1 = Date.now();
170
+ if (!item?.content) {
171
+ throw new Error(
172
+ `File not found in data collection: v${this.version}/${relativePath} (id: ${id})`
173
+ );
93
174
  }
94
- getBuildDir() {
95
- return this.cacheDir;
96
- }
97
- // ========================================================================
98
- // Eager loading (cold start)
99
- // ========================================================================
100
- async loadEagerFiles() {
101
- console.log(`[WixDataArtifactStore] Loading eager files v${this.version} from "${this.collectionId}"...`);
102
- let totalLoaded = 0;
103
- let hasMore = true;
104
- let offset = 0;
105
- const limit = 50;
106
- while (hasMore) {
107
- const result = await this.dataClient.items
108
- .query(this.collectionId)
109
- .eq('category', 'eager')
110
- .eq('version', this.version)
111
- .skip(offset)
112
- .limit(limit)
113
- .find();
114
- for (const item of result.items) {
115
- this.writeToCache(item.path, item.content);
116
- totalLoaded++;
117
- }
118
- hasMore = result.items.length === limit;
119
- offset += limit;
120
- }
121
- console.log(`[WixDataArtifactStore] Loaded ${totalLoaded} eager files`);
122
- }
123
- // ========================================================================
124
- // Writes (for upload-backend and renderer)
125
- // ========================================================================
126
- /**
127
- * Write a single file to the data collection.
128
- */
129
- async writeFile(relativePath, content, category) {
130
- const ext = path.extname(relativePath).slice(1);
131
- const item = {
132
- _id: makeItemId(this.version, relativePath),
133
- version: this.version,
134
- path: relativePath,
135
- content,
136
- fileType: ext || 'unknown',
137
- sizeBytes: Buffer.byteLength(content),
138
- category,
139
- };
140
- await this.dataClient.items.save(this.collectionId, item);
141
- }
142
- /**
143
- * Write a batch of files to the data collection.
144
- * Returns the number of successfully written files.
145
- */
146
- async writeFiles(files) {
147
- const dataItems = files.map((f) => ({
148
- _id: makeItemId(this.version, f.path),
149
- version: this.version,
150
- path: f.path,
151
- content: f.content,
152
- fileType: path.extname(f.path).slice(1) || 'unknown',
153
- sizeBytes: Buffer.byteLength(f.content),
154
- category: f.category,
155
- }));
156
- try {
157
- await this.dataClient.items.bulkSave(this.collectionId, dataItems);
158
- return dataItems.length;
159
- }
160
- catch {
161
- // Fallback to individual saves
162
- let count = 0;
163
- for (const item of dataItems) {
164
- try {
165
- await this.dataClient.items.save(this.collectionId, item);
166
- count++;
167
- }
168
- catch {
169
- /* skip failed items */
175
+ this.writeToCache(relativePath, item.content);
176
+ console.log(
177
+ `[WixDataArtifactStore] Fetched v${this.version}/${relativePath} (${t1 - t0}ms)`
178
+ );
179
+ return item.content;
180
+ }
181
+ writeToCache(relativePath, content) {
182
+ const fullPath = path.join(this.cacheDir, relativePath);
183
+ fs.mkdirSync(path.dirname(fullPath), { recursive: true });
184
+ if (relativePath.endsWith("page-parts.json")) {
185
+ try {
186
+ const config = JSON.parse(content);
187
+ const rewriteParts = (parts) => {
188
+ for (const part of parts) {
189
+ if (part.modulePath && part.source === "npm") {
190
+ const npmMatch = part.modulePath.match(/\/@jay-framework\/([^/]+)\//);
191
+ if (npmMatch) {
192
+ part.modulePath = `@jay-framework/${npmMatch[1]}`;
193
+ } else {
194
+ const pkgMatch = part.modulePath.match(/\/packages\/(wix-[^/]+)\//);
195
+ if (pkgMatch) {
196
+ part.modulePath = `@jay-framework/${pkgMatch[1]}`;
170
197
  }
198
+ }
171
199
  }
172
- return count;
173
- }
174
- }
175
- // ========================================================================
176
- // Internal: lazy file fetching
177
- // ========================================================================
178
- async ensureFile(relativePath) {
179
- const fullPath = path.join(this.cacheDir, relativePath);
180
- if (fs.existsSync(fullPath)) {
181
- return fs.readFileSync(fullPath, 'utf8');
182
- }
183
- const existing = this.fetchPromises.get(relativePath);
184
- if (existing)
185
- return existing;
186
- const promise = this.fetchFromCollection(relativePath);
187
- this.fetchPromises.set(relativePath, promise);
188
- try {
189
- return await promise;
190
- }
191
- finally {
192
- this.fetchPromises.delete(relativePath);
193
- }
194
- }
195
- async fetchFromCollection(relativePath) {
196
- const id = makeItemId(this.version, relativePath);
197
- const t0 = Date.now();
198
- const item = (await this.dataClient.items.get(this.collectionId, id));
199
- const t1 = Date.now();
200
- if (!item?.content) {
201
- throw new Error(`File not found in data collection: v${this.version}/${relativePath} (id: ${id})`);
202
- }
203
- this.writeToCache(relativePath, item.content);
204
- console.log(`[WixDataArtifactStore] Fetched v${this.version}/${relativePath} (${t1 - t0}ms)`);
205
- return item.content;
206
- }
207
- writeToCache(relativePath, content) {
208
- const fullPath = path.join(this.cacheDir, relativePath);
209
- fs.mkdirSync(path.dirname(fullPath), { recursive: true });
210
- // Rewrite page-parts.json modulePath entries from absolute build paths
211
- // to package names that Node can resolve from the bundled entry.mjs
212
- if (relativePath.endsWith('page-parts.json')) {
213
- try {
214
- const config = JSON.parse(content);
215
- const rewriteParts = (parts) => {
216
- for (const part of parts) {
217
- if (part.modulePath && part.source === 'npm') {
218
- // Extract package dir name from absolute path and map to npm name
219
- // e.g. /Users/.../packages/wix-stores/dist/index.js → @jay-framework/wix-stores
220
- // e.g. /Users/.../node_modules/@jay-framework/wix-stores/dist/index.js → @jay-framework/wix-stores
221
- const npmMatch = part.modulePath.match(/\/@jay-framework\/([^/]+)\//);
222
- if (npmMatch) {
223
- part.modulePath = `@jay-framework/${npmMatch[1]}`;
224
- }
225
- else {
226
- const pkgMatch = part.modulePath.match(/\/packages\/(wix-[^/]+)\//);
227
- if (pkgMatch) {
228
- part.modulePath = `@jay-framework/${pkgMatch[1]}`;
229
- }
230
- }
231
- }
232
- }
233
- };
234
- if (config.parts)
235
- rewriteParts(config.parts);
236
- if (config.instanceComponents)
237
- rewriteParts(config.instanceComponents);
238
- content = JSON.stringify(config);
239
- }
240
- catch {
241
- /* keep original content if parsing fails */
242
- }
243
- }
244
- fs.writeFileSync(fullPath, content, 'utf8');
200
+ }
201
+ };
202
+ if (config.parts) rewriteParts(config.parts);
203
+ if (config.instanceComponents) rewriteParts(config.instanceComponents);
204
+ content = JSON.stringify(config);
205
+ } catch {
206
+ }
245
207
  }
208
+ fs.writeFileSync(fullPath, content, "utf8");
209
+ }
246
210
  }
211
+ export {
212
+ WixDataArtifactStore,
213
+ makeItemId
214
+ };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,112 @@
1
- export { WixDataArtifactStore } from './artifact-store.js';
2
- export type { WixDataArtifactStoreOptions } from './artifact-store.js';
3
- export { buildEntry } from './commands/build-entry.js';
4
- export { uploadBackend } from './commands/upload-backend.js';
5
- export { deployBaas } from './commands/deploy-baas.js';
6
- export { deploy } from './commands/deploy.js';
7
- export { setupWixDeploy } from './setup.js';
1
+ import { WixClient } from '@wix/sdk';
2
+ import { ArtifactStore, RouteManifest, CacheEntry, ServerElementModule } from '@jay-framework/production-server/serve';
3
+ import * as _jay_framework_fullstack_component from '@jay-framework/fullstack-component';
4
+ import { ConsoleContext } from '@jay-framework/fullstack-component';
5
+ import { WixClientService } from '@jay-framework/wix-server-client';
6
+
7
+ /**
8
+ * WixDataArtifactStore — implements ArtifactStore for Wix BaaS deployments.
9
+ *
10
+ * Manages both reads (for serving) and writes (for upload/renderer) of
11
+ * backend build artifacts in a Wix data collection. All items are versioned
12
+ * so that a new version can be uploaded while the current version serves.
13
+ *
14
+ * Data collection schema:
15
+ * _id: string — "{version}__{path}" (unique key)
16
+ * version: string — build version (semver)
17
+ * path: string — relative file path within backend dir
18
+ * content: string — file content (text)
19
+ * fileType: string — extension (js, json)
20
+ * sizeBytes: number — content byte length
21
+ * category: string — 'eager' | 'lazy'
22
+ */
23
+
24
+ interface WixDataArtifactStoreOptions {
25
+ wixClient: WixClient;
26
+ collectionId: string;
27
+ cacheDir: string;
28
+ version: string;
29
+ moduleRegistry?: Record<string, any>;
30
+ }
31
+ declare class WixDataArtifactStore implements ArtifactStore {
32
+ readonly collectionId: string;
33
+ readonly version: string;
34
+ private readonly cacheDir;
35
+ private readonly dataClient;
36
+ private readonly moduleRegistry;
37
+ private manifestCache?;
38
+ private moduleCache;
39
+ private fetchPromises;
40
+ constructor(options: WixDataArtifactStoreOptions);
41
+ readManifest(): Promise<RouteManifest>;
42
+ readCacheData(relativePath: string): Promise<CacheEntry>;
43
+ readPagePartsConfig(relativePath: string): Promise<any>;
44
+ loadServerElement(relativePath: string): Promise<ServerElementModule>;
45
+ loadModule(modulePath: string, _local?: boolean): Promise<any>;
46
+ getAssetPath(relativePath: string): string;
47
+ getBuildDir(): string;
48
+ loadEagerFiles(): Promise<void>;
49
+ /**
50
+ * Write a single file to the data collection.
51
+ */
52
+ writeFile(relativePath: string, content: string, category: 'eager' | 'lazy'): Promise<void>;
53
+ /**
54
+ * Write a batch of files to the data collection.
55
+ * Returns the number of successfully written files.
56
+ */
57
+ writeFiles(files: Array<{
58
+ path: string;
59
+ content: string;
60
+ category: 'eager' | 'lazy';
61
+ }>): Promise<number>;
62
+ private ensureFile;
63
+ private fetchFromCollection;
64
+ private writeToCache;
65
+ }
66
+
67
+ interface BuildEntryInput {
68
+ collectionId?: string;
69
+ staticBaseUrl?: string;
70
+ excludePlugins?: string;
71
+ }
72
+ declare const buildEntry: _jay_framework_fullstack_component.JayCliCommand<BuildEntryInput> & _jay_framework_fullstack_component.JayCliCommandDefinition<BuildEntryInput, [ConsoleContext]>;
73
+
74
+ interface UploadBackendInput {
75
+ collectionId?: string;
76
+ dryRun?: boolean;
77
+ }
78
+ declare const uploadBackend: _jay_framework_fullstack_component.JayCliCommand<UploadBackendInput> & _jay_framework_fullstack_component.JayCliCommandDefinition<UploadBackendInput, [WixClientService, ConsoleContext]>;
79
+
80
+ interface DeployBaasInput {
81
+ dryRun?: boolean;
82
+ }
83
+ declare const deployBaas: _jay_framework_fullstack_component.JayCliCommand<DeployBaasInput> & _jay_framework_fullstack_component.JayCliCommandDefinition<DeployBaasInput, [ConsoleContext]>;
84
+
85
+ interface DeployInput {
86
+ collectionId?: string;
87
+ staticBaseUrl?: string;
88
+ excludePlugins?: string;
89
+ dryRun?: boolean;
90
+ }
91
+ declare const deploy: _jay_framework_fullstack_component.JayCliCommand<DeployInput> & _jay_framework_fullstack_component.JayCliCommandDefinition<DeployInput, [WixClientService, ConsoleContext]>;
92
+
93
+ /**
94
+ * wix-deploy setup hook
95
+ *
96
+ * Runs after wix-server-client setup. Reads wix.config.json to populate
97
+ * clientId and siteId in config/.wix.yaml (if they're still placeholders),
98
+ * then validates the data collection exists.
99
+ */
100
+ interface SetupContext {
101
+ configDir: string;
102
+ projectRoot: string;
103
+ initError?: Error;
104
+ }
105
+ interface SetupResult {
106
+ status: 'configured' | 'needs-config' | 'error';
107
+ message?: string;
108
+ configCreated?: string[];
109
+ }
110
+ declare function setupWixDeploy(ctx: SetupContext): Promise<SetupResult>;
111
+
112
+ export { WixDataArtifactStore, type WixDataArtifactStoreOptions, buildEntry, deploy, deployBaas, setupWixDeploy, uploadBackend };