@drawcall/market 0.1.96 → 0.1.97
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/commands/upload.d.ts.map +1 -1
- package/dist/commands/upload.js +9 -68
- package/dist/commands/upload.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/upload.ts +6 -77
- package/dist/template-deployment.d.ts +0 -20
- package/dist/template-deployment.d.ts.map +0 -1
- package/dist/template-deployment.js +0 -117
- package/dist/template-deployment.js.map +0 -1
- package/src/template-deployment.ts +0 -160
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAKA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,eAAe,CAAA;AAEtB,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,iFAAiF;IACjF,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CAoFf;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQlE"}
|
package/dist/commands/upload.js
CHANGED
|
@@ -3,7 +3,6 @@ import semver from 'semver';
|
|
|
3
3
|
import { getCliClient } from '../cli-client.js';
|
|
4
4
|
import { packAsset, packPolicyFromInstallMetadata, parsePackDependencies } from '../pack.js';
|
|
5
5
|
import { unchangedUploadResult, uploadResult } from '../output.js';
|
|
6
|
-
import { buildTemplateDeployment, getTemplateDeploymentStatus, uploadTemplateDeployment, } from '../template-deployment.js';
|
|
7
6
|
import { assetDescriptionSchema, assetNameSchema, semverSchema, MAX_ASSET_DESCRIPTION_LENGTH, } from '../schemas.js';
|
|
8
7
|
export async function uploadCommand(name, zipFilter, description, opts) {
|
|
9
8
|
const spinner = ora({
|
|
@@ -23,12 +22,7 @@ export async function uploadCommand(name, zipFilter, description, opts) {
|
|
|
23
22
|
});
|
|
24
23
|
const cwd = opts.cwd ?? process.cwd();
|
|
25
24
|
const type = opts.type;
|
|
26
|
-
const { client
|
|
27
|
-
baseUrl: opts.baseUrl,
|
|
28
|
-
requireAuth: true,
|
|
29
|
-
});
|
|
30
|
-
if (!authToken)
|
|
31
|
-
throw new Error('Not logged in. Run `market login` first.');
|
|
25
|
+
const { client } = await getCliClient({ baseUrl: opts.baseUrl, requireAuth: true });
|
|
32
26
|
const installMetadata = await client.asset.installMetadata();
|
|
33
27
|
const packed = await packAsset(zipFilter, {
|
|
34
28
|
cwd,
|
|
@@ -49,53 +43,23 @@ export async function uploadCommand(name, zipFilter, description, opts) {
|
|
|
49
43
|
if (existing && existing.ownerId !== profile.id) {
|
|
50
44
|
throw new Error(`Asset "${parsedName}" already exists and is owned by another user`);
|
|
51
45
|
}
|
|
52
|
-
let unchanged = false;
|
|
53
46
|
if (existing) {
|
|
54
47
|
const latestZip = await client.asset.downloadZip({
|
|
55
48
|
name: parsedName,
|
|
56
49
|
version: existing.latestVersion,
|
|
57
50
|
});
|
|
58
51
|
const latestBytes = new Uint8Array(await latestZip.arrayBuffer());
|
|
59
|
-
|
|
60
|
-
existing.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (type === 'template') {
|
|
68
|
-
const status = await getTemplateDeploymentStatus({
|
|
69
|
-
baseUrl,
|
|
70
|
-
authToken,
|
|
71
|
-
name: parsedName,
|
|
72
|
-
version: existing.latestVersion,
|
|
73
|
-
});
|
|
74
|
-
if (!status.ready) {
|
|
75
|
-
spinner.stop();
|
|
76
|
-
const root = await buildTemplateDeployment(zipFilter, cwd);
|
|
77
|
-
spinner.start(`Uploading deployment for ${parsedName}@${existing.latestVersion}`);
|
|
78
|
-
await uploadDeployment({
|
|
79
|
-
baseUrl,
|
|
80
|
-
authToken,
|
|
81
|
-
name: parsedName,
|
|
82
|
-
version: existing.latestVersion,
|
|
83
|
-
root,
|
|
84
|
-
spinner,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
52
|
+
if (existing.description === parsedDescription &&
|
|
53
|
+
depsEqual(existing.npmDependencies, npmDependencies) &&
|
|
54
|
+
depsEqual(existing.assetDependencies, assetDependencies) &&
|
|
55
|
+
depsEqual(existing.skillDependencies, skillDependencies) &&
|
|
56
|
+
bytesEqual(latestBytes, zip)) {
|
|
57
|
+
spinner.stop();
|
|
58
|
+
console.log(unchangedUploadResult(parsedName, existing.latestVersion));
|
|
59
|
+
return;
|
|
87
60
|
}
|
|
88
|
-
spinner.stop();
|
|
89
|
-
console.log(unchangedUploadResult(parsedName, existing.latestVersion));
|
|
90
|
-
return;
|
|
91
61
|
}
|
|
92
62
|
const version = parsedVersion ?? nextVersion(existing?.latestVersion);
|
|
93
|
-
let deploymentRoot = null;
|
|
94
|
-
if (type === 'template') {
|
|
95
|
-
spinner.stop();
|
|
96
|
-
deploymentRoot = await buildTemplateDeployment(zipFilter, cwd);
|
|
97
|
-
spinner.start(`Uploading ${parsedName}@${version}`);
|
|
98
|
-
}
|
|
99
63
|
spinner.text = `Uploading ${parsedName}@${version}`;
|
|
100
64
|
const uploaded = await client.asset.uploadZip({
|
|
101
65
|
name: parsedName,
|
|
@@ -111,16 +75,6 @@ export async function uploadCommand(name, zipFilter, description, opts) {
|
|
|
111
75
|
type: 'application/zip',
|
|
112
76
|
}),
|
|
113
77
|
});
|
|
114
|
-
if (deploymentRoot) {
|
|
115
|
-
await uploadDeployment({
|
|
116
|
-
baseUrl,
|
|
117
|
-
authToken,
|
|
118
|
-
name: parsedName,
|
|
119
|
-
version: uploaded.version,
|
|
120
|
-
root: deploymentRoot,
|
|
121
|
-
spinner,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
78
|
spinner.stop();
|
|
125
79
|
console.log(uploadResult(parsedName, uploaded.version));
|
|
126
80
|
}
|
|
@@ -129,19 +83,6 @@ export async function uploadCommand(name, zipFilter, description, opts) {
|
|
|
129
83
|
throw err;
|
|
130
84
|
}
|
|
131
85
|
}
|
|
132
|
-
async function uploadDeployment(input) {
|
|
133
|
-
input.spinner.text = `Uploading deployment for ${input.name}@${input.version}`;
|
|
134
|
-
await uploadTemplateDeployment({
|
|
135
|
-
baseUrl: input.baseUrl,
|
|
136
|
-
authToken: input.authToken,
|
|
137
|
-
name: input.name,
|
|
138
|
-
version: input.version,
|
|
139
|
-
root: input.root,
|
|
140
|
-
onProgress(uploaded, total) {
|
|
141
|
-
input.spinner.text = `Uploading deployment for ${input.name}@${input.version} (${uploaded}/${total})`;
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
86
|
export function parseUploadDescription(description) {
|
|
146
87
|
try {
|
|
147
88
|
return assetDescriptionSchema.parse(description);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAC5F,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/commands/upload.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/commands/upload.ts
CHANGED
|
@@ -3,11 +3,6 @@ import semver from 'semver'
|
|
|
3
3
|
import { getCliClient } from '../cli-client.js'
|
|
4
4
|
import { packAsset, packPolicyFromInstallMetadata, parsePackDependencies } from '../pack.js'
|
|
5
5
|
import { unchangedUploadResult, uploadResult } from '../output.js'
|
|
6
|
-
import {
|
|
7
|
-
buildTemplateDeployment,
|
|
8
|
-
getTemplateDeploymentStatus,
|
|
9
|
-
uploadTemplateDeployment,
|
|
10
|
-
} from '../template-deployment.js'
|
|
11
6
|
import {
|
|
12
7
|
assetDescriptionSchema,
|
|
13
8
|
assetNameSchema,
|
|
@@ -56,11 +51,7 @@ export async function uploadCommand(
|
|
|
56
51
|
})
|
|
57
52
|
const cwd = opts.cwd ?? process.cwd()
|
|
58
53
|
const type = opts.type
|
|
59
|
-
const { client
|
|
60
|
-
baseUrl: opts.baseUrl,
|
|
61
|
-
requireAuth: true,
|
|
62
|
-
})
|
|
63
|
-
if (!authToken) throw new Error('Not logged in. Run `market login` first.')
|
|
54
|
+
const { client } = await getCliClient({ baseUrl: opts.baseUrl, requireAuth: true })
|
|
64
55
|
const installMetadata = await client.asset.installMetadata()
|
|
65
56
|
const packed = await packAsset(zipFilter, {
|
|
66
57
|
cwd,
|
|
@@ -83,56 +74,26 @@ export async function uploadCommand(
|
|
|
83
74
|
throw new Error(`Asset "${parsedName}" already exists and is owned by another user`)
|
|
84
75
|
}
|
|
85
76
|
|
|
86
|
-
let unchanged = false
|
|
87
77
|
if (existing) {
|
|
88
78
|
const latestZip = await client.asset.downloadZip({
|
|
89
79
|
name: parsedName,
|
|
90
80
|
version: existing.latestVersion,
|
|
91
81
|
})
|
|
92
82
|
const latestBytes = new Uint8Array(await latestZip.arrayBuffer())
|
|
93
|
-
|
|
83
|
+
if (
|
|
94
84
|
existing.description === parsedDescription &&
|
|
95
85
|
depsEqual(existing.npmDependencies, npmDependencies) &&
|
|
96
86
|
depsEqual(existing.assetDependencies, assetDependencies) &&
|
|
97
87
|
depsEqual(existing.skillDependencies, skillDependencies) &&
|
|
98
88
|
bytesEqual(latestBytes, zip)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const status = await getTemplateDeploymentStatus({
|
|
104
|
-
baseUrl,
|
|
105
|
-
authToken,
|
|
106
|
-
name: parsedName,
|
|
107
|
-
version: existing.latestVersion,
|
|
108
|
-
})
|
|
109
|
-
if (!status.ready) {
|
|
110
|
-
spinner.stop()
|
|
111
|
-
const root = await buildTemplateDeployment(zipFilter, cwd)
|
|
112
|
-
spinner.start(`Uploading deployment for ${parsedName}@${existing.latestVersion}`)
|
|
113
|
-
await uploadDeployment({
|
|
114
|
-
baseUrl,
|
|
115
|
-
authToken,
|
|
116
|
-
name: parsedName,
|
|
117
|
-
version: existing.latestVersion,
|
|
118
|
-
root,
|
|
119
|
-
spinner,
|
|
120
|
-
})
|
|
121
|
-
}
|
|
89
|
+
) {
|
|
90
|
+
spinner.stop()
|
|
91
|
+
console.log(unchangedUploadResult(parsedName, existing.latestVersion))
|
|
92
|
+
return
|
|
122
93
|
}
|
|
123
|
-
spinner.stop()
|
|
124
|
-
console.log(unchangedUploadResult(parsedName, existing.latestVersion))
|
|
125
|
-
return
|
|
126
94
|
}
|
|
127
95
|
|
|
128
96
|
const version = parsedVersion ?? nextVersion(existing?.latestVersion)
|
|
129
|
-
let deploymentRoot: string | null = null
|
|
130
|
-
if (type === 'template') {
|
|
131
|
-
spinner.stop()
|
|
132
|
-
deploymentRoot = await buildTemplateDeployment(zipFilter, cwd)
|
|
133
|
-
spinner.start(`Uploading ${parsedName}@${version}`)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
97
|
spinner.text = `Uploading ${parsedName}@${version}`
|
|
137
98
|
const uploaded = await client.asset.uploadZip({
|
|
138
99
|
name: parsedName,
|
|
@@ -149,17 +110,6 @@ export async function uploadCommand(
|
|
|
149
110
|
}),
|
|
150
111
|
})
|
|
151
112
|
|
|
152
|
-
if (deploymentRoot) {
|
|
153
|
-
await uploadDeployment({
|
|
154
|
-
baseUrl,
|
|
155
|
-
authToken,
|
|
156
|
-
name: parsedName,
|
|
157
|
-
version: uploaded.version,
|
|
158
|
-
root: deploymentRoot,
|
|
159
|
-
spinner,
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
|
|
163
113
|
spinner.stop()
|
|
164
114
|
console.log(uploadResult(parsedName, uploaded.version))
|
|
165
115
|
} catch (err) {
|
|
@@ -168,27 +118,6 @@ export async function uploadCommand(
|
|
|
168
118
|
}
|
|
169
119
|
}
|
|
170
120
|
|
|
171
|
-
async function uploadDeployment(input: {
|
|
172
|
-
baseUrl: string
|
|
173
|
-
authToken: string
|
|
174
|
-
name: string
|
|
175
|
-
version: string
|
|
176
|
-
root: string
|
|
177
|
-
spinner: ReturnType<typeof ora>
|
|
178
|
-
}): Promise<void> {
|
|
179
|
-
input.spinner.text = `Uploading deployment for ${input.name}@${input.version}`
|
|
180
|
-
await uploadTemplateDeployment({
|
|
181
|
-
baseUrl: input.baseUrl,
|
|
182
|
-
authToken: input.authToken,
|
|
183
|
-
name: input.name,
|
|
184
|
-
version: input.version,
|
|
185
|
-
root: input.root,
|
|
186
|
-
onProgress(uploaded, total) {
|
|
187
|
-
input.spinner.text = `Uploading deployment for ${input.name}@${input.version} (${uploaded}/${total})`
|
|
188
|
-
},
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
121
|
export function parseUploadDescription(description: string): string {
|
|
193
122
|
try {
|
|
194
123
|
return assetDescriptionSchema.parse(description)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export interface TemplateDeploymentStatus {
|
|
2
|
-
ready: boolean;
|
|
3
|
-
url: string | null;
|
|
4
|
-
}
|
|
5
|
-
export interface UploadTemplateDeploymentInput {
|
|
6
|
-
baseUrl: string;
|
|
7
|
-
authToken: string;
|
|
8
|
-
name: string;
|
|
9
|
-
version: string;
|
|
10
|
-
root: string;
|
|
11
|
-
onProgress?(uploaded: number, total: number): void;
|
|
12
|
-
}
|
|
13
|
-
export declare function buildTemplateDeployment(zipFilter: string, cwd: string): Promise<string>;
|
|
14
|
-
export declare function getTemplateDeploymentStatus(input: Omit<UploadTemplateDeploymentInput, 'root' | 'onProgress'>): Promise<TemplateDeploymentStatus>;
|
|
15
|
-
export declare function uploadTemplateDeployment(input: UploadTemplateDeploymentInput): Promise<string>;
|
|
16
|
-
export declare function deploymentFiles(root: string): Promise<Array<{
|
|
17
|
-
absolutePath: string;
|
|
18
|
-
path: string;
|
|
19
|
-
}>>;
|
|
20
|
-
//# sourceMappingURL=template-deployment.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"template-deployment.d.ts","sourceRoot":"","sources":["../src/template-deployment.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAA;IACd,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACnD;AAED,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa7F;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,IAAI,CAAC,6BAA6B,EAAE,MAAM,GAAG,YAAY,CAAC,GAChE,OAAO,CAAC,wBAAwB,CAAC,CAOnC;AAED,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAAC,MAAM,CAAC,CAwCjB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,KAAK,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAuBxD"}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs/promises';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import { detectPackageManager, runScript } from 'nypm';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
const deploymentStatusSchema = z.object({
|
|
6
|
-
ready: z.boolean(),
|
|
7
|
-
url: z.string().url().nullable(),
|
|
8
|
-
});
|
|
9
|
-
const deploymentCompleteSchema = z.object({
|
|
10
|
-
url: z.string().url(),
|
|
11
|
-
});
|
|
12
|
-
export async function buildTemplateDeployment(zipFilter, cwd) {
|
|
13
|
-
const sourceRoot = path.resolve(cwd, zipFilter);
|
|
14
|
-
const stat = await fs.stat(sourceRoot).catch(() => null);
|
|
15
|
-
if (!stat?.isDirectory()) {
|
|
16
|
-
throw new Error('Template uploads require a project directory so Market can run its build');
|
|
17
|
-
}
|
|
18
|
-
const packageManager = (await detectPackageManager(sourceRoot)) ?? 'npm';
|
|
19
|
-
await runScript('build', { cwd: sourceRoot, packageManager });
|
|
20
|
-
const deploymentRoot = path.join(sourceRoot, 'dist');
|
|
21
|
-
await requireFile(path.join(deploymentRoot, 'index.html'), 'dist/index.html');
|
|
22
|
-
await requireFile(path.join(deploymentRoot, 'schema.json'), 'dist/schema.json');
|
|
23
|
-
return deploymentRoot;
|
|
24
|
-
}
|
|
25
|
-
export async function getTemplateDeploymentStatus(input) {
|
|
26
|
-
const response = await fetch(deploymentEndpoint(input), {
|
|
27
|
-
headers: authHeaders(input.authToken),
|
|
28
|
-
});
|
|
29
|
-
const body = await responseBody(response);
|
|
30
|
-
if (!response.ok)
|
|
31
|
-
throw httpError('read template deployment', response, body);
|
|
32
|
-
return deploymentStatusSchema.parse(body);
|
|
33
|
-
}
|
|
34
|
-
export async function uploadTemplateDeployment(input) {
|
|
35
|
-
const files = await deploymentFiles(input.root);
|
|
36
|
-
if (files.length === 0)
|
|
37
|
-
throw new Error('Template deployment is empty');
|
|
38
|
-
await checkedFetch(new URL(`${deploymentEndpoint(input).pathname}/prepare`, input.baseUrl), { method: 'POST', headers: authHeaders(input.authToken) }, 'prepare template deployment');
|
|
39
|
-
let uploaded = 0;
|
|
40
|
-
for (let start = 0; start < files.length; start += 6) {
|
|
41
|
-
await Promise.all(files.slice(start, start + 6).map(async (file) => {
|
|
42
|
-
const url = deploymentEndpoint(input);
|
|
43
|
-
url.searchParams.set('path', file.path);
|
|
44
|
-
const bytes = await fs.readFile(file.absolutePath);
|
|
45
|
-
await checkedFetch(url, {
|
|
46
|
-
method: 'PUT',
|
|
47
|
-
headers: authHeaders(input.authToken),
|
|
48
|
-
body: new Blob([bytes]),
|
|
49
|
-
}, `upload ${file.path}`);
|
|
50
|
-
uploaded += 1;
|
|
51
|
-
input.onProgress?.(uploaded, files.length);
|
|
52
|
-
}));
|
|
53
|
-
}
|
|
54
|
-
const completeUrl = new URL(`${deploymentEndpoint(input).pathname}/complete`, input.baseUrl);
|
|
55
|
-
const response = await fetch(completeUrl, {
|
|
56
|
-
method: 'POST',
|
|
57
|
-
headers: authHeaders(input.authToken),
|
|
58
|
-
});
|
|
59
|
-
const body = await responseBody(response);
|
|
60
|
-
if (!response.ok)
|
|
61
|
-
throw httpError('publish template deployment', response, body);
|
|
62
|
-
return deploymentCompleteSchema.parse(body).url;
|
|
63
|
-
}
|
|
64
|
-
export async function deploymentFiles(root) {
|
|
65
|
-
const files = [];
|
|
66
|
-
async function visit(directory) {
|
|
67
|
-
const entries = await fs.readdir(directory, { withFileTypes: true });
|
|
68
|
-
for (const entry of entries) {
|
|
69
|
-
const absolutePath = path.join(directory, entry.name);
|
|
70
|
-
if (entry.isDirectory()) {
|
|
71
|
-
await visit(absolutePath);
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
if (!entry.isFile()) {
|
|
75
|
-
throw new Error(`Template deployment contains an unsupported entry: ${absolutePath}`);
|
|
76
|
-
}
|
|
77
|
-
files.push({
|
|
78
|
-
absolutePath,
|
|
79
|
-
path: path.relative(root, absolutePath).split(path.sep).join('/'),
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
await visit(root);
|
|
84
|
-
return files.sort((a, b) => a.path.localeCompare(b.path));
|
|
85
|
-
}
|
|
86
|
-
function deploymentEndpoint(input) {
|
|
87
|
-
return new URL(`/api/templates/${encodeURIComponent(input.name)}/${encodeURIComponent(input.version)}/deployment`, input.baseUrl);
|
|
88
|
-
}
|
|
89
|
-
function authHeaders(token) {
|
|
90
|
-
return new Headers({ authorization: `Bearer ${token}` });
|
|
91
|
-
}
|
|
92
|
-
async function checkedFetch(url, init, action) {
|
|
93
|
-
const response = await fetch(url, init);
|
|
94
|
-
if (response.ok)
|
|
95
|
-
return;
|
|
96
|
-
throw httpError(action, response, await responseBody(response));
|
|
97
|
-
}
|
|
98
|
-
async function responseBody(response) {
|
|
99
|
-
const text = await response.text();
|
|
100
|
-
if (!text)
|
|
101
|
-
return {};
|
|
102
|
-
try {
|
|
103
|
-
return JSON.parse(text);
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
return { raw: text };
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function httpError(action, response, body) {
|
|
110
|
-
return new Error(`${action} failed (${response.status}): ${JSON.stringify(body)}`);
|
|
111
|
-
}
|
|
112
|
-
async function requireFile(file, label) {
|
|
113
|
-
const stat = await fs.stat(file).catch(() => null);
|
|
114
|
-
if (!stat?.isFile())
|
|
115
|
-
throw new Error(`Template build did not produce ${label}`);
|
|
116
|
-
}
|
|
117
|
-
//# sourceMappingURL=template-deployment.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"template-deployment.js","sourceRoot":"","sources":["../src/template-deployment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import * as fs from 'node:fs/promises'
|
|
2
|
-
import * as path from 'node:path'
|
|
3
|
-
import { detectPackageManager, runScript } from 'nypm'
|
|
4
|
-
import { z } from 'zod'
|
|
5
|
-
|
|
6
|
-
const deploymentStatusSchema = z.object({
|
|
7
|
-
ready: z.boolean(),
|
|
8
|
-
url: z.string().url().nullable(),
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
const deploymentCompleteSchema = z.object({
|
|
12
|
-
url: z.string().url(),
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
export interface TemplateDeploymentStatus {
|
|
16
|
-
ready: boolean
|
|
17
|
-
url: string | null
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface UploadTemplateDeploymentInput {
|
|
21
|
-
baseUrl: string
|
|
22
|
-
authToken: string
|
|
23
|
-
name: string
|
|
24
|
-
version: string
|
|
25
|
-
root: string
|
|
26
|
-
onProgress?(uploaded: number, total: number): void
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function buildTemplateDeployment(zipFilter: string, cwd: string): Promise<string> {
|
|
30
|
-
const sourceRoot = path.resolve(cwd, zipFilter)
|
|
31
|
-
const stat = await fs.stat(sourceRoot).catch(() => null)
|
|
32
|
-
if (!stat?.isDirectory()) {
|
|
33
|
-
throw new Error('Template uploads require a project directory so Market can run its build')
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const packageManager = (await detectPackageManager(sourceRoot)) ?? 'npm'
|
|
37
|
-
await runScript('build', { cwd: sourceRoot, packageManager })
|
|
38
|
-
const deploymentRoot = path.join(sourceRoot, 'dist')
|
|
39
|
-
await requireFile(path.join(deploymentRoot, 'index.html'), 'dist/index.html')
|
|
40
|
-
await requireFile(path.join(deploymentRoot, 'schema.json'), 'dist/schema.json')
|
|
41
|
-
return deploymentRoot
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export async function getTemplateDeploymentStatus(
|
|
45
|
-
input: Omit<UploadTemplateDeploymentInput, 'root' | 'onProgress'>,
|
|
46
|
-
): Promise<TemplateDeploymentStatus> {
|
|
47
|
-
const response = await fetch(deploymentEndpoint(input), {
|
|
48
|
-
headers: authHeaders(input.authToken),
|
|
49
|
-
})
|
|
50
|
-
const body = await responseBody(response)
|
|
51
|
-
if (!response.ok) throw httpError('read template deployment', response, body)
|
|
52
|
-
return deploymentStatusSchema.parse(body)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export async function uploadTemplateDeployment(
|
|
56
|
-
input: UploadTemplateDeploymentInput,
|
|
57
|
-
): Promise<string> {
|
|
58
|
-
const files = await deploymentFiles(input.root)
|
|
59
|
-
if (files.length === 0) throw new Error('Template deployment is empty')
|
|
60
|
-
|
|
61
|
-
await checkedFetch(
|
|
62
|
-
new URL(`${deploymentEndpoint(input).pathname}/prepare`, input.baseUrl),
|
|
63
|
-
{ method: 'POST', headers: authHeaders(input.authToken) },
|
|
64
|
-
'prepare template deployment',
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
let uploaded = 0
|
|
68
|
-
for (let start = 0; start < files.length; start += 6) {
|
|
69
|
-
await Promise.all(
|
|
70
|
-
files.slice(start, start + 6).map(async (file) => {
|
|
71
|
-
const url = deploymentEndpoint(input)
|
|
72
|
-
url.searchParams.set('path', file.path)
|
|
73
|
-
const bytes = await fs.readFile(file.absolutePath)
|
|
74
|
-
await checkedFetch(
|
|
75
|
-
url,
|
|
76
|
-
{
|
|
77
|
-
method: 'PUT',
|
|
78
|
-
headers: authHeaders(input.authToken),
|
|
79
|
-
body: new Blob([bytes]),
|
|
80
|
-
},
|
|
81
|
-
`upload ${file.path}`,
|
|
82
|
-
)
|
|
83
|
-
uploaded += 1
|
|
84
|
-
input.onProgress?.(uploaded, files.length)
|
|
85
|
-
}),
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const completeUrl = new URL(`${deploymentEndpoint(input).pathname}/complete`, input.baseUrl)
|
|
90
|
-
const response = await fetch(completeUrl, {
|
|
91
|
-
method: 'POST',
|
|
92
|
-
headers: authHeaders(input.authToken),
|
|
93
|
-
})
|
|
94
|
-
const body = await responseBody(response)
|
|
95
|
-
if (!response.ok) throw httpError('publish template deployment', response, body)
|
|
96
|
-
return deploymentCompleteSchema.parse(body).url
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function deploymentFiles(
|
|
100
|
-
root: string,
|
|
101
|
-
): Promise<Array<{ absolutePath: string; path: string }>> {
|
|
102
|
-
const files: Array<{ absolutePath: string; path: string }> = []
|
|
103
|
-
|
|
104
|
-
async function visit(directory: string): Promise<void> {
|
|
105
|
-
const entries = await fs.readdir(directory, { withFileTypes: true })
|
|
106
|
-
for (const entry of entries) {
|
|
107
|
-
const absolutePath = path.join(directory, entry.name)
|
|
108
|
-
if (entry.isDirectory()) {
|
|
109
|
-
await visit(absolutePath)
|
|
110
|
-
continue
|
|
111
|
-
}
|
|
112
|
-
if (!entry.isFile()) {
|
|
113
|
-
throw new Error(`Template deployment contains an unsupported entry: ${absolutePath}`)
|
|
114
|
-
}
|
|
115
|
-
files.push({
|
|
116
|
-
absolutePath,
|
|
117
|
-
path: path.relative(root, absolutePath).split(path.sep).join('/'),
|
|
118
|
-
})
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
await visit(root)
|
|
123
|
-
return files.sort((a, b) => a.path.localeCompare(b.path))
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function deploymentEndpoint(input: { baseUrl: string; name: string; version: string }): URL {
|
|
127
|
-
return new URL(
|
|
128
|
-
`/api/templates/${encodeURIComponent(input.name)}/${encodeURIComponent(input.version)}/deployment`,
|
|
129
|
-
input.baseUrl,
|
|
130
|
-
)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function authHeaders(token: string): Headers {
|
|
134
|
-
return new Headers({ authorization: `Bearer ${token}` })
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
async function checkedFetch(url: URL, init: RequestInit, action: string): Promise<void> {
|
|
138
|
-
const response = await fetch(url, init)
|
|
139
|
-
if (response.ok) return
|
|
140
|
-
throw httpError(action, response, await responseBody(response))
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async function responseBody(response: Response): Promise<unknown> {
|
|
144
|
-
const text = await response.text()
|
|
145
|
-
if (!text) return {}
|
|
146
|
-
try {
|
|
147
|
-
return JSON.parse(text)
|
|
148
|
-
} catch {
|
|
149
|
-
return { raw: text }
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function httpError(action: string, response: Response, body: unknown): Error {
|
|
154
|
-
return new Error(`${action} failed (${response.status}): ${JSON.stringify(body)}`)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
async function requireFile(file: string, label: string): Promise<void> {
|
|
158
|
-
const stat = await fs.stat(file).catch(() => null)
|
|
159
|
-
if (!stat?.isFile()) throw new Error(`Template build did not produce ${label}`)
|
|
160
|
-
}
|