@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/main.js CHANGED
@@ -1,23 +1,29 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/main.ts
4
- import { Builtins, Cli } from "clipanion";
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.14";
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("@highstate/backend").then(({ getSharedServices }) => {
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
- // src/shared/schema-transformer.ts
79
- import { readFile } from "node:fs/promises";
80
- import { parseAsync } from "oxc-parser";
81
- import { walk } from "oxc-walker";
82
-
83
- // ../../node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
84
- var comma = ",".charCodeAt(0);
85
- var semicolon = ";".charCodeAt(0);
86
- var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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
- var Chunk = class _Chunk {
184
- constructor(start, end, content) {
185
- this.start = start;
186
- this.end = end;
187
- this.original = content;
188
- this.intro = "";
189
- this.outro = "";
190
- this.content = content;
191
- this.storeName = false;
192
- this.edited = false;
193
- {
194
- this.previous = null;
195
- this.next = null;
196
- }
197
- }
198
- appendLeft(content) {
199
- this.outro += content;
200
- }
201
- appendRight(content) {
202
- this.intro = this.intro + content;
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
- this.edit("", void 0, true);
117
+ return;
308
118
  }
309
- return true;
310
- } else {
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
- const line = i - 1;
404
- const column = index - lineOffsets[line];
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 segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
436
- if (nameIndex >= 0) {
437
- segment.push(nameIndex);
126
+ const jsdoc = comments.find((comment) => isLeadingComment(content, node, comment));
127
+ if (!jsdoc) {
128
+ return;
438
129
  }
439
- this.rawSegments.push(segment);
440
- this.advance(content.slice(previousContentLineEnd + 1));
441
- } else if (this.pending) {
442
- this.rawSegments.push(this.pending);
443
- this.advance(content);
444
- }
445
- this.pending = null;
446
- }
447
- addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {
448
- let originalCharIndex = chunk.start;
449
- let first = true;
450
- let charInHiresBoundary = false;
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
- if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {
462
- const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
463
- if (this.hires === "boundary") {
464
- if (wordRegex.test(original[originalCharIndex])) {
465
- if (!charInHiresBoundary) {
466
- this.rawSegments.push(segment);
467
- charInHiresBoundary = true;
468
- }
469
- } else {
470
- this.rawSegments.push(segment);
471
- charInHiresBoundary = false;
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
- originalChunk = nextOriginalChunk;
574
- }
575
- cloned.lastChunk = clonedChunk;
576
- if (this.indentExclusionRanges) {
577
- cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
155
+ },
156
+ leave() {
157
+ parentStack.pop();
578
158
  }
579
- cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
580
- cloned.intro = this.intro;
581
- cloned.outro = this.outro;
582
- return cloned;
583
- }
584
- generateDecodedMap(options) {
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
- return {
609
- file: options.file ? options.file.split(/[/\\]/).pop() : void 0,
610
- sources: [
611
- options.source ? getRelativePath(options.file || "", options.source) : options.file || ""
612
- ],
613
- sourcesContent: options.includeContent ? [this.original] : void 0,
614
- names,
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
- let shouldIndentNextCharacter = options.indentStart !== false;
657
- const replacer = (match) => {
658
- if (shouldIndentNextCharacter) return `${indentStr}${match}`;
659
- shouldIndentNextCharacter = true;
660
- return match;
661
- };
662
- this.intro = this.intro.replace(pattern, replacer);
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
- warned.storeName = true;
779
- }
780
- options = { storeName: true };
781
- }
782
- const storeName = options !== void 0 ? options.storeName : false;
783
- const overwrite = options !== void 0 ? options.overwrite : false;
784
- if (storeName) {
785
- const original = this.original.slice(start, end);
786
- Object.defineProperty(this.storedNames, original, {
787
- writable: true,
788
- value: true,
789
- enumerable: true
790
- });
791
- }
792
- const first = this.byStart[start];
793
- const last = this.byEnd[end];
794
- if (first) {
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 this;
810
- }
811
- prepend(content) {
812
- if (typeof content !== "string") throw new TypeError("outro content must be a string");
813
- this.intro = content + this.intro;
814
- return this;
815
- }
816
- prependLeft(index, content) {
817
- index = index + this.offset;
818
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
819
- this._split(index);
820
- const chunk = this.byEnd[index];
821
- if (chunk) {
822
- chunk.prependLeft(content);
823
- } else {
824
- this.intro = content + this.intro;
825
- }
826
- return this;
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
- prependRight(index, content) {
829
- index = index + this.offset;
830
- if (typeof content !== "string") throw new TypeError("inserted content must be a string");
831
- this._split(index);
832
- const chunk = this.byStart[index];
833
- if (chunk) {
834
- chunk.prependRight(content);
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
- this.outro = content + this.outro;
837
- }
838
- return this;
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
- const newChunk = chunk.split(index);
979
- this.byEnd[index] = chunk;
980
- this.byStart[index] = newChunk;
981
- this.byEnd[newChunk.end] = newChunk;
982
- if (chunk === this.lastChunk) this.lastChunk = newChunk;
983
- this.lastSearchedChunk = chunk;
984
- return true;
985
- }
986
- toString() {
987
- let str = this.intro;
988
- let chunk = this.firstChunk;
989
- while (chunk) {
990
- str += chunk.toString();
991
- chunk = chunk.next;
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
- trimStartAborted(charType) {
1043
- const rx = new RegExp("^" + (charType || "\\s") + "+");
1044
- this.intro = this.intro.replace(rx, "");
1045
- if (this.intro.length) return true;
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
- trimStart(charType) {
1062
- this.trimStartAborted(charType);
1063
- return this;
1064
- }
1065
- hasChanged() {
1066
- return this.original !== this.toString();
1067
- }
1068
- _replaceRegexp(searchValue, replacement) {
1069
- function getReplacement(match, str) {
1070
- if (typeof replacement === "string") {
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
- _replaceString(string, replacement) {
1112
- const { original } = this;
1113
- const index = original.indexOf(string);
1114
- if (index !== -1) {
1115
- this.overwrite(index, index + string.length, replacement);
1116
- }
1117
- return this;
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("@schema", "").replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\${/g, "\\${").trim();
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
- async writeHighstateManifest(distBasePath, distPaths) {
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 distPaths) {
413
+ for (const [distPath, exportKey] of distPathToExportKey) {
1213
414
  const fullPath = resolve(distPath);
1214
- promises.push(
1215
- this.getFileHash(fullPath).then((hash) => ({
1216
- distPath,
1217
- hash
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 readFile2(fullPath, "utf8");
472
+ const content = await readFile(fullPath, "utf8");
1242
473
  const fileDeps = this.parseDependencies(fullPath, content);
1243
474
  const hashes = await Promise.all([
1244
- sha256(content),
475
+ this.hashString(content),
1245
476
  ...fileDeps.map((dep) => this.getDependencyHash(dep))
1246
477
  ]);
1247
- return await sha256(hashes.join(""));
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 = importMetaResolve(dependency.package, baseUrl.toString());
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 readFile2(highstateManifestPath, "utf8");
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 if (nodeBuiltin) {
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 readFile3(args.path, "utf-8");
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 readPackageJSON2();
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((resolve2) => {
622
+ await new Promise((resolve3) => {
1396
623
  console.log = (message) => {
1397
624
  if (message.startsWith("Listening on")) {
1398
- resolve2();
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
- consola2.log(
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
- consola2.info("shutting down highstate designer...");
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 = Command2.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 readPackageJSON3();
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: "esnext",
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 resolvePackageJSON2();
1515
- const upToDatePackageJson = await readPackageJSON3();
1516
- if (!this.library) {
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 distPaths = Object.values(entry).map((value) => value.distPath);
1523
- await sourceHashCalculator.writeHighstateManifest("./dist", distPaths);
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