@highstate/cli 0.9.15 → 0.9.18
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/chunk-CMECLVT7.js +11 -0
- package/dist/chunk-CMECLVT7.js.map +1 -0
- package/dist/highstate.manifest.json +1 -1
- package/dist/library-loader-ZABUULFB.js +83 -0
- package/dist/library-loader-ZABUULFB.js.map +1 -0
- package/dist/main.js +407 -1145
- package/dist/main.js.map +1 -1
- package/package.json +24 -6
- package/src/commands/backend/identity.ts +24 -0
- package/src/commands/build.ts +42 -5
- package/src/main.ts +2 -0
- package/src/shared/index.ts +1 -0
- package/src/shared/library-loader.ts +129 -0
- package/src/shared/schema-transformer.spec.ts +489 -0
- package/src/shared/schema-transformer.ts +325 -13
- package/src/shared/schemas.ts +41 -0
- package/src/shared/source-hash-calculator.ts +129 -26
- package/src/shared/utils.ts +6 -0
package/dist/main.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
2
|
+
import { int32ToBytes } from './chunk-CMECLVT7.js';
|
|
3
|
+
import { Command, UsageError, Option, Cli, Builtins } from 'clipanion';
|
|
4
|
+
import { readPackageJSON, resolvePackageJSON } from 'pkg-types';
|
|
5
|
+
import { addDevDependency } from 'nypm';
|
|
6
|
+
import { LogLevels, consola } from 'consola';
|
|
7
|
+
import { colorize } from 'consola/utils';
|
|
8
|
+
import { getPort } from 'get-port-please';
|
|
9
|
+
import { PassThrough } from 'node:stream';
|
|
10
|
+
import pino, { levels } from 'pino';
|
|
11
|
+
import { writeFile, readFile } from 'node:fs/promises';
|
|
12
|
+
import { parseAsync } from 'oxc-parser';
|
|
13
|
+
import { walk } from 'oxc-walker';
|
|
14
|
+
import MagicString from 'magic-string';
|
|
15
|
+
import { resolve, dirname, relative } from 'node:path';
|
|
16
|
+
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
17
|
+
import { crc32 } from '@aws-crypto/crc32';
|
|
18
|
+
import { resolve as resolve$1 } from 'import-meta-resolve';
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
import { pipe, mapValues, mapKeys } from 'remeda';
|
|
21
|
+
import { build } from 'tsup';
|
|
22
|
+
import { encode } from '@msgpack/msgpack';
|
|
23
|
+
import { identityToRecipient } from 'age-encryption';
|
|
5
24
|
|
|
6
25
|
// package.json
|
|
7
|
-
var version = "0.9.
|
|
8
|
-
|
|
9
|
-
// src/commands/designer.ts
|
|
10
|
-
import { Command, UsageError } from "clipanion";
|
|
11
|
-
import { readPackageJSON as readPackageJSON2 } from "pkg-types";
|
|
12
|
-
import { addDevDependency } from "nypm";
|
|
13
|
-
import { consola as consola2 } from "consola";
|
|
14
|
-
import { colorize } from "consola/utils";
|
|
15
|
-
import { getPort } from "get-port-please";
|
|
16
|
-
|
|
17
|
-
// src/shared/logger.ts
|
|
18
|
-
import { PassThrough } from "node:stream";
|
|
19
|
-
import pino, { levels } from "pino";
|
|
20
|
-
import { consola, LogLevels } from "consola";
|
|
26
|
+
var version = "0.9.17";
|
|
21
27
|
var logger = pino(
|
|
22
28
|
{
|
|
23
29
|
name: "highstate-cli",
|
|
@@ -65,7 +71,7 @@ function getBackendServices() {
|
|
|
65
71
|
if (services) {
|
|
66
72
|
return services;
|
|
67
73
|
}
|
|
68
|
-
services = import(
|
|
74
|
+
services = import('@highstate/backend').then(({ getSharedServices }) => {
|
|
69
75
|
return getSharedServices({
|
|
70
76
|
services: {
|
|
71
77
|
logger: logger.child({}, { msgPrefix: "[backend] " })
|
|
@@ -74,1112 +80,209 @@ function getBackendServices() {
|
|
|
74
80
|
});
|
|
75
81
|
return services;
|
|
76
82
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
var intToChar = new Uint8Array(64);
|
|
88
|
-
var charToInt = new Uint8Array(128);
|
|
89
|
-
for (let i = 0; i < chars.length; i++) {
|
|
90
|
-
const c = chars.charCodeAt(i);
|
|
91
|
-
intToChar[i] = c;
|
|
92
|
-
charToInt[c] = i;
|
|
93
|
-
}
|
|
94
|
-
function encodeInteger(builder, num, relative2) {
|
|
95
|
-
let delta = num - relative2;
|
|
96
|
-
delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
|
|
97
|
-
do {
|
|
98
|
-
let clamped = delta & 31;
|
|
99
|
-
delta >>>= 5;
|
|
100
|
-
if (delta > 0)
|
|
101
|
-
clamped |= 32;
|
|
102
|
-
builder.write(intToChar[clamped]);
|
|
103
|
-
} while (delta > 0);
|
|
104
|
-
return num;
|
|
105
|
-
}
|
|
106
|
-
var bufLength = 1024 * 16;
|
|
107
|
-
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
|
|
108
|
-
decode(buf) {
|
|
109
|
-
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
110
|
-
return out.toString();
|
|
111
|
-
}
|
|
112
|
-
} : {
|
|
113
|
-
decode(buf) {
|
|
114
|
-
let out = "";
|
|
115
|
-
for (let i = 0; i < buf.length; i++) {
|
|
116
|
-
out += String.fromCharCode(buf[i]);
|
|
117
|
-
}
|
|
118
|
-
return out;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
var StringWriter = class {
|
|
122
|
-
constructor() {
|
|
123
|
-
this.pos = 0;
|
|
124
|
-
this.out = "";
|
|
125
|
-
this.buffer = new Uint8Array(bufLength);
|
|
126
|
-
}
|
|
127
|
-
write(v) {
|
|
128
|
-
const { buffer } = this;
|
|
129
|
-
buffer[this.pos++] = v;
|
|
130
|
-
if (this.pos === bufLength) {
|
|
131
|
-
this.out += td.decode(buffer);
|
|
132
|
-
this.pos = 0;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
flush() {
|
|
136
|
-
const { buffer, out, pos } = this;
|
|
137
|
-
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
function encode(decoded) {
|
|
141
|
-
const writer = new StringWriter();
|
|
142
|
-
let sourcesIndex = 0;
|
|
143
|
-
let sourceLine = 0;
|
|
144
|
-
let sourceColumn = 0;
|
|
145
|
-
let namesIndex = 0;
|
|
146
|
-
for (let i = 0; i < decoded.length; i++) {
|
|
147
|
-
const line = decoded[i];
|
|
148
|
-
if (i > 0)
|
|
149
|
-
writer.write(semicolon);
|
|
150
|
-
if (line.length === 0)
|
|
151
|
-
continue;
|
|
152
|
-
let genColumn = 0;
|
|
153
|
-
for (let j = 0; j < line.length; j++) {
|
|
154
|
-
const segment = line[j];
|
|
155
|
-
if (j > 0)
|
|
156
|
-
writer.write(comma);
|
|
157
|
-
genColumn = encodeInteger(writer, segment[0], genColumn);
|
|
158
|
-
if (segment.length === 1)
|
|
159
|
-
continue;
|
|
160
|
-
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
|
|
161
|
-
sourceLine = encodeInteger(writer, segment[2], sourceLine);
|
|
162
|
-
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
|
|
163
|
-
if (segment.length === 4)
|
|
164
|
-
continue;
|
|
165
|
-
namesIndex = encodeInteger(writer, segment[4], namesIndex);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return writer.flush();
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ../../node_modules/magic-string/dist/magic-string.es.mjs
|
|
172
|
-
var BitSet = class _BitSet {
|
|
173
|
-
constructor(arg) {
|
|
174
|
-
this.bits = arg instanceof _BitSet ? arg.bits.slice() : [];
|
|
175
|
-
}
|
|
176
|
-
add(n2) {
|
|
177
|
-
this.bits[n2 >> 5] |= 1 << (n2 & 31);
|
|
178
|
-
}
|
|
179
|
-
has(n2) {
|
|
180
|
-
return !!(this.bits[n2 >> 5] & 1 << (n2 & 31));
|
|
83
|
+
var schemaTransformerPlugin = {
|
|
84
|
+
name: "schema-transformer",
|
|
85
|
+
setup(build2) {
|
|
86
|
+
build2.onLoad({ filter: /src\/.*\.ts$/ }, async (args) => {
|
|
87
|
+
const content = await readFile(args.path, "utf-8");
|
|
88
|
+
return {
|
|
89
|
+
contents: await applySchemaTransformations(content),
|
|
90
|
+
loader: "ts"
|
|
91
|
+
};
|
|
92
|
+
});
|
|
181
93
|
}
|
|
182
94
|
};
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
clone() {
|
|
205
|
-
const chunk = new _Chunk(this.start, this.end, this.original);
|
|
206
|
-
chunk.intro = this.intro;
|
|
207
|
-
chunk.outro = this.outro;
|
|
208
|
-
chunk.content = this.content;
|
|
209
|
-
chunk.storeName = this.storeName;
|
|
210
|
-
chunk.edited = this.edited;
|
|
211
|
-
return chunk;
|
|
212
|
-
}
|
|
213
|
-
contains(index) {
|
|
214
|
-
return this.start < index && index < this.end;
|
|
215
|
-
}
|
|
216
|
-
eachNext(fn) {
|
|
217
|
-
let chunk = this;
|
|
218
|
-
while (chunk) {
|
|
219
|
-
fn(chunk);
|
|
220
|
-
chunk = chunk.next;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
eachPrevious(fn) {
|
|
224
|
-
let chunk = this;
|
|
225
|
-
while (chunk) {
|
|
226
|
-
fn(chunk);
|
|
227
|
-
chunk = chunk.previous;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
edit(content, storeName, contentOnly) {
|
|
231
|
-
this.content = content;
|
|
232
|
-
if (!contentOnly) {
|
|
233
|
-
this.intro = "";
|
|
234
|
-
this.outro = "";
|
|
235
|
-
}
|
|
236
|
-
this.storeName = storeName;
|
|
237
|
-
this.edited = true;
|
|
238
|
-
return this;
|
|
239
|
-
}
|
|
240
|
-
prependLeft(content) {
|
|
241
|
-
this.outro = content + this.outro;
|
|
242
|
-
}
|
|
243
|
-
prependRight(content) {
|
|
244
|
-
this.intro = content + this.intro;
|
|
245
|
-
}
|
|
246
|
-
reset() {
|
|
247
|
-
this.intro = "";
|
|
248
|
-
this.outro = "";
|
|
249
|
-
if (this.edited) {
|
|
250
|
-
this.content = this.original;
|
|
251
|
-
this.storeName = false;
|
|
252
|
-
this.edited = false;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
split(index) {
|
|
256
|
-
const sliceIndex = index - this.start;
|
|
257
|
-
const originalBefore = this.original.slice(0, sliceIndex);
|
|
258
|
-
const originalAfter = this.original.slice(sliceIndex);
|
|
259
|
-
this.original = originalBefore;
|
|
260
|
-
const newChunk = new _Chunk(index, this.end, originalAfter);
|
|
261
|
-
newChunk.outro = this.outro;
|
|
262
|
-
this.outro = "";
|
|
263
|
-
this.end = index;
|
|
264
|
-
if (this.edited) {
|
|
265
|
-
newChunk.edit("", false);
|
|
266
|
-
this.content = "";
|
|
267
|
-
} else {
|
|
268
|
-
this.content = originalBefore;
|
|
269
|
-
}
|
|
270
|
-
newChunk.next = this.next;
|
|
271
|
-
if (newChunk.next) newChunk.next.previous = newChunk;
|
|
272
|
-
newChunk.previous = this;
|
|
273
|
-
this.next = newChunk;
|
|
274
|
-
return newChunk;
|
|
275
|
-
}
|
|
276
|
-
toString() {
|
|
277
|
-
return this.intro + this.content + this.outro;
|
|
278
|
-
}
|
|
279
|
-
trimEnd(rx) {
|
|
280
|
-
this.outro = this.outro.replace(rx, "");
|
|
281
|
-
if (this.outro.length) return true;
|
|
282
|
-
const trimmed = this.content.replace(rx, "");
|
|
283
|
-
if (trimmed.length) {
|
|
284
|
-
if (trimmed !== this.content) {
|
|
285
|
-
this.split(this.start + trimmed.length).edit("", void 0, true);
|
|
286
|
-
if (this.edited) {
|
|
287
|
-
this.edit(trimmed, this.storeName, true);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
return true;
|
|
291
|
-
} else {
|
|
292
|
-
this.edit("", void 0, true);
|
|
293
|
-
this.intro = this.intro.replace(rx, "");
|
|
294
|
-
if (this.intro.length) return true;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
trimStart(rx) {
|
|
298
|
-
this.intro = this.intro.replace(rx, "");
|
|
299
|
-
if (this.intro.length) return true;
|
|
300
|
-
const trimmed = this.content.replace(rx, "");
|
|
301
|
-
if (trimmed.length) {
|
|
302
|
-
if (trimmed !== this.content) {
|
|
303
|
-
const newChunk = this.split(this.end - trimmed.length);
|
|
304
|
-
if (this.edited) {
|
|
305
|
-
newChunk.edit(trimmed, this.storeName, true);
|
|
95
|
+
async function applySchemaTransformations(content) {
|
|
96
|
+
const { program, comments } = await parseAsync("file.ts", content);
|
|
97
|
+
const transformations = [];
|
|
98
|
+
const parentStack = [];
|
|
99
|
+
walk(program, {
|
|
100
|
+
enter(node) {
|
|
101
|
+
parentStack.push(node);
|
|
102
|
+
if (node.type === "Property" && node.key.type === "Identifier" && isInsideZodObject(parentStack)) {
|
|
103
|
+
const jsdoc2 = comments.find((comment) => isLeadingComment(content, node, comment));
|
|
104
|
+
if (jsdoc2) {
|
|
105
|
+
const description2 = cleanJsdoc(jsdoc2.value);
|
|
106
|
+
const fieldName = node.key.name;
|
|
107
|
+
const originalValue2 = content.substring(node.value.start, node.value.end);
|
|
108
|
+
if (!originalValue2.includes(".meta(")) {
|
|
109
|
+
transformations.push({
|
|
110
|
+
start: node.value.start,
|
|
111
|
+
end: node.value.end,
|
|
112
|
+
newValue: `${originalValue2}.meta({ title: __camelCaseToHumanReadable("${fieldName}"), description: \`${description2}\` })`,
|
|
113
|
+
type: "zod-meta"
|
|
114
|
+
});
|
|
115
|
+
}
|
|
306
116
|
}
|
|
307
|
-
|
|
117
|
+
return;
|
|
308
118
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
this.edit("", void 0, true);
|
|
312
|
-
this.outro = this.outro.replace(rx, "");
|
|
313
|
-
if (this.outro.length) return true;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
function getBtoa() {
|
|
318
|
-
if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") {
|
|
319
|
-
return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));
|
|
320
|
-
} else if (typeof Buffer === "function") {
|
|
321
|
-
return (str) => Buffer.from(str, "utf-8").toString("base64");
|
|
322
|
-
} else {
|
|
323
|
-
return () => {
|
|
324
|
-
throw new Error("Unsupported environment: `window.btoa` or `Buffer` should be supported.");
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
var btoa = /* @__PURE__ */ getBtoa();
|
|
329
|
-
var SourceMap = class {
|
|
330
|
-
constructor(properties) {
|
|
331
|
-
this.version = 3;
|
|
332
|
-
this.file = properties.file;
|
|
333
|
-
this.sources = properties.sources;
|
|
334
|
-
this.sourcesContent = properties.sourcesContent;
|
|
335
|
-
this.names = properties.names;
|
|
336
|
-
this.mappings = encode(properties.mappings);
|
|
337
|
-
if (typeof properties.x_google_ignoreList !== "undefined") {
|
|
338
|
-
this.x_google_ignoreList = properties.x_google_ignoreList;
|
|
339
|
-
}
|
|
340
|
-
if (typeof properties.debugId !== "undefined") {
|
|
341
|
-
this.debugId = properties.debugId;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
toString() {
|
|
345
|
-
return JSON.stringify(this);
|
|
346
|
-
}
|
|
347
|
-
toUrl() {
|
|
348
|
-
return "data:application/json;charset=utf-8;base64," + btoa(this.toString());
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
function guessIndent(code) {
|
|
352
|
-
const lines = code.split("\n");
|
|
353
|
-
const tabbed = lines.filter((line) => /^\t+/.test(line));
|
|
354
|
-
const spaced = lines.filter((line) => /^ {2,}/.test(line));
|
|
355
|
-
if (tabbed.length === 0 && spaced.length === 0) {
|
|
356
|
-
return null;
|
|
357
|
-
}
|
|
358
|
-
if (tabbed.length >= spaced.length) {
|
|
359
|
-
return " ";
|
|
360
|
-
}
|
|
361
|
-
const min = spaced.reduce((previous, current) => {
|
|
362
|
-
const numSpaces = /^ +/.exec(current)[0].length;
|
|
363
|
-
return Math.min(numSpaces, previous);
|
|
364
|
-
}, Infinity);
|
|
365
|
-
return new Array(min + 1).join(" ");
|
|
366
|
-
}
|
|
367
|
-
function getRelativePath(from, to) {
|
|
368
|
-
const fromParts = from.split(/[/\\]/);
|
|
369
|
-
const toParts = to.split(/[/\\]/);
|
|
370
|
-
fromParts.pop();
|
|
371
|
-
while (fromParts[0] === toParts[0]) {
|
|
372
|
-
fromParts.shift();
|
|
373
|
-
toParts.shift();
|
|
374
|
-
}
|
|
375
|
-
if (fromParts.length) {
|
|
376
|
-
let i = fromParts.length;
|
|
377
|
-
while (i--) fromParts[i] = "..";
|
|
378
|
-
}
|
|
379
|
-
return fromParts.concat(toParts).join("/");
|
|
380
|
-
}
|
|
381
|
-
var toString = Object.prototype.toString;
|
|
382
|
-
function isObject(thing) {
|
|
383
|
-
return toString.call(thing) === "[object Object]";
|
|
384
|
-
}
|
|
385
|
-
function getLocator(source) {
|
|
386
|
-
const originalLines = source.split("\n");
|
|
387
|
-
const lineOffsets = [];
|
|
388
|
-
for (let i = 0, pos = 0; i < originalLines.length; i++) {
|
|
389
|
-
lineOffsets.push(pos);
|
|
390
|
-
pos += originalLines[i].length + 1;
|
|
391
|
-
}
|
|
392
|
-
return function locate(index) {
|
|
393
|
-
let i = 0;
|
|
394
|
-
let j = lineOffsets.length;
|
|
395
|
-
while (i < j) {
|
|
396
|
-
const m = i + j >> 1;
|
|
397
|
-
if (index < lineOffsets[m]) {
|
|
398
|
-
j = m;
|
|
399
|
-
} else {
|
|
400
|
-
i = m + 1;
|
|
119
|
+
if (node.type !== "Property" || node.key.type !== "Identifier") {
|
|
120
|
+
return;
|
|
401
121
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
return { line, column };
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
var wordRegex = /\w/;
|
|
409
|
-
var Mappings = class {
|
|
410
|
-
constructor(hires) {
|
|
411
|
-
this.hires = hires;
|
|
412
|
-
this.generatedCodeLine = 0;
|
|
413
|
-
this.generatedCodeColumn = 0;
|
|
414
|
-
this.raw = [];
|
|
415
|
-
this.rawSegments = this.raw[this.generatedCodeLine] = [];
|
|
416
|
-
this.pending = null;
|
|
417
|
-
}
|
|
418
|
-
addEdit(sourceIndex, content, loc, nameIndex) {
|
|
419
|
-
if (content.length) {
|
|
420
|
-
const contentLengthMinusOne = content.length - 1;
|
|
421
|
-
let contentLineEnd = content.indexOf("\n", 0);
|
|
422
|
-
let previousContentLineEnd = -1;
|
|
423
|
-
while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {
|
|
424
|
-
const segment2 = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
|
|
425
|
-
if (nameIndex >= 0) {
|
|
426
|
-
segment2.push(nameIndex);
|
|
427
|
-
}
|
|
428
|
-
this.rawSegments.push(segment2);
|
|
429
|
-
this.generatedCodeLine += 1;
|
|
430
|
-
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
431
|
-
this.generatedCodeColumn = 0;
|
|
432
|
-
previousContentLineEnd = contentLineEnd;
|
|
433
|
-
contentLineEnd = content.indexOf("\n", contentLineEnd + 1);
|
|
122
|
+
const parentKey = getParentObjectKey(parentStack) || getMarkerFunctionName(parentStack);
|
|
123
|
+
if (!parentKey || !["inputs", "outputs", "args", "secrets"].includes(parentKey)) {
|
|
124
|
+
return;
|
|
434
125
|
}
|
|
435
|
-
const
|
|
436
|
-
if (
|
|
437
|
-
|
|
126
|
+
const jsdoc = comments.find((comment) => isLeadingComment(content, node, comment));
|
|
127
|
+
if (!jsdoc) {
|
|
128
|
+
return;
|
|
438
129
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
while (originalCharIndex < chunk.end) {
|
|
452
|
-
if (original[originalCharIndex] === "\n") {
|
|
453
|
-
loc.line += 1;
|
|
454
|
-
loc.column = 0;
|
|
455
|
-
this.generatedCodeLine += 1;
|
|
456
|
-
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
457
|
-
this.generatedCodeColumn = 0;
|
|
458
|
-
first = true;
|
|
459
|
-
charInHiresBoundary = false;
|
|
130
|
+
const description = cleanJsdoc(jsdoc.value);
|
|
131
|
+
const originalValue = content.substring(node.value.start, node.value.end);
|
|
132
|
+
const entityField = ["inputs", "outputs"].includes(parentKey) ? "entity" : "schema";
|
|
133
|
+
const isAlreadyStructured = isStructuredValue(originalValue, entityField);
|
|
134
|
+
if (isAlreadyStructured) {
|
|
135
|
+
const modifiedValue = injectDescriptionIntoObject(originalValue, description);
|
|
136
|
+
transformations.push({
|
|
137
|
+
start: node.value.start,
|
|
138
|
+
end: node.value.end,
|
|
139
|
+
newValue: modifiedValue,
|
|
140
|
+
type: "schema-structure"
|
|
141
|
+
});
|
|
460
142
|
} else {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
} else {
|
|
474
|
-
this.rawSegments.push(segment);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
loc.column += 1;
|
|
478
|
-
this.generatedCodeColumn += 1;
|
|
479
|
-
first = false;
|
|
480
|
-
}
|
|
481
|
-
originalCharIndex += 1;
|
|
482
|
-
}
|
|
483
|
-
this.pending = null;
|
|
484
|
-
}
|
|
485
|
-
advance(str) {
|
|
486
|
-
if (!str) return;
|
|
487
|
-
const lines = str.split("\n");
|
|
488
|
-
if (lines.length > 1) {
|
|
489
|
-
for (let i = 0; i < lines.length - 1; i++) {
|
|
490
|
-
this.generatedCodeLine++;
|
|
491
|
-
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
492
|
-
}
|
|
493
|
-
this.generatedCodeColumn = 0;
|
|
494
|
-
}
|
|
495
|
-
this.generatedCodeColumn += lines[lines.length - 1].length;
|
|
496
|
-
}
|
|
497
|
-
};
|
|
498
|
-
var n = "\n";
|
|
499
|
-
var warned = {
|
|
500
|
-
insertLeft: false,
|
|
501
|
-
insertRight: false,
|
|
502
|
-
storeName: false
|
|
503
|
-
};
|
|
504
|
-
var MagicString = class _MagicString {
|
|
505
|
-
constructor(string, options = {}) {
|
|
506
|
-
const chunk = new Chunk(0, string.length, string);
|
|
507
|
-
Object.defineProperties(this, {
|
|
508
|
-
original: { writable: true, value: string },
|
|
509
|
-
outro: { writable: true, value: "" },
|
|
510
|
-
intro: { writable: true, value: "" },
|
|
511
|
-
firstChunk: { writable: true, value: chunk },
|
|
512
|
-
lastChunk: { writable: true, value: chunk },
|
|
513
|
-
lastSearchedChunk: { writable: true, value: chunk },
|
|
514
|
-
byStart: { writable: true, value: {} },
|
|
515
|
-
byEnd: { writable: true, value: {} },
|
|
516
|
-
filename: { writable: true, value: options.filename },
|
|
517
|
-
indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
|
|
518
|
-
sourcemapLocations: { writable: true, value: new BitSet() },
|
|
519
|
-
storedNames: { writable: true, value: {} },
|
|
520
|
-
indentStr: { writable: true, value: void 0 },
|
|
521
|
-
ignoreList: { writable: true, value: options.ignoreList },
|
|
522
|
-
offset: { writable: true, value: options.offset || 0 }
|
|
523
|
-
});
|
|
524
|
-
this.byStart[0] = chunk;
|
|
525
|
-
this.byEnd[string.length] = chunk;
|
|
526
|
-
}
|
|
527
|
-
addSourcemapLocation(char) {
|
|
528
|
-
this.sourcemapLocations.add(char);
|
|
529
|
-
}
|
|
530
|
-
append(content) {
|
|
531
|
-
if (typeof content !== "string") throw new TypeError("outro content must be a string");
|
|
532
|
-
this.outro += content;
|
|
533
|
-
return this;
|
|
534
|
-
}
|
|
535
|
-
appendLeft(index, content) {
|
|
536
|
-
index = index + this.offset;
|
|
537
|
-
if (typeof content !== "string") throw new TypeError("inserted content must be a string");
|
|
538
|
-
this._split(index);
|
|
539
|
-
const chunk = this.byEnd[index];
|
|
540
|
-
if (chunk) {
|
|
541
|
-
chunk.appendLeft(content);
|
|
542
|
-
} else {
|
|
543
|
-
this.intro += content;
|
|
544
|
-
}
|
|
545
|
-
return this;
|
|
546
|
-
}
|
|
547
|
-
appendRight(index, content) {
|
|
548
|
-
index = index + this.offset;
|
|
549
|
-
if (typeof content !== "string") throw new TypeError("inserted content must be a string");
|
|
550
|
-
this._split(index);
|
|
551
|
-
const chunk = this.byStart[index];
|
|
552
|
-
if (chunk) {
|
|
553
|
-
chunk.appendRight(content);
|
|
554
|
-
} else {
|
|
555
|
-
this.outro += content;
|
|
556
|
-
}
|
|
557
|
-
return this;
|
|
558
|
-
}
|
|
559
|
-
clone() {
|
|
560
|
-
const cloned = new _MagicString(this.original, { filename: this.filename, offset: this.offset });
|
|
561
|
-
let originalChunk = this.firstChunk;
|
|
562
|
-
let clonedChunk = cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone();
|
|
563
|
-
while (originalChunk) {
|
|
564
|
-
cloned.byStart[clonedChunk.start] = clonedChunk;
|
|
565
|
-
cloned.byEnd[clonedChunk.end] = clonedChunk;
|
|
566
|
-
const nextOriginalChunk = originalChunk.next;
|
|
567
|
-
const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
|
|
568
|
-
if (nextClonedChunk) {
|
|
569
|
-
clonedChunk.next = nextClonedChunk;
|
|
570
|
-
nextClonedChunk.previous = clonedChunk;
|
|
571
|
-
clonedChunk = nextClonedChunk;
|
|
143
|
+
transformations.push({
|
|
144
|
+
start: node.value.start,
|
|
145
|
+
end: node.value.end,
|
|
146
|
+
newValue: `{
|
|
147
|
+
${entityField}: ${originalValue},
|
|
148
|
+
meta: {
|
|
149
|
+
description: \`${description}\`,
|
|
150
|
+
},
|
|
151
|
+
}`,
|
|
152
|
+
type: "schema-structure"
|
|
153
|
+
});
|
|
572
154
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (this.indentExclusionRanges) {
|
|
577
|
-
cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
|
|
155
|
+
},
|
|
156
|
+
leave() {
|
|
157
|
+
parentStack.pop();
|
|
578
158
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
options = options || {};
|
|
586
|
-
const sourceIndex = 0;
|
|
587
|
-
const names = Object.keys(this.storedNames);
|
|
588
|
-
const mappings = new Mappings(options.hires);
|
|
589
|
-
const locate = getLocator(this.original);
|
|
590
|
-
if (this.intro) {
|
|
591
|
-
mappings.advance(this.intro);
|
|
592
|
-
}
|
|
593
|
-
this.firstChunk.eachNext((chunk) => {
|
|
594
|
-
const loc = locate(chunk.start);
|
|
595
|
-
if (chunk.intro.length) mappings.advance(chunk.intro);
|
|
596
|
-
if (chunk.edited) {
|
|
597
|
-
mappings.addEdit(
|
|
598
|
-
sourceIndex,
|
|
599
|
-
chunk.content,
|
|
600
|
-
loc,
|
|
601
|
-
chunk.storeName ? names.indexOf(chunk.original) : -1
|
|
602
|
-
);
|
|
603
|
-
} else {
|
|
604
|
-
mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);
|
|
605
|
-
}
|
|
606
|
-
if (chunk.outro.length) mappings.advance(chunk.outro);
|
|
159
|
+
});
|
|
160
|
+
const zodMetaTransformations = transformations.filter((t) => t.type === "zod-meta");
|
|
161
|
+
const schemaTransformations = transformations.filter((t) => t.type === "schema-structure");
|
|
162
|
+
const processedSchemaTransformations = schemaTransformations.map((schemaTransform) => {
|
|
163
|
+
const containedZodMetas = zodMetaTransformations.filter((zodTransform) => {
|
|
164
|
+
return schemaTransform.start <= zodTransform.start && schemaTransform.end >= zodTransform.end;
|
|
607
165
|
});
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
mappings: mappings.raw,
|
|
616
|
-
x_google_ignoreList: this.ignoreList ? [sourceIndex] : void 0
|
|
617
|
-
};
|
|
618
|
-
}
|
|
619
|
-
generateMap(options) {
|
|
620
|
-
return new SourceMap(this.generateDecodedMap(options));
|
|
621
|
-
}
|
|
622
|
-
_ensureindentStr() {
|
|
623
|
-
if (this.indentStr === void 0) {
|
|
624
|
-
this.indentStr = guessIndent(this.original);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
_getRawIndentString() {
|
|
628
|
-
this._ensureindentStr();
|
|
629
|
-
return this.indentStr;
|
|
630
|
-
}
|
|
631
|
-
getIndentString() {
|
|
632
|
-
this._ensureindentStr();
|
|
633
|
-
return this.indentStr === null ? " " : this.indentStr;
|
|
634
|
-
}
|
|
635
|
-
indent(indentStr, options) {
|
|
636
|
-
const pattern = /^[^\r\n]/gm;
|
|
637
|
-
if (isObject(indentStr)) {
|
|
638
|
-
options = indentStr;
|
|
639
|
-
indentStr = void 0;
|
|
640
|
-
}
|
|
641
|
-
if (indentStr === void 0) {
|
|
642
|
-
this._ensureindentStr();
|
|
643
|
-
indentStr = this.indentStr || " ";
|
|
644
|
-
}
|
|
645
|
-
if (indentStr === "") return this;
|
|
646
|
-
options = options || {};
|
|
647
|
-
const isExcluded = {};
|
|
648
|
-
if (options.exclude) {
|
|
649
|
-
const exclusions = typeof options.exclude[0] === "number" ? [options.exclude] : options.exclude;
|
|
650
|
-
exclusions.forEach((exclusion) => {
|
|
651
|
-
for (let i = exclusion[0]; i < exclusion[1]; i += 1) {
|
|
652
|
-
isExcluded[i] = true;
|
|
653
|
-
}
|
|
166
|
+
if (containedZodMetas.length > 0) {
|
|
167
|
+
const originalContent = content.substring(schemaTransform.start, schemaTransform.end);
|
|
168
|
+
const tempMagicString = new MagicString(originalContent);
|
|
169
|
+
containedZodMetas.sort((a, b) => b.start - a.start).forEach((zodTransform) => {
|
|
170
|
+
const relativeStart = zodTransform.start - schemaTransform.start;
|
|
171
|
+
const relativeEnd = zodTransform.end - schemaTransform.start;
|
|
172
|
+
tempMagicString.update(relativeStart, relativeEnd, zodTransform.newValue);
|
|
654
173
|
});
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
if (
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
let charIndex = 0;
|
|
664
|
-
let chunk = this.firstChunk;
|
|
665
|
-
while (chunk) {
|
|
666
|
-
const end = chunk.end;
|
|
667
|
-
if (chunk.edited) {
|
|
668
|
-
if (!isExcluded[charIndex]) {
|
|
669
|
-
chunk.content = chunk.content.replace(pattern, replacer);
|
|
670
|
-
if (chunk.content.length) {
|
|
671
|
-
shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === "\n";
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
} else {
|
|
675
|
-
charIndex = chunk.start;
|
|
676
|
-
while (charIndex < end) {
|
|
677
|
-
if (!isExcluded[charIndex]) {
|
|
678
|
-
const char = this.original[charIndex];
|
|
679
|
-
if (char === "\n") {
|
|
680
|
-
shouldIndentNextCharacter = true;
|
|
681
|
-
} else if (char !== "\r" && shouldIndentNextCharacter) {
|
|
682
|
-
shouldIndentNextCharacter = false;
|
|
683
|
-
if (charIndex === chunk.start) {
|
|
684
|
-
chunk.prependRight(indentStr);
|
|
685
|
-
} else {
|
|
686
|
-
this._splitChunk(chunk, charIndex);
|
|
687
|
-
chunk = chunk.next;
|
|
688
|
-
chunk.prependRight(indentStr);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
charIndex += 1;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
charIndex = chunk.end;
|
|
696
|
-
chunk = chunk.next;
|
|
697
|
-
}
|
|
698
|
-
this.outro = this.outro.replace(pattern, replacer);
|
|
699
|
-
return this;
|
|
700
|
-
}
|
|
701
|
-
insert() {
|
|
702
|
-
throw new Error(
|
|
703
|
-
"magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)"
|
|
704
|
-
);
|
|
705
|
-
}
|
|
706
|
-
insertLeft(index, content) {
|
|
707
|
-
if (!warned.insertLeft) {
|
|
708
|
-
console.warn(
|
|
709
|
-
"magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead"
|
|
710
|
-
);
|
|
711
|
-
warned.insertLeft = true;
|
|
712
|
-
}
|
|
713
|
-
return this.appendLeft(index, content);
|
|
714
|
-
}
|
|
715
|
-
insertRight(index, content) {
|
|
716
|
-
if (!warned.insertRight) {
|
|
717
|
-
console.warn(
|
|
718
|
-
"magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead"
|
|
719
|
-
);
|
|
720
|
-
warned.insertRight = true;
|
|
721
|
-
}
|
|
722
|
-
return this.prependRight(index, content);
|
|
723
|
-
}
|
|
724
|
-
move(start, end, index) {
|
|
725
|
-
start = start + this.offset;
|
|
726
|
-
end = end + this.offset;
|
|
727
|
-
index = index + this.offset;
|
|
728
|
-
if (index >= start && index <= end) throw new Error("Cannot move a selection inside itself");
|
|
729
|
-
this._split(start);
|
|
730
|
-
this._split(end);
|
|
731
|
-
this._split(index);
|
|
732
|
-
const first = this.byStart[start];
|
|
733
|
-
const last = this.byEnd[end];
|
|
734
|
-
const oldLeft = first.previous;
|
|
735
|
-
const oldRight = last.next;
|
|
736
|
-
const newRight = this.byStart[index];
|
|
737
|
-
if (!newRight && last === this.lastChunk) return this;
|
|
738
|
-
const newLeft = newRight ? newRight.previous : this.lastChunk;
|
|
739
|
-
if (oldLeft) oldLeft.next = oldRight;
|
|
740
|
-
if (oldRight) oldRight.previous = oldLeft;
|
|
741
|
-
if (newLeft) newLeft.next = first;
|
|
742
|
-
if (newRight) newRight.previous = last;
|
|
743
|
-
if (!first.previous) this.firstChunk = last.next;
|
|
744
|
-
if (!last.next) {
|
|
745
|
-
this.lastChunk = first.previous;
|
|
746
|
-
this.lastChunk.next = null;
|
|
747
|
-
}
|
|
748
|
-
first.previous = newLeft;
|
|
749
|
-
last.next = newRight || null;
|
|
750
|
-
if (!newLeft) this.firstChunk = first;
|
|
751
|
-
if (!newRight) this.lastChunk = last;
|
|
752
|
-
return this;
|
|
753
|
-
}
|
|
754
|
-
overwrite(start, end, content, options) {
|
|
755
|
-
options = options || {};
|
|
756
|
-
return this.update(start, end, content, { ...options, overwrite: !options.contentOnly });
|
|
757
|
-
}
|
|
758
|
-
update(start, end, content, options) {
|
|
759
|
-
start = start + this.offset;
|
|
760
|
-
end = end + this.offset;
|
|
761
|
-
if (typeof content !== "string") throw new TypeError("replacement content must be a string");
|
|
762
|
-
if (this.original.length !== 0) {
|
|
763
|
-
while (start < 0) start += this.original.length;
|
|
764
|
-
while (end < 0) end += this.original.length;
|
|
765
|
-
}
|
|
766
|
-
if (end > this.original.length) throw new Error("end is out of bounds");
|
|
767
|
-
if (start === end)
|
|
768
|
-
throw new Error(
|
|
769
|
-
"Cannot overwrite a zero-length range \u2013 use appendLeft or prependRight instead"
|
|
770
|
-
);
|
|
771
|
-
this._split(start);
|
|
772
|
-
this._split(end);
|
|
773
|
-
if (options === true) {
|
|
774
|
-
if (!warned.storeName) {
|
|
775
|
-
console.warn(
|
|
776
|
-
"The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string"
|
|
174
|
+
const modifiedContent = tempMagicString.toString();
|
|
175
|
+
const entityField = schemaTransform.newValue.includes("entity:") ? "entity" : "schema";
|
|
176
|
+
const descriptionMatch = schemaTransform.newValue.match(/description: `([^`]+)`/);
|
|
177
|
+
if (descriptionMatch) {
|
|
178
|
+
const description = descriptionMatch[1];
|
|
179
|
+
const isAlreadyStructured = isStructuredValue(
|
|
180
|
+
content.substring(schemaTransform.start, schemaTransform.end),
|
|
181
|
+
entityField
|
|
777
182
|
);
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
let chunk = first;
|
|
796
|
-
while (chunk !== last) {
|
|
797
|
-
if (chunk.next !== this.byStart[chunk.end]) {
|
|
798
|
-
throw new Error("Cannot overwrite across a split point");
|
|
183
|
+
if (isAlreadyStructured) {
|
|
184
|
+
return {
|
|
185
|
+
...schemaTransform,
|
|
186
|
+
newValue: injectDescriptionIntoObject(modifiedContent, description),
|
|
187
|
+
containsZodMeta: true
|
|
188
|
+
};
|
|
189
|
+
} else {
|
|
190
|
+
return {
|
|
191
|
+
...schemaTransform,
|
|
192
|
+
newValue: `{
|
|
193
|
+
${entityField}: ${modifiedContent},
|
|
194
|
+
meta: {
|
|
195
|
+
description: \`${description}\`,
|
|
196
|
+
},
|
|
197
|
+
}`,
|
|
198
|
+
containsZodMeta: true
|
|
199
|
+
};
|
|
799
200
|
}
|
|
800
|
-
chunk = chunk.next;
|
|
801
|
-
chunk.edit("", false);
|
|
802
201
|
}
|
|
803
|
-
first.edit(content, storeName, !overwrite);
|
|
804
|
-
} else {
|
|
805
|
-
const newChunk = new Chunk(start, end, "").edit(content, storeName);
|
|
806
|
-
last.next = newChunk;
|
|
807
|
-
newChunk.previous = last;
|
|
808
202
|
}
|
|
809
|
-
return
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
203
|
+
return { ...schemaTransform, containsZodMeta: false };
|
|
204
|
+
});
|
|
205
|
+
const independentZodMetas = zodMetaTransformations.filter((zodTransform) => {
|
|
206
|
+
return !schemaTransformations.some((schemaTransform) => {
|
|
207
|
+
return schemaTransform.start <= zodTransform.start && schemaTransform.end >= zodTransform.end;
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
const finalTransformations = [
|
|
211
|
+
...independentZodMetas,
|
|
212
|
+
...processedSchemaTransformations.map(({ containsZodMeta, ...rest }) => rest)
|
|
213
|
+
// eslint-disable-line @typescript-eslint/no-unused-vars
|
|
214
|
+
];
|
|
215
|
+
const hasZodMetaTransformations = zodMetaTransformations.length > 0;
|
|
216
|
+
const needsImport = hasZodMetaTransformations && !content.includes("__camelCaseToHumanReadable");
|
|
217
|
+
let result = content;
|
|
218
|
+
const magicString = new MagicString(result);
|
|
219
|
+
finalTransformations.sort((a, b) => b.start - a.start).forEach((transformation) => {
|
|
220
|
+
magicString.update(transformation.start, transformation.end, transformation.newValue);
|
|
221
|
+
});
|
|
222
|
+
result = magicString.toString();
|
|
223
|
+
if (needsImport) {
|
|
224
|
+
result = 'import { camelCaseToHumanReadable as __camelCaseToHumanReadable } from "@highstate/contract"\n' + result;
|
|
827
225
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
function injectDescriptionIntoObject(objectString, description) {
|
|
229
|
+
const trimmed = objectString.trim();
|
|
230
|
+
const metaRegex = /meta\s*:\s*\{/;
|
|
231
|
+
if (metaRegex.test(trimmed)) {
|
|
232
|
+
const hasDescription = /meta\s*:\s*\{[^}]*description\s*:/.test(trimmed);
|
|
233
|
+
if (hasDescription) {
|
|
234
|
+
return trimmed.replace(/description\s*:\s*`[^`]*`/, `description: \`${description}\``);
|
|
835
235
|
} else {
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
remove(start, end) {
|
|
841
|
-
start = start + this.offset;
|
|
842
|
-
end = end + this.offset;
|
|
843
|
-
if (this.original.length !== 0) {
|
|
844
|
-
while (start < 0) start += this.original.length;
|
|
845
|
-
while (end < 0) end += this.original.length;
|
|
846
|
-
}
|
|
847
|
-
if (start === end) return this;
|
|
848
|
-
if (start < 0 || end > this.original.length) throw new Error("Character is out of bounds");
|
|
849
|
-
if (start > end) throw new Error("end must be greater than start");
|
|
850
|
-
this._split(start);
|
|
851
|
-
this._split(end);
|
|
852
|
-
let chunk = this.byStart[start];
|
|
853
|
-
while (chunk) {
|
|
854
|
-
chunk.intro = "";
|
|
855
|
-
chunk.outro = "";
|
|
856
|
-
chunk.edit("");
|
|
857
|
-
chunk = end > chunk.end ? this.byStart[chunk.end] : null;
|
|
858
|
-
}
|
|
859
|
-
return this;
|
|
860
|
-
}
|
|
861
|
-
reset(start, end) {
|
|
862
|
-
start = start + this.offset;
|
|
863
|
-
end = end + this.offset;
|
|
864
|
-
if (this.original.length !== 0) {
|
|
865
|
-
while (start < 0) start += this.original.length;
|
|
866
|
-
while (end < 0) end += this.original.length;
|
|
867
|
-
}
|
|
868
|
-
if (start === end) return this;
|
|
869
|
-
if (start < 0 || end > this.original.length) throw new Error("Character is out of bounds");
|
|
870
|
-
if (start > end) throw new Error("end must be greater than start");
|
|
871
|
-
this._split(start);
|
|
872
|
-
this._split(end);
|
|
873
|
-
let chunk = this.byStart[start];
|
|
874
|
-
while (chunk) {
|
|
875
|
-
chunk.reset();
|
|
876
|
-
chunk = end > chunk.end ? this.byStart[chunk.end] : null;
|
|
877
|
-
}
|
|
878
|
-
return this;
|
|
879
|
-
}
|
|
880
|
-
lastChar() {
|
|
881
|
-
if (this.outro.length) return this.outro[this.outro.length - 1];
|
|
882
|
-
let chunk = this.lastChunk;
|
|
883
|
-
do {
|
|
884
|
-
if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];
|
|
885
|
-
if (chunk.content.length) return chunk.content[chunk.content.length - 1];
|
|
886
|
-
if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];
|
|
887
|
-
} while (chunk = chunk.previous);
|
|
888
|
-
if (this.intro.length) return this.intro[this.intro.length - 1];
|
|
889
|
-
return "";
|
|
890
|
-
}
|
|
891
|
-
lastLine() {
|
|
892
|
-
let lineIndex = this.outro.lastIndexOf(n);
|
|
893
|
-
if (lineIndex !== -1) return this.outro.substr(lineIndex + 1);
|
|
894
|
-
let lineStr = this.outro;
|
|
895
|
-
let chunk = this.lastChunk;
|
|
896
|
-
do {
|
|
897
|
-
if (chunk.outro.length > 0) {
|
|
898
|
-
lineIndex = chunk.outro.lastIndexOf(n);
|
|
899
|
-
if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;
|
|
900
|
-
lineStr = chunk.outro + lineStr;
|
|
901
|
-
}
|
|
902
|
-
if (chunk.content.length > 0) {
|
|
903
|
-
lineIndex = chunk.content.lastIndexOf(n);
|
|
904
|
-
if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;
|
|
905
|
-
lineStr = chunk.content + lineStr;
|
|
906
|
-
}
|
|
907
|
-
if (chunk.intro.length > 0) {
|
|
908
|
-
lineIndex = chunk.intro.lastIndexOf(n);
|
|
909
|
-
if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;
|
|
910
|
-
lineStr = chunk.intro + lineStr;
|
|
911
|
-
}
|
|
912
|
-
} while (chunk = chunk.previous);
|
|
913
|
-
lineIndex = this.intro.lastIndexOf(n);
|
|
914
|
-
if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;
|
|
915
|
-
return this.intro + lineStr;
|
|
916
|
-
}
|
|
917
|
-
slice(start = 0, end = this.original.length - this.offset) {
|
|
918
|
-
start = start + this.offset;
|
|
919
|
-
end = end + this.offset;
|
|
920
|
-
if (this.original.length !== 0) {
|
|
921
|
-
while (start < 0) start += this.original.length;
|
|
922
|
-
while (end < 0) end += this.original.length;
|
|
923
|
-
}
|
|
924
|
-
let result = "";
|
|
925
|
-
let chunk = this.firstChunk;
|
|
926
|
-
while (chunk && (chunk.start > start || chunk.end <= start)) {
|
|
927
|
-
if (chunk.start < end && chunk.end >= end) {
|
|
928
|
-
return result;
|
|
929
|
-
}
|
|
930
|
-
chunk = chunk.next;
|
|
931
|
-
}
|
|
932
|
-
if (chunk && chunk.edited && chunk.start !== start)
|
|
933
|
-
throw new Error(`Cannot use replaced character ${start} as slice start anchor.`);
|
|
934
|
-
const startChunk = chunk;
|
|
935
|
-
while (chunk) {
|
|
936
|
-
if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
|
|
937
|
-
result += chunk.intro;
|
|
938
|
-
}
|
|
939
|
-
const containsEnd = chunk.start < end && chunk.end >= end;
|
|
940
|
-
if (containsEnd && chunk.edited && chunk.end !== end)
|
|
941
|
-
throw new Error(`Cannot use replaced character ${end} as slice end anchor.`);
|
|
942
|
-
const sliceStart = startChunk === chunk ? start - chunk.start : 0;
|
|
943
|
-
const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
|
|
944
|
-
result += chunk.content.slice(sliceStart, sliceEnd);
|
|
945
|
-
if (chunk.outro && (!containsEnd || chunk.end === end)) {
|
|
946
|
-
result += chunk.outro;
|
|
947
|
-
}
|
|
948
|
-
if (containsEnd) {
|
|
949
|
-
break;
|
|
950
|
-
}
|
|
951
|
-
chunk = chunk.next;
|
|
952
|
-
}
|
|
953
|
-
return result;
|
|
954
|
-
}
|
|
955
|
-
// TODO deprecate this? not really very useful
|
|
956
|
-
snip(start, end) {
|
|
957
|
-
const clone = this.clone();
|
|
958
|
-
clone.remove(0, start);
|
|
959
|
-
clone.remove(end, clone.original.length);
|
|
960
|
-
return clone;
|
|
961
|
-
}
|
|
962
|
-
_split(index) {
|
|
963
|
-
if (this.byStart[index] || this.byEnd[index]) return;
|
|
964
|
-
let chunk = this.lastSearchedChunk;
|
|
965
|
-
const searchForward = index > chunk.end;
|
|
966
|
-
while (chunk) {
|
|
967
|
-
if (chunk.contains(index)) return this._splitChunk(chunk, index);
|
|
968
|
-
chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
_splitChunk(chunk, index) {
|
|
972
|
-
if (chunk.edited && chunk.content.length) {
|
|
973
|
-
const loc = getLocator(this.original)(index);
|
|
974
|
-
throw new Error(
|
|
975
|
-
`Cannot split a chunk that has already been edited (${loc.line}:${loc.column} \u2013 "${chunk.original}")`
|
|
236
|
+
return trimmed.replace(
|
|
237
|
+
/meta\s*:\s*\{/,
|
|
238
|
+
`meta: {
|
|
239
|
+
description: \`${description}\`,`
|
|
976
240
|
);
|
|
977
241
|
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
}
|
|
993
|
-
return str + this.outro;
|
|
994
|
-
}
|
|
995
|
-
isEmpty() {
|
|
996
|
-
let chunk = this.firstChunk;
|
|
997
|
-
do {
|
|
998
|
-
if (chunk.intro.length && chunk.intro.trim() || chunk.content.length && chunk.content.trim() || chunk.outro.length && chunk.outro.trim())
|
|
999
|
-
return false;
|
|
1000
|
-
} while (chunk = chunk.next);
|
|
1001
|
-
return true;
|
|
1002
|
-
}
|
|
1003
|
-
length() {
|
|
1004
|
-
let chunk = this.firstChunk;
|
|
1005
|
-
let length = 0;
|
|
1006
|
-
do {
|
|
1007
|
-
length += chunk.intro.length + chunk.content.length + chunk.outro.length;
|
|
1008
|
-
} while (chunk = chunk.next);
|
|
1009
|
-
return length;
|
|
1010
|
-
}
|
|
1011
|
-
trimLines() {
|
|
1012
|
-
return this.trim("[\\r\\n]");
|
|
1013
|
-
}
|
|
1014
|
-
trim(charType) {
|
|
1015
|
-
return this.trimStart(charType).trimEnd(charType);
|
|
1016
|
-
}
|
|
1017
|
-
trimEndAborted(charType) {
|
|
1018
|
-
const rx = new RegExp((charType || "\\s") + "+$");
|
|
1019
|
-
this.outro = this.outro.replace(rx, "");
|
|
1020
|
-
if (this.outro.length) return true;
|
|
1021
|
-
let chunk = this.lastChunk;
|
|
1022
|
-
do {
|
|
1023
|
-
const end = chunk.end;
|
|
1024
|
-
const aborted = chunk.trimEnd(rx);
|
|
1025
|
-
if (chunk.end !== end) {
|
|
1026
|
-
if (this.lastChunk === chunk) {
|
|
1027
|
-
this.lastChunk = chunk.next;
|
|
1028
|
-
}
|
|
1029
|
-
this.byEnd[chunk.end] = chunk;
|
|
1030
|
-
this.byStart[chunk.next.start] = chunk.next;
|
|
1031
|
-
this.byEnd[chunk.next.end] = chunk.next;
|
|
1032
|
-
}
|
|
1033
|
-
if (aborted) return true;
|
|
1034
|
-
chunk = chunk.previous;
|
|
1035
|
-
} while (chunk);
|
|
1036
|
-
return false;
|
|
1037
|
-
}
|
|
1038
|
-
trimEnd(charType) {
|
|
1039
|
-
this.trimEndAborted(charType);
|
|
1040
|
-
return this;
|
|
242
|
+
} else {
|
|
243
|
+
const lastBraceIndex = trimmed.lastIndexOf("}");
|
|
244
|
+
if (lastBraceIndex === -1) {
|
|
245
|
+
return trimmed;
|
|
246
|
+
}
|
|
247
|
+
const beforeBrace = trimmed.substring(0, lastBraceIndex);
|
|
248
|
+
const afterBrace = trimmed.substring(lastBraceIndex);
|
|
249
|
+
const needsComma = beforeBrace.trim().length > 1 && !beforeBrace.trim().endsWith(",");
|
|
250
|
+
const comma = needsComma ? "," : "";
|
|
251
|
+
return `${beforeBrace}${comma}
|
|
252
|
+
meta: {
|
|
253
|
+
description: \`${description}\`,
|
|
254
|
+
},
|
|
255
|
+
${afterBrace}`;
|
|
1041
256
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
let chunk = this.firstChunk;
|
|
1047
|
-
do {
|
|
1048
|
-
const end = chunk.end;
|
|
1049
|
-
const aborted = chunk.trimStart(rx);
|
|
1050
|
-
if (chunk.end !== end) {
|
|
1051
|
-
if (chunk === this.lastChunk) this.lastChunk = chunk.next;
|
|
1052
|
-
this.byEnd[chunk.end] = chunk;
|
|
1053
|
-
this.byStart[chunk.next.start] = chunk.next;
|
|
1054
|
-
this.byEnd[chunk.next.end] = chunk.next;
|
|
1055
|
-
}
|
|
1056
|
-
if (aborted) return true;
|
|
1057
|
-
chunk = chunk.next;
|
|
1058
|
-
} while (chunk);
|
|
257
|
+
}
|
|
258
|
+
function isStructuredValue(value, expectedField) {
|
|
259
|
+
const trimmed = value.trim();
|
|
260
|
+
if (!trimmed.startsWith("{")) {
|
|
1059
261
|
return false;
|
|
1060
262
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => {
|
|
1072
|
-
if (i === "$") return "$";
|
|
1073
|
-
if (i === "&") return match[0];
|
|
1074
|
-
const num = +i;
|
|
1075
|
-
if (num < match.length) return match[+i];
|
|
1076
|
-
return `$${i}`;
|
|
1077
|
-
});
|
|
1078
|
-
} else {
|
|
1079
|
-
return replacement(...match, match.index, str, match.groups);
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
function matchAll(re, str) {
|
|
1083
|
-
let match;
|
|
1084
|
-
const matches = [];
|
|
1085
|
-
while (match = re.exec(str)) {
|
|
1086
|
-
matches.push(match);
|
|
1087
|
-
}
|
|
1088
|
-
return matches;
|
|
1089
|
-
}
|
|
1090
|
-
if (searchValue.global) {
|
|
1091
|
-
const matches = matchAll(searchValue, this.original);
|
|
1092
|
-
matches.forEach((match) => {
|
|
1093
|
-
if (match.index != null) {
|
|
1094
|
-
const replacement2 = getReplacement(match, this.original);
|
|
1095
|
-
if (replacement2 !== match[0]) {
|
|
1096
|
-
this.overwrite(match.index, match.index + match[0].length, replacement2);
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
});
|
|
1100
|
-
} else {
|
|
1101
|
-
const match = this.original.match(searchValue);
|
|
1102
|
-
if (match && match.index != null) {
|
|
1103
|
-
const replacement2 = getReplacement(match, this.original);
|
|
1104
|
-
if (replacement2 !== match[0]) {
|
|
1105
|
-
this.overwrite(match.index, match.index + match[0].length, replacement2);
|
|
1106
|
-
}
|
|
263
|
+
const fieldPattern = new RegExp(`^\\s*{[^}]*\\b${expectedField}\\s*:`, "s");
|
|
264
|
+
return fieldPattern.test(trimmed);
|
|
265
|
+
}
|
|
266
|
+
function getMarkerFunctionName(parentStack) {
|
|
267
|
+
for (let i = parentStack.length - 1; i >= 0; i--) {
|
|
268
|
+
const node = parentStack[i];
|
|
269
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier") {
|
|
270
|
+
const functionName = node.callee.name;
|
|
271
|
+
if (functionName.startsWith("$") && ["$args", "$inputs", "$outputs", "$secrets"].includes(functionName)) {
|
|
272
|
+
return functionName.substring(1);
|
|
1107
273
|
}
|
|
1108
274
|
}
|
|
1109
|
-
return this;
|
|
1110
275
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
}
|
|
1119
|
-
replace(searchValue, replacement) {
|
|
1120
|
-
if (typeof searchValue === "string") {
|
|
1121
|
-
return this._replaceString(searchValue, replacement);
|
|
1122
|
-
}
|
|
1123
|
-
return this._replaceRegexp(searchValue, replacement);
|
|
1124
|
-
}
|
|
1125
|
-
_replaceAllString(string, replacement) {
|
|
1126
|
-
const { original } = this;
|
|
1127
|
-
const stringLength = string.length;
|
|
1128
|
-
for (let index = original.indexOf(string); index !== -1; index = original.indexOf(string, index + stringLength)) {
|
|
1129
|
-
const previous = original.slice(index, index + stringLength);
|
|
1130
|
-
if (previous !== replacement) this.overwrite(index, index + stringLength, replacement);
|
|
1131
|
-
}
|
|
1132
|
-
return this;
|
|
1133
|
-
}
|
|
1134
|
-
replaceAll(searchValue, replacement) {
|
|
1135
|
-
if (typeof searchValue === "string") {
|
|
1136
|
-
return this._replaceAllString(searchValue, replacement);
|
|
1137
|
-
}
|
|
1138
|
-
if (!searchValue.global) {
|
|
1139
|
-
throw new TypeError(
|
|
1140
|
-
"MagicString.prototype.replaceAll called with a non-global RegExp argument"
|
|
1141
|
-
);
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
function getParentObjectKey(parentStack) {
|
|
279
|
+
for (let i = parentStack.length - 2; i >= 0; i--) {
|
|
280
|
+
const node = parentStack[i];
|
|
281
|
+
if (node.type === "Property" && node.key.type === "Identifier") {
|
|
282
|
+
return node.key.name;
|
|
1142
283
|
}
|
|
1143
|
-
return this._replaceRegexp(searchValue, replacement);
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
|
|
1147
|
-
// src/shared/schema-transformer.ts
|
|
1148
|
-
var schemaTransformerPlugin = {
|
|
1149
|
-
name: "schema-transformer",
|
|
1150
|
-
setup(build2) {
|
|
1151
|
-
build2.onLoad({ filter: /src\/.*\.ts$/ }, async (args) => {
|
|
1152
|
-
const content = await readFile(args.path, "utf-8");
|
|
1153
|
-
return {
|
|
1154
|
-
contents: await applySchemaTransformations(content),
|
|
1155
|
-
loader: "ts"
|
|
1156
|
-
};
|
|
1157
|
-
});
|
|
1158
284
|
}
|
|
1159
|
-
|
|
1160
|
-
async function applySchemaTransformations(content) {
|
|
1161
|
-
const magicString = new MagicString(content);
|
|
1162
|
-
const { program, comments } = await parseAsync("file.ts", content);
|
|
1163
|
-
walk(program, {
|
|
1164
|
-
enter(node) {
|
|
1165
|
-
if (node.type !== "Property" || node.key.type !== "Identifier") {
|
|
1166
|
-
return;
|
|
1167
|
-
}
|
|
1168
|
-
const jsdoc = comments.find((comment) => isLeadingComment(content, node, comment));
|
|
1169
|
-
if (!jsdoc || !jsdoc.value.includes("@schema")) {
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
magicString.update(
|
|
1173
|
-
node.value.start,
|
|
1174
|
-
node.value.end,
|
|
1175
|
-
`{
|
|
1176
|
-
...${content.substring(node.value.start, node.value.end)},
|
|
1177
|
-
description: \`${cleanJsdoc(jsdoc.value)}\`,
|
|
1178
|
-
}`
|
|
1179
|
-
);
|
|
1180
|
-
}
|
|
1181
|
-
});
|
|
1182
|
-
return magicString.toString();
|
|
285
|
+
return null;
|
|
1183
286
|
}
|
|
1184
287
|
function isLeadingComment(content, node, comment) {
|
|
1185
288
|
if (comment.end > node.start) {
|
|
@@ -1189,16 +292,67 @@ function isLeadingComment(content, node, comment) {
|
|
|
1189
292
|
return contentRange.trim().length === 0;
|
|
1190
293
|
}
|
|
1191
294
|
function cleanJsdoc(str) {
|
|
1192
|
-
return str.replace(/^\s*\*/gm, "").replace(
|
|
295
|
+
return str.replace(/^\s*\*/gm, "").replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\${/g, "\\${").trim();
|
|
296
|
+
}
|
|
297
|
+
function isInsideZodObject(parentStack) {
|
|
298
|
+
for (let i = parentStack.length - 1; i >= 0; i--) {
|
|
299
|
+
const node = parentStack[i];
|
|
300
|
+
if (node.type === "CallExpression" && node.callee.type === "MemberExpression" && isZodObjectCall(node.callee)) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
function isZodObjectCall(memberExpression) {
|
|
307
|
+
if (memberExpression.type !== "MemberExpression") {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
if (memberExpression.object.type === "Identifier" && memberExpression.object.name === "z" && memberExpression.property.type === "Identifier" && memberExpression.property.name === "object") {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
if (memberExpression.property.type === "Identifier" && memberExpression.property.name === "object" && memberExpression.object.type === "CallExpression" && memberExpression.object.callee.type === "MemberExpression") {
|
|
314
|
+
return startsWithZodCall(memberExpression.object);
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
function startsWithZodCall(callExpression) {
|
|
319
|
+
if (!callExpression || callExpression.type !== "CallExpression") {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
if (callExpression.callee.type === "MemberExpression") {
|
|
323
|
+
if (callExpression.callee.object.type === "Identifier" && callExpression.callee.object.name === "z") {
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
if (callExpression.callee.object.type === "CallExpression") {
|
|
327
|
+
return startsWithZodCall(callExpression.callee.object);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return false;
|
|
1193
331
|
}
|
|
332
|
+
var sourceHashConfigSchema = z.discriminatedUnion("mode", [
|
|
333
|
+
z.object({
|
|
334
|
+
mode: z.literal("manual"),
|
|
335
|
+
version: z.string()
|
|
336
|
+
}),
|
|
337
|
+
z.object({
|
|
338
|
+
mode: z.literal("auto")
|
|
339
|
+
}),
|
|
340
|
+
z.object({
|
|
341
|
+
mode: z.literal("version")
|
|
342
|
+
}),
|
|
343
|
+
z.object({
|
|
344
|
+
mode: z.literal("none")
|
|
345
|
+
})
|
|
346
|
+
]);
|
|
347
|
+
var highstateConfigSchema = z.object({
|
|
348
|
+
type: z.enum(["source", "library", "worker"]).default("source"),
|
|
349
|
+
sourceHash: z.union([sourceHashConfigSchema, z.record(z.string(), sourceHashConfigSchema)]).optional()
|
|
350
|
+
});
|
|
351
|
+
var highstateManifestSchema = z.object({
|
|
352
|
+
sourceHashes: z.record(z.string(), z.number()).optional()
|
|
353
|
+
});
|
|
1194
354
|
|
|
1195
355
|
// src/shared/source-hash-calculator.ts
|
|
1196
|
-
import { dirname, relative, resolve } from "node:path";
|
|
1197
|
-
import { readFile as readFile2, writeFile } from "node:fs/promises";
|
|
1198
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
1199
|
-
import { readPackageJSON, resolvePackageJSON } from "pkg-types";
|
|
1200
|
-
import { sha256 } from "crypto-hash";
|
|
1201
|
-
import { resolve as importMetaResolve } from "import-meta-resolve";
|
|
1202
356
|
var SourceHashCalculator = class {
|
|
1203
357
|
constructor(packageJsonPath, packageJson, logger2) {
|
|
1204
358
|
this.packageJsonPath = packageJsonPath;
|
|
@@ -1207,16 +361,93 @@ var SourceHashCalculator = class {
|
|
|
1207
361
|
}
|
|
1208
362
|
dependencyHashes = /* @__PURE__ */ new Map();
|
|
1209
363
|
fileHashes = /* @__PURE__ */ new Map();
|
|
1210
|
-
|
|
364
|
+
/**
|
|
365
|
+
* Calculates CRC32 hash of a string.
|
|
366
|
+
*/
|
|
367
|
+
hashString(input) {
|
|
368
|
+
return crc32(Buffer.from(input));
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Gets the highstate configuration from package.json with defaults.
|
|
372
|
+
*/
|
|
373
|
+
getHighstateConfig(packageJson) {
|
|
374
|
+
const rawConfig = packageJson.highstate;
|
|
375
|
+
if (!rawConfig) {
|
|
376
|
+
return { type: "source" };
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
return highstateConfigSchema.parse(rawConfig);
|
|
380
|
+
} catch (error) {
|
|
381
|
+
this.logger.warn(
|
|
382
|
+
{ error, packageName: packageJson.name },
|
|
383
|
+
"invalid highstate configuration, using defaults"
|
|
384
|
+
);
|
|
385
|
+
return { type: "source" };
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Gets the effective source hash configuration with defaults for a specific output.
|
|
390
|
+
*/
|
|
391
|
+
getSourceHashConfig(highstateConfig, exportKey) {
|
|
392
|
+
if (highstateConfig.sourceHash) {
|
|
393
|
+
const singleConfigResult = sourceHashConfigSchema.safeParse(highstateConfig.sourceHash);
|
|
394
|
+
if (singleConfigResult.success) {
|
|
395
|
+
return singleConfigResult.data;
|
|
396
|
+
}
|
|
397
|
+
const recordConfigResult = z.record(z.string(), sourceHashConfigSchema).safeParse(highstateConfig.sourceHash);
|
|
398
|
+
if (recordConfigResult.success && exportKey) {
|
|
399
|
+
const perOutputConfig = recordConfigResult.data[exportKey];
|
|
400
|
+
if (perOutputConfig) {
|
|
401
|
+
return perOutputConfig;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (highstateConfig.type === "library") {
|
|
406
|
+
return { mode: "none" };
|
|
407
|
+
}
|
|
408
|
+
return { mode: "auto" };
|
|
409
|
+
}
|
|
410
|
+
async writeHighstateManifest(distBasePath, distPathToExportKey) {
|
|
411
|
+
const highstateConfig = this.getHighstateConfig(this.packageJson);
|
|
1211
412
|
const promises = [];
|
|
1212
|
-
for (const distPath of
|
|
413
|
+
for (const [distPath, exportKey] of distPathToExportKey) {
|
|
1213
414
|
const fullPath = resolve(distPath);
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
415
|
+
const sourceHashConfig = this.getSourceHashConfig(highstateConfig, exportKey);
|
|
416
|
+
switch (sourceHashConfig.mode) {
|
|
417
|
+
case "manual":
|
|
418
|
+
promises.push(
|
|
419
|
+
Promise.resolve({
|
|
420
|
+
distPath,
|
|
421
|
+
hash: this.hashString(sourceHashConfig.version)
|
|
422
|
+
})
|
|
423
|
+
);
|
|
424
|
+
break;
|
|
425
|
+
case "version":
|
|
426
|
+
promises.push(
|
|
427
|
+
Promise.resolve({
|
|
428
|
+
distPath,
|
|
429
|
+
hash: this.hashString(this.packageJson.version ?? "")
|
|
430
|
+
})
|
|
431
|
+
);
|
|
432
|
+
break;
|
|
433
|
+
case "none":
|
|
434
|
+
promises.push(
|
|
435
|
+
Promise.resolve({
|
|
436
|
+
distPath,
|
|
437
|
+
hash: 0
|
|
438
|
+
})
|
|
439
|
+
);
|
|
440
|
+
break;
|
|
441
|
+
case "auto":
|
|
442
|
+
default:
|
|
443
|
+
promises.push(
|
|
444
|
+
this.getFileHash(fullPath).then((hash) => ({
|
|
445
|
+
distPath,
|
|
446
|
+
hash
|
|
447
|
+
}))
|
|
448
|
+
);
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
1220
451
|
}
|
|
1221
452
|
const manifest = {
|
|
1222
453
|
sourceHashes: {}
|
|
@@ -1238,13 +469,13 @@ var SourceHashCalculator = class {
|
|
|
1238
469
|
return hash;
|
|
1239
470
|
}
|
|
1240
471
|
async calculateFileHash(fullPath) {
|
|
1241
|
-
const content = await
|
|
472
|
+
const content = await readFile(fullPath, "utf8");
|
|
1242
473
|
const fileDeps = this.parseDependencies(fullPath, content);
|
|
1243
474
|
const hashes = await Promise.all([
|
|
1244
|
-
|
|
475
|
+
this.hashString(content),
|
|
1245
476
|
...fileDeps.map((dep) => this.getDependencyHash(dep))
|
|
1246
477
|
]);
|
|
1247
|
-
return
|
|
478
|
+
return crc32(Buffer.concat(hashes.map(int32ToBytes)));
|
|
1248
479
|
}
|
|
1249
480
|
getDependencyHash(dependency) {
|
|
1250
481
|
const existingHash = this.dependencyHashes.get(dependency.id);
|
|
@@ -1264,7 +495,7 @@ var SourceHashCalculator = class {
|
|
|
1264
495
|
let resolvedUrl;
|
|
1265
496
|
try {
|
|
1266
497
|
const baseUrl = pathToFileURL(dirname(this.packageJsonPath));
|
|
1267
|
-
resolvedUrl =
|
|
498
|
+
resolvedUrl = resolve$1(dependency.package, baseUrl.toString());
|
|
1268
499
|
} catch (error) {
|
|
1269
500
|
this.logger.error(`failed to resolve package "%s"`, dependency.package);
|
|
1270
501
|
throw error;
|
|
@@ -1292,8 +523,8 @@ var SourceHashCalculator = class {
|
|
|
1292
523
|
);
|
|
1293
524
|
let manifest;
|
|
1294
525
|
try {
|
|
1295
|
-
const manifestContent = await
|
|
1296
|
-
manifest = JSON.parse(manifestContent);
|
|
526
|
+
const manifestContent = await readFile(highstateManifestPath, "utf8");
|
|
527
|
+
manifest = highstateManifestSchema.parse(JSON.parse(manifestContent));
|
|
1297
528
|
} catch (error) {
|
|
1298
529
|
this.logger.debug(
|
|
1299
530
|
{ error },
|
|
@@ -1307,7 +538,7 @@ var SourceHashCalculator = class {
|
|
|
1307
538
|
return sourceHash;
|
|
1308
539
|
}
|
|
1309
540
|
this.logger.debug(`using package version as a fallback hash for "%s"`, packageName);
|
|
1310
|
-
return depPackageJson.version ?? "0.0.0";
|
|
541
|
+
return this.hashString(depPackageJson.version ?? "0.0.0");
|
|
1311
542
|
}
|
|
1312
543
|
}
|
|
1313
544
|
}
|
|
@@ -1340,15 +571,11 @@ var SourceHashCalculator = class {
|
|
|
1340
571
|
id: `npm:${npmPackage}`,
|
|
1341
572
|
package: npmPackage
|
|
1342
573
|
});
|
|
1343
|
-
} else
|
|
1344
|
-
}
|
|
574
|
+
} else ;
|
|
1345
575
|
}
|
|
1346
576
|
return dependencies;
|
|
1347
577
|
}
|
|
1348
578
|
};
|
|
1349
|
-
|
|
1350
|
-
// src/shared/bin-transformer.ts
|
|
1351
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
1352
579
|
function createBinTransformerPlugin(sourceFilePaths) {
|
|
1353
580
|
const filter = new RegExp(`(${sourceFilePaths.join("|")})$`);
|
|
1354
581
|
logger.debug("created bin transformer plugin with filter: %s", filter);
|
|
@@ -1356,7 +583,7 @@ function createBinTransformerPlugin(sourceFilePaths) {
|
|
|
1356
583
|
name: "bin-transformer",
|
|
1357
584
|
setup(build2) {
|
|
1358
585
|
build2.onLoad({ filter }, async (args) => {
|
|
1359
|
-
const content = await
|
|
586
|
+
const content = await readFile(args.path, "utf-8");
|
|
1360
587
|
return {
|
|
1361
588
|
contents: `#!/usr/bin/env node
|
|
1362
589
|
|
|
@@ -1376,7 +603,7 @@ var DesignerCommand = class extends Command {
|
|
|
1376
603
|
description: "Starts the Highstate designer in the current project."
|
|
1377
604
|
});
|
|
1378
605
|
async execute() {
|
|
1379
|
-
const packageJson = await
|
|
606
|
+
const packageJson = await readPackageJSON();
|
|
1380
607
|
if (!packageJson.devDependencies?.["@highstate/cli"]) {
|
|
1381
608
|
throw new UsageError(
|
|
1382
609
|
"This project is not a Highstate project.\n@highstate/cli must be installed as a devDependency."
|
|
@@ -1392,17 +619,17 @@ var DesignerCommand = class extends Command {
|
|
|
1392
619
|
const port = await getPort();
|
|
1393
620
|
process.env.NITRO_PORT = port.toString();
|
|
1394
621
|
process.env.NITRO_HOST = "0.0.0.0";
|
|
1395
|
-
await new Promise((
|
|
622
|
+
await new Promise((resolve3) => {
|
|
1396
623
|
console.log = (message) => {
|
|
1397
624
|
if (message.startsWith("Listening on")) {
|
|
1398
|
-
|
|
625
|
+
resolve3();
|
|
1399
626
|
}
|
|
1400
627
|
};
|
|
1401
628
|
const path = "@highstate/designer/.output/server/index.mjs";
|
|
1402
629
|
void import(path);
|
|
1403
630
|
});
|
|
1404
631
|
console.log = oldConsoleLog;
|
|
1405
|
-
|
|
632
|
+
consola.log(
|
|
1406
633
|
[
|
|
1407
634
|
"\n ",
|
|
1408
635
|
colorize("bold", colorize("cyanBright", "Highstate Designer")),
|
|
@@ -1414,28 +641,30 @@ var DesignerCommand = class extends Command {
|
|
|
1414
641
|
);
|
|
1415
642
|
process.on("SIGINT", () => {
|
|
1416
643
|
process.stdout.write("\r");
|
|
1417
|
-
|
|
644
|
+
consola.info("shutting down highstate designer...");
|
|
1418
645
|
setTimeout(() => process.exit(0), 1e3);
|
|
1419
646
|
});
|
|
1420
647
|
}
|
|
1421
648
|
};
|
|
1422
|
-
|
|
1423
|
-
// src/commands/build.ts
|
|
1424
|
-
import { Command as Command2, Option } from "clipanion";
|
|
1425
|
-
import { readPackageJSON as readPackageJSON3, resolvePackageJSON as resolvePackageJSON2 } from "pkg-types";
|
|
1426
|
-
import { mapKeys, mapValues, pipe } from "remeda";
|
|
1427
|
-
import { build } from "tsup";
|
|
1428
|
-
var BuildCommand = class extends Command2 {
|
|
649
|
+
var BuildCommand = class extends Command {
|
|
1429
650
|
static paths = [["build"]];
|
|
1430
|
-
static usage =
|
|
651
|
+
static usage = Command.Usage({
|
|
1431
652
|
category: "Builder",
|
|
1432
653
|
description: "Builds the Highstate library or unit package."
|
|
1433
654
|
});
|
|
1434
655
|
watch = Option.Boolean("--watch", false);
|
|
1435
656
|
library = Option.Boolean("--library", false);
|
|
1436
657
|
silent = Option.Boolean("--silent", true);
|
|
658
|
+
noSourceHash = Option.Boolean("--no-source-hash", false);
|
|
1437
659
|
async execute() {
|
|
1438
|
-
const packageJson = await
|
|
660
|
+
const packageJson = await readPackageJSON();
|
|
661
|
+
const highstateConfig = highstateConfigSchema.parse(packageJson.highstate ?? {});
|
|
662
|
+
if (highstateConfig.type === "library") {
|
|
663
|
+
this.library = true;
|
|
664
|
+
}
|
|
665
|
+
if (highstateConfig.type === "worker") {
|
|
666
|
+
this.noSourceHash = true;
|
|
667
|
+
}
|
|
1439
668
|
const exports = packageJson.exports;
|
|
1440
669
|
let bin = packageJson.bin;
|
|
1441
670
|
if (!packageJson.name) {
|
|
@@ -1486,7 +715,8 @@ var BuildCommand = class extends Command2 {
|
|
|
1486
715
|
entryPoint: `./src/${targetName}.ts`,
|
|
1487
716
|
targetName,
|
|
1488
717
|
distPath,
|
|
1489
|
-
isBin
|
|
718
|
+
isBin,
|
|
719
|
+
key
|
|
1490
720
|
};
|
|
1491
721
|
}),
|
|
1492
722
|
mapKeys((_, value) => value.targetName)
|
|
@@ -1506,22 +736,52 @@ var BuildCommand = class extends Command2 {
|
|
|
1506
736
|
sourcemap: true,
|
|
1507
737
|
clean: true,
|
|
1508
738
|
format: "esm",
|
|
1509
|
-
target: "
|
|
739
|
+
target: "es2024",
|
|
740
|
+
platform: "node",
|
|
1510
741
|
external: ["@pulumi/pulumi"],
|
|
1511
742
|
esbuildPlugins,
|
|
743
|
+
treeshake: true,
|
|
744
|
+
removeNodeProtocol: false,
|
|
1512
745
|
silent: this.silent || ["warn", "error", "fatal"].includes(logger.level)
|
|
1513
746
|
});
|
|
1514
|
-
const packageJsonPath = await
|
|
1515
|
-
const upToDatePackageJson = await
|
|
1516
|
-
if (!this.
|
|
747
|
+
const packageJsonPath = await resolvePackageJSON();
|
|
748
|
+
const upToDatePackageJson = await readPackageJSON();
|
|
749
|
+
if (!this.noSourceHash) {
|
|
1517
750
|
const sourceHashCalculator = new SourceHashCalculator(
|
|
1518
751
|
packageJsonPath,
|
|
1519
752
|
upToDatePackageJson,
|
|
1520
753
|
logger
|
|
1521
754
|
);
|
|
1522
|
-
const
|
|
1523
|
-
|
|
755
|
+
const distPathToExportKey = /* @__PURE__ */ new Map();
|
|
756
|
+
for (const value of Object.values(entry)) {
|
|
757
|
+
distPathToExportKey.set(value.distPath, value.key);
|
|
758
|
+
}
|
|
759
|
+
await sourceHashCalculator.writeHighstateManifest("./dist", distPathToExportKey);
|
|
760
|
+
}
|
|
761
|
+
if (this.library) {
|
|
762
|
+
const { loadLibrary } = await import('./library-loader-ZABUULFB.js');
|
|
763
|
+
const fullModulePaths = Object.values(entry).map((value) => resolve(value.distPath));
|
|
764
|
+
logger.info("evaluating library components from modules: %s", fullModulePaths.join(", "));
|
|
765
|
+
const library = await loadLibrary(logger, fullModulePaths);
|
|
766
|
+
const libraryPath = resolve("./dist", "highstate.library.msgpack");
|
|
767
|
+
await writeFile(libraryPath, encode(library), "utf8");
|
|
1524
768
|
}
|
|
769
|
+
logger.info("build completed successfully");
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
var BackendIdentityCommand = class extends Command {
|
|
773
|
+
static paths = [["backend", "identity"]];
|
|
774
|
+
static usage = Command.Usage({
|
|
775
|
+
category: "Backend",
|
|
776
|
+
description: "Ensures the backend identity is set up and returns the recipient."
|
|
777
|
+
});
|
|
778
|
+
async execute() {
|
|
779
|
+
const backendLogger = logger.child({}, { msgPrefix: "[backend] " });
|
|
780
|
+
const { getOrCreateBackendIdentity } = await import('@highstate/backend');
|
|
781
|
+
const backendIdentity = await getOrCreateBackendIdentity(backendLogger);
|
|
782
|
+
const recipient = await identityToRecipient(backendIdentity);
|
|
783
|
+
logger.info(`stored backend identity is: ${recipient}`);
|
|
784
|
+
logger.info(`run "highstate backend unlock-method add ${recipient}" on other authorized device`);
|
|
1525
785
|
}
|
|
1526
786
|
};
|
|
1527
787
|
|
|
@@ -1533,7 +793,9 @@ var cli = new Cli({
|
|
|
1533
793
|
});
|
|
1534
794
|
cli.register(BuildCommand);
|
|
1535
795
|
cli.register(DesignerCommand);
|
|
796
|
+
cli.register(BackendIdentityCommand);
|
|
1536
797
|
cli.register(Builtins.HelpCommand);
|
|
1537
798
|
cli.register(Builtins.VersionCommand);
|
|
1538
799
|
await cli.runExit(process.argv.slice(2));
|
|
800
|
+
//# sourceMappingURL=main.js.map
|
|
1539
801
|
//# sourceMappingURL=main.js.map
|