@quonfig/cli 0.0.22 → 0.0.24

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.
@@ -298,8 +298,10 @@ export function storedConfigJsonSchema() {
298
298
  type: 'string',
299
299
  description: 'References a schema in schemas/ or schemas-protected/. The referenced file must exist.',
300
300
  },
301
- accessLevel: { type: 'string' },
302
- protection: { type: 'string' },
301
+ access: {
302
+ enum: ['support', 'standard', 'protected-env', 'protected-all-envs'],
303
+ description: 'Edit-access tier for this config. Defaults to "standard" when absent. See protecting-access.md.',
304
+ },
303
305
  tags: {
304
306
  type: 'array',
305
307
  items: { type: 'string' },
@@ -3,7 +3,7 @@ import * as path from 'node:path';
3
3
  import { removeQfFromGitignore, writeImportState } from './import-state.js';
4
4
  import { writeMigrationReport } from './migration-report.js';
5
5
  import { detectDuplicateKeys } from './sources/launch/translate.js';
6
- import { cloneAndStackPush } from '../util/clone-and-stack-push.js';
6
+ import { cloneAndStackPush, } from '../util/clone-and-stack-push.js';
7
7
  const writeQuonfigFiles = (dir, changes, source) => {
8
8
  const livePaths = new Map();
9
9
  for (const change of changes) {
@@ -59,8 +59,7 @@ const mergeEnvironmentsIntoQuonfigJson = (dir, sourceEnvs) => {
59
59
  }
60
60
  const existingEnvs = Array.isArray(existing.environments) ? existing.environments : [];
61
61
  const merged = [...new Set([...existingEnvs, ...sourceEnvs])].sort();
62
- if (existingEnvs.length === merged.length &&
63
- existingEnvs.every((e, i) => e === merged[i])) {
62
+ if (existingEnvs.length === merged.length && existingEnvs.every((e, i) => e === merged[i])) {
64
63
  return;
65
64
  }
66
65
  fs.writeFileSync(quonfigPath, JSON.stringify({ ...existing, environments: merged }, null, 2) + '\n', 'utf8');
@@ -80,9 +79,7 @@ export const pushMigrationToCloud = async (opts) => {
80
79
  droppedOverrides = opts.source.getDroppedOverrides?.() ?? null;
81
80
  skippedConfigs = opts.source.getSkippedConfigs?.() ?? null;
82
81
  duplicateResolutions =
83
- resolutionEntries.length > 0
84
- ? { entries: resolutionEntries, total: resolutionEntries.length }
85
- : null;
82
+ resolutionEntries.length > 0 ? { entries: resolutionEntries, total: resolutionEntries.length } : null;
86
83
  const reportData = {
87
84
  ...opts.reportData,
88
85
  ...(droppedOverrides ? { droppedOverrides } : {}),
@@ -2,27 +2,25 @@
2
2
  // Vendored verbatim from launch-migrator/src/zod-to-json-schema.ts to keep a
3
3
  // drop-in sync path. Do not reformat — edits here should be mirrored against
4
4
  // launch-migrator so the two converters stay behaviorally identical.
5
- import * as ts from "typescript";
6
- const JSON_SCHEMA_DRAFT_2020_12 = "https://json-schema.org/draft/2020-12/schema";
5
+ import * as ts from 'typescript';
6
+ const JSON_SCHEMA_DRAFT_2020_12 = 'https://json-schema.org/draft/2020-12/schema';
7
7
  function unwrapExpression(node) {
8
8
  let current = node;
9
- while (ts.isParenthesizedExpression(current) ||
10
- ts.isAsExpression(current) ||
11
- ts.isTypeAssertionExpression(current)) {
9
+ while (ts.isParenthesizedExpression(current) || ts.isAsExpression(current) || ts.isTypeAssertionExpression(current)) {
12
10
  current = current.expression;
13
11
  }
14
12
  return current;
15
13
  }
16
14
  function parseRegexLiteral(text) {
17
- if (!text.startsWith("/")) {
15
+ if (!text.startsWith('/')) {
18
16
  throw new Error(`Expected regex literal, got: ${text}`);
19
17
  }
20
18
  let lastSlash = -1;
21
19
  for (let index = text.length - 1; index > 0; index -= 1) {
22
- if (text[index] !== "/")
20
+ if (text[index] !== '/')
23
21
  continue;
24
22
  let backslashCount = 0;
25
- for (let i = index - 1; i >= 0 && text[i] === "\\"; i -= 1) {
23
+ for (let i = index - 1; i >= 0 && text[i] === '\\'; i -= 1) {
26
24
  backslashCount += 1;
27
25
  }
28
26
  if (backslashCount % 2 === 0) {
@@ -39,7 +37,7 @@ function parseRegexLiteral(text) {
39
37
  };
40
38
  }
41
39
  function isPlainObject(value) {
42
- return typeof value === "object" && value !== null && !Array.isArray(value);
40
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
43
41
  }
44
42
  function evaluateLiteralExpression(node) {
45
43
  const current = unwrapExpression(node);
@@ -57,13 +55,13 @@ function evaluateLiteralExpression(node) {
57
55
  return null;
58
56
  if (ts.isPrefixUnaryExpression(current) && current.operator === ts.SyntaxKind.MinusToken) {
59
57
  const operand = evaluateLiteralExpression(current.operand);
60
- if (typeof operand === "number")
58
+ if (typeof operand === 'number')
61
59
  return -operand;
62
60
  }
63
61
  if (ts.isArrayLiteralExpression(current)) {
64
62
  return current.elements.map((element) => {
65
63
  if (ts.isSpreadElement(element)) {
66
- throw new Error("Spread elements are not supported in literal arrays");
64
+ throw new Error('Spread elements are not supported in literal arrays');
67
65
  }
68
66
  return evaluateLiteralExpression(element);
69
67
  });
@@ -72,10 +70,10 @@ function evaluateLiteralExpression(node) {
72
70
  const result = {};
73
71
  for (const property of current.properties) {
74
72
  if (ts.isSpreadAssignment(property) || ts.isShorthandPropertyAssignment(property)) {
75
- throw new Error("Spread and shorthand properties are not supported in literal objects");
73
+ throw new Error('Spread and shorthand properties are not supported in literal objects');
76
74
  }
77
75
  if (!ts.isPropertyAssignment(property)) {
78
- throw new Error("Unsupported object literal property");
76
+ throw new Error('Unsupported object literal property');
79
77
  }
80
78
  const key = getPropertyName(property.name);
81
79
  result[key] = evaluateLiteralExpression(property.initializer);
@@ -88,14 +86,14 @@ function evaluateLiteralExpression(node) {
88
86
  if (ts.isBinaryExpression(current) && current.operatorToken.kind === ts.SyntaxKind.PlusToken) {
89
87
  const left = evaluateLiteralExpression(current.left);
90
88
  const right = evaluateLiteralExpression(current.right);
91
- if (typeof left === "string" || typeof right === "string") {
89
+ if (typeof left === 'string' || typeof right === 'string') {
92
90
  return String(left) + String(right);
93
91
  }
94
- if (typeof left === "number" && typeof right === "number") {
92
+ if (typeof left === 'number' && typeof right === 'number') {
95
93
  return left + right;
96
94
  }
97
95
  }
98
- if (ts.isIdentifier(current) && current.text === "undefined") {
96
+ if (ts.isIdentifier(current) && current.text === 'undefined') {
99
97
  return undefined;
100
98
  }
101
99
  throw new Error(`Unsupported literal expression: ${current.getText()}`);
@@ -108,38 +106,38 @@ function getPropertyName(name) {
108
106
  }
109
107
  function schemaKind(schema) {
110
108
  if (schema === false)
111
- return "never";
109
+ return 'never';
112
110
  if (!isPlainObject(schema))
113
- return "unknown";
111
+ return 'unknown';
114
112
  if (Array.isArray(schema.anyOf))
115
- return "union";
113
+ return 'union';
116
114
  if (schema.const !== undefined)
117
- return "const";
115
+ return 'const';
118
116
  if (Array.isArray(schema.enum))
119
- return "enum";
117
+ return 'enum';
120
118
  const type = schema.type;
121
- if (typeof type === "string")
119
+ if (typeof type === 'string')
122
120
  return type;
123
- return "unknown";
121
+ return 'unknown';
124
122
  }
125
123
  function ensureObjectSchema(schema) {
126
- if (schema === false || !isPlainObject(schema) || schema.type !== "object") {
127
- throw new Error("Expected object schema");
124
+ if (schema === false || !isPlainObject(schema) || schema.type !== 'object') {
125
+ throw new Error('Expected object schema');
128
126
  }
129
127
  return schema;
130
128
  }
131
129
  function makeNullable(schema) {
132
130
  if (!isPlainObject(schema)) {
133
- return { anyOf: [schema, { type: "null" }] };
131
+ return { anyOf: [schema, { type: 'null' }] };
134
132
  }
135
133
  const existing = schema.type;
136
134
  if (Array.isArray(existing)) {
137
- return existing.includes("null") ? schema : { ...schema, type: [...existing, "null"] };
135
+ return existing.includes('null') ? schema : { ...schema, type: [...existing, 'null'] };
138
136
  }
139
- if (typeof existing === "string") {
140
- return { ...schema, type: [existing, "null"] };
137
+ if (typeof existing === 'string') {
138
+ return { ...schema, type: [existing, 'null'] };
141
139
  }
142
- return { anyOf: [schema, { type: "null" }] };
140
+ return { anyOf: [schema, { type: 'null' }] };
143
141
  }
144
142
  function withAnnotation(schema, key, value) {
145
143
  if (schema === false) {
@@ -153,24 +151,24 @@ function applyNumericConstraint(schema, kind, method, value) {
153
151
  if (schema === false)
154
152
  return schema;
155
153
  const next = { ...schema };
156
- if (kind === "number" || kind === "integer") {
157
- if (method === "min" || method === "length")
154
+ if (kind === 'number' || kind === 'integer') {
155
+ if (method === 'min' || method === 'length')
158
156
  next.minimum = value;
159
- if (method === "max" || method === "length")
157
+ if (method === 'max' || method === 'length')
160
158
  next.maximum = value;
161
159
  return next;
162
160
  }
163
- if (kind === "string") {
164
- if (method === "min" || method === "length")
161
+ if (kind === 'string') {
162
+ if (method === 'min' || method === 'length')
165
163
  next.minLength = value;
166
- if (method === "max" || method === "length")
164
+ if (method === 'max' || method === 'length')
167
165
  next.maxLength = value;
168
166
  return next;
169
167
  }
170
- if (kind === "array") {
171
- if (method === "min" || method === "length")
168
+ if (kind === 'array') {
169
+ if (method === 'min' || method === 'length')
172
170
  next.minItems = value;
173
- if (method === "max" || method === "length")
171
+ if (method === 'max' || method === 'length')
174
172
  next.maxItems = value;
175
173
  return next;
176
174
  }
@@ -179,35 +177,35 @@ function applyNumericConstraint(schema, kind, method, value) {
179
177
  function applyMethod(receiver, method, args, ctx) {
180
178
  const kind = schemaKind(receiver.schema);
181
179
  switch (method) {
182
- case "optional":
180
+ case 'optional':
183
181
  return { ...receiver, optional: true };
184
- case "nullable":
182
+ case 'nullable':
185
183
  return { schema: makeNullable(receiver.schema), optional: receiver.optional };
186
- case "default": {
184
+ case 'default': {
187
185
  if (args.length === 0)
188
- throw new Error("default() requires an argument");
186
+ throw new Error('default() requires an argument');
189
187
  return {
190
- schema: withAnnotation(receiver.schema, "default", evaluateLiteralExpression(args[0])),
188
+ schema: withAnnotation(receiver.schema, 'default', evaluateLiteralExpression(args[0])),
191
189
  optional: true,
192
190
  };
193
191
  }
194
- case "describe": {
192
+ case 'describe': {
195
193
  if (args.length === 0)
196
- throw new Error("describe() requires an argument");
194
+ throw new Error('describe() requires an argument');
197
195
  return {
198
- schema: withAnnotation(receiver.schema, "description", evaluateLiteralExpression(args[0])),
196
+ schema: withAnnotation(receiver.schema, 'description', evaluateLiteralExpression(args[0])),
199
197
  optional: receiver.optional,
200
198
  };
201
199
  }
202
- case "meta": {
200
+ case 'meta': {
203
201
  if (args.length === 0)
204
- throw new Error("meta() requires an argument");
202
+ throw new Error('meta() requires an argument');
205
203
  const meta = evaluateLiteralExpression(args[0]);
206
204
  if (!isPlainObject(meta)) {
207
- throw new Error("meta() expects an object literal");
205
+ throw new Error('meta() expects an object literal');
208
206
  }
209
207
  let schema = receiver.schema;
210
- const supportedKeys = new Set(["description", "title"]);
208
+ const supportedKeys = new Set(['description', 'title']);
211
209
  for (const [key, value] of Object.entries(meta)) {
212
210
  if (supportedKeys.has(key)) {
213
211
  schema = withAnnotation(schema, key, value);
@@ -218,99 +216,99 @@ function applyMethod(receiver, method, args, ctx) {
218
216
  }
219
217
  return { schema, optional: receiver.optional };
220
218
  }
221
- case "url":
222
- if (kind !== "string") {
223
- throw new Error("url() can only be applied to string schemas");
219
+ case 'url':
220
+ if (kind !== 'string') {
221
+ throw new Error('url() can only be applied to string schemas');
224
222
  }
225
223
  return {
226
- schema: withAnnotation(receiver.schema, "format", "uri"),
224
+ schema: withAnnotation(receiver.schema, 'format', 'uri'),
227
225
  optional: receiver.optional,
228
226
  };
229
- case "email":
230
- if (kind !== "string") {
231
- throw new Error("email() can only be applied to string schemas");
227
+ case 'email':
228
+ if (kind !== 'string') {
229
+ throw new Error('email() can only be applied to string schemas');
232
230
  }
233
231
  return {
234
- schema: withAnnotation(receiver.schema, "format", "email"),
232
+ schema: withAnnotation(receiver.schema, 'format', 'email'),
235
233
  optional: receiver.optional,
236
234
  };
237
- case "uuid":
238
- if (kind !== "string") {
239
- throw new Error("uuid() can only be applied to string schemas");
235
+ case 'uuid':
236
+ if (kind !== 'string') {
237
+ throw new Error('uuid() can only be applied to string schemas');
240
238
  }
241
239
  return {
242
- schema: withAnnotation(receiver.schema, "format", "uuid"),
240
+ schema: withAnnotation(receiver.schema, 'format', 'uuid'),
243
241
  optional: receiver.optional,
244
242
  };
245
- case "datetime":
246
- if (kind !== "string") {
247
- throw new Error("datetime() can only be applied to string schemas");
243
+ case 'datetime':
244
+ if (kind !== 'string') {
245
+ throw new Error('datetime() can only be applied to string schemas');
248
246
  }
249
247
  return {
250
- schema: withAnnotation(receiver.schema, "format", "date-time"),
248
+ schema: withAnnotation(receiver.schema, 'format', 'date-time'),
251
249
  optional: receiver.optional,
252
250
  };
253
- case "regex": {
254
- if (kind !== "string") {
255
- throw new Error("regex() can only be applied to string schemas");
251
+ case 'regex': {
252
+ if (kind !== 'string') {
253
+ throw new Error('regex() can only be applied to string schemas');
256
254
  }
257
255
  if (args.length === 0)
258
- throw new Error("regex() requires an argument");
256
+ throw new Error('regex() requires an argument');
259
257
  const regex = evaluateLiteralExpression(args[0]);
260
- if (!isPlainObject(regex) || typeof regex.pattern !== "string") {
261
- throw new Error("regex() expects a regex literal");
258
+ if (!isPlainObject(regex) || typeof regex.pattern !== 'string') {
259
+ throw new Error('regex() expects a regex literal');
262
260
  }
263
- if (typeof regex.flags === "string" && regex.flags.length > 0) {
261
+ if (typeof regex.flags === 'string' && regex.flags.length > 0) {
264
262
  ctx.warnings.push(`Ignored regex flags "${regex.flags}"`);
265
263
  }
266
264
  return {
267
- schema: withAnnotation(receiver.schema, "pattern", regex.pattern),
265
+ schema: withAnnotation(receiver.schema, 'pattern', regex.pattern),
268
266
  optional: receiver.optional,
269
267
  };
270
268
  }
271
- case "min":
269
+ case 'min':
272
270
  if (args.length === 0)
273
- throw new Error("min() requires an argument");
271
+ throw new Error('min() requires an argument');
274
272
  return {
275
- schema: applyNumericConstraint(receiver.schema, kind, "min", Number(evaluateLiteralExpression(args[0]))),
273
+ schema: applyNumericConstraint(receiver.schema, kind, 'min', Number(evaluateLiteralExpression(args[0]))),
276
274
  optional: receiver.optional,
277
275
  };
278
- case "max":
276
+ case 'max':
279
277
  if (args.length === 0)
280
- throw new Error("max() requires an argument");
278
+ throw new Error('max() requires an argument');
281
279
  return {
282
- schema: applyNumericConstraint(receiver.schema, kind, "max", Number(evaluateLiteralExpression(args[0]))),
280
+ schema: applyNumericConstraint(receiver.schema, kind, 'max', Number(evaluateLiteralExpression(args[0]))),
283
281
  optional: receiver.optional,
284
282
  };
285
- case "length":
283
+ case 'length':
286
284
  if (args.length === 0)
287
- throw new Error("length() requires an argument");
285
+ throw new Error('length() requires an argument');
288
286
  return {
289
- schema: applyNumericConstraint(receiver.schema, kind, "length", Number(evaluateLiteralExpression(args[0]))),
287
+ schema: applyNumericConstraint(receiver.schema, kind, 'length', Number(evaluateLiteralExpression(args[0]))),
290
288
  optional: receiver.optional,
291
289
  };
292
- case "int": {
293
- if (kind !== "number" && kind !== "integer") {
294
- throw new Error("int() can only be applied to number schemas");
290
+ case 'int': {
291
+ if (kind !== 'number' && kind !== 'integer') {
292
+ throw new Error('int() can only be applied to number schemas');
295
293
  }
296
- const next = withAnnotation(receiver.schema, "type", "integer");
294
+ const next = withAnnotation(receiver.schema, 'type', 'integer');
297
295
  return { schema: next, optional: receiver.optional };
298
296
  }
299
- case "positive": {
300
- if (kind !== "number" && kind !== "integer") {
301
- throw new Error("positive() can only be applied to number schemas");
297
+ case 'positive': {
298
+ if (kind !== 'number' && kind !== 'integer') {
299
+ throw new Error('positive() can only be applied to number schemas');
302
300
  }
303
- const next = withAnnotation(receiver.schema, "exclusiveMinimum", 0);
301
+ const next = withAnnotation(receiver.schema, 'exclusiveMinimum', 0);
304
302
  return { schema: next, optional: receiver.optional };
305
303
  }
306
- case "strict": {
304
+ case 'strict': {
307
305
  const objectSchema = ensureObjectSchema(receiver.schema);
308
306
  return {
309
307
  schema: { ...objectSchema, additionalProperties: false },
310
308
  optional: receiver.optional,
311
309
  };
312
310
  }
313
- case "partial": {
311
+ case 'partial': {
314
312
  // .partial() makes all declared properties optional. For records
315
313
  // (open-shape objects) there's nothing to do.
316
314
  if (!isPlainObject(receiver.schema)) {
@@ -319,17 +317,17 @@ function applyMethod(receiver, method, args, ctx) {
319
317
  const { required: _required, ...rest } = receiver.schema;
320
318
  return { schema: rest, optional: receiver.optional };
321
319
  }
322
- case "array":
320
+ case 'array':
323
321
  return {
324
322
  schema: {
325
- type: "array",
323
+ type: 'array',
326
324
  items: receiver.schema,
327
325
  },
328
326
  optional: receiver.optional,
329
327
  };
330
- case "or": {
328
+ case 'or': {
331
329
  if (args.length === 0)
332
- throw new Error("or() requires an argument");
330
+ throw new Error('or() requires an argument');
333
331
  const other = convertExpression(args[0], ctx);
334
332
  return {
335
333
  schema: { anyOf: [receiver.schema, other.schema] },
@@ -345,7 +343,7 @@ function convertObjectShape(objectLiteral, ctx) {
345
343
  const required = [];
346
344
  for (const property of objectLiteral.properties) {
347
345
  if (!ts.isPropertyAssignment(property)) {
348
- throw new Error("Only property assignments are supported in z.object()");
346
+ throw new Error('Only property assignments are supported in z.object()');
349
347
  }
350
348
  const key = getPropertyName(property.name);
351
349
  const child = convertExpression(property.initializer, ctx);
@@ -355,20 +353,20 @@ function convertObjectShape(objectLiteral, ctx) {
355
353
  }
356
354
  }
357
355
  return {
358
- type: "object",
356
+ type: 'object',
359
357
  properties,
360
358
  required,
361
359
  };
362
360
  }
363
361
  function convertBaseZodCall(method, args, ctx) {
364
362
  switch (method) {
365
- case "string":
366
- return { schema: { type: "string" }, optional: false };
367
- case "number":
368
- return { schema: { type: "number" }, optional: false };
369
- case "boolean":
370
- return { schema: { type: "boolean" }, optional: false };
371
- case "enum": {
363
+ case 'string':
364
+ return { schema: { type: 'string' }, optional: false };
365
+ case 'number':
366
+ return { schema: { type: 'number' }, optional: false };
367
+ case 'boolean':
368
+ return { schema: { type: 'boolean' }, optional: false };
369
+ case 'enum': {
372
370
  // Canonical form: z.enum(["a", "b"]). Also tolerate the hand-written
373
371
  // typo z.enum("a", "b") by treating variadic args as an implicit array.
374
372
  let elements;
@@ -379,46 +377,46 @@ function convertBaseZodCall(method, args, ctx) {
379
377
  elements = args;
380
378
  }
381
379
  else {
382
- throw new Error("enum() expects at least one argument");
380
+ throw new Error('enum() expects at least one argument');
383
381
  }
384
382
  const values = elements.map((element) => evaluateLiteralExpression(element));
385
383
  return { schema: { enum: values }, optional: false };
386
384
  }
387
- case "literal": {
385
+ case 'literal': {
388
386
  if (args.length !== 1)
389
- throw new Error("literal() expects a single argument");
387
+ throw new Error('literal() expects a single argument');
390
388
  return { schema: { const: evaluateLiteralExpression(args[0]) }, optional: false };
391
389
  }
392
- case "never":
390
+ case 'never':
393
391
  return { schema: false, optional: false };
394
- case "array": {
392
+ case 'array': {
395
393
  if (args.length !== 1) {
396
- throw new Error("array() expects a single argument");
394
+ throw new Error('array() expects a single argument');
397
395
  }
398
396
  const item = convertExpression(args[0], ctx);
399
397
  return {
400
398
  schema: {
401
- type: "array",
399
+ type: 'array',
402
400
  items: item.schema,
403
401
  },
404
402
  optional: false,
405
403
  };
406
404
  }
407
- case "object": {
405
+ case 'object': {
408
406
  if (args.length === 0) {
409
- return { schema: { type: "object" }, optional: false };
407
+ return { schema: { type: 'object' }, optional: false };
410
408
  }
411
409
  if (args.length !== 1 || !ts.isObjectLiteralExpression(args[0])) {
412
- throw new Error("object() expects a single object literal argument");
410
+ throw new Error('object() expects a single object literal argument');
413
411
  }
414
412
  return {
415
413
  schema: convertObjectShape(args[0], ctx),
416
414
  optional: false,
417
415
  };
418
416
  }
419
- case "record": {
417
+ case 'record': {
420
418
  if (args.length === 0 || args.length > 2) {
421
- throw new Error("record() expects one or two arguments");
419
+ throw new Error('record() expects one or two arguments');
422
420
  }
423
421
  let keySchema;
424
422
  let valueIndex = 0;
@@ -428,7 +426,7 @@ function convertBaseZodCall(method, args, ctx) {
428
426
  }
429
427
  const valueSchema = convertExpression(args[valueIndex], ctx);
430
428
  const schema = {
431
- type: "object",
429
+ type: 'object',
432
430
  additionalProperties: valueSchema.schema,
433
431
  };
434
432
  if (keySchema && isPlainObject(keySchema.schema) && Array.isArray(keySchema.schema.enum)) {
@@ -436,19 +434,19 @@ function convertBaseZodCall(method, args, ctx) {
436
434
  }
437
435
  return { schema, optional: false };
438
436
  }
439
- case "union": {
437
+ case 'union': {
440
438
  if (args.length !== 1 || !ts.isArrayLiteralExpression(args[0])) {
441
- throw new Error("union() expects a single array literal argument");
439
+ throw new Error('union() expects a single array literal argument');
442
440
  }
443
441
  const options = args[0].elements.map((element) => convertExpression(element, ctx).schema);
444
442
  return { schema: { anyOf: options }, optional: false };
445
443
  }
446
- case "tuple": {
444
+ case 'tuple': {
447
445
  if (args.length !== 1 || !ts.isArrayLiteralExpression(args[0])) {
448
- throw new Error("tuple() expects a single array literal argument");
446
+ throw new Error('tuple() expects a single array literal argument');
449
447
  }
450
448
  const items = args[0].elements.map((element) => convertExpression(element, ctx).schema);
451
- const schema = { type: "array", minItems: items.length, maxItems: items.length };
449
+ const schema = { type: 'array', minItems: items.length, maxItems: items.length };
452
450
  if (items.length > 0) {
453
451
  schema.prefixItems = items;
454
452
  schema.items = false;
@@ -469,7 +467,7 @@ function convertCallExpression(call, ctx) {
469
467
  const receiverExpr = unwrapExpression(callee.expression);
470
468
  if (ts.isIdentifier(receiverExpr)) {
471
469
  const base = receiverExpr.text;
472
- if (base === "z") {
470
+ if (base === 'z') {
473
471
  return convertBaseZodCall(method, call.arguments, ctx);
474
472
  }
475
473
  }
@@ -477,8 +475,8 @@ function convertCallExpression(call, ctx) {
477
475
  return applyMethod(receiver, method, call.arguments, ctx);
478
476
  }
479
477
  if (ts.isIdentifier(callee)) {
480
- if (callee.text === "z") {
481
- throw new Error("Unexpected bare z() call");
478
+ if (callee.text === 'z') {
479
+ throw new Error('Unexpected bare z() call');
482
480
  }
483
481
  }
484
482
  throw new Error(`Unsupported call expression: ${call.getText()}`);
@@ -493,22 +491,22 @@ function convertExpression(node, ctx) {
493
491
  // schema, so the intent is always the method call).
494
492
  if (ts.isPropertyAccessExpression(expr)) {
495
493
  const method = expr.name.text;
496
- if (method === "nullable" || method === "optional") {
494
+ if (method === 'nullable' || method === 'optional') {
497
495
  const receiver = convertExpression(expr.expression, ctx);
498
496
  return applyMethod(receiver, method, ts.factory.createNodeArray([]), ctx);
499
497
  }
500
498
  }
501
- if (ts.isIdentifier(expr) && expr.text === "undefined") {
499
+ if (ts.isIdentifier(expr) && expr.text === 'undefined') {
502
500
  return { schema: false, optional: true };
503
501
  }
504
502
  throw new Error(`Unsupported Zod expression: ${expr.getText()}`);
505
503
  }
506
504
  export function zodToJsonSchema(source) {
507
- const sourceFile = ts.createSourceFile("schema.ts", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
505
+ const sourceFile = ts.createSourceFile('schema.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
508
506
  const ctx = { warnings: [] };
509
507
  const expressionStatement = sourceFile.statements.find(ts.isExpressionStatement);
510
508
  if (!expressionStatement) {
511
- throw new Error("Expected a Zod expression");
509
+ throw new Error('Expected a Zod expression');
512
510
  }
513
511
  const result = convertExpression(expressionStatement.expression, ctx);
514
512
  if (result.schema !== false && isPlainObject(result.schema)) {
@@ -1,5 +1,5 @@
1
1
  import { fetchAllChangeHistory, fetchEnvironments } from './launch/api.js';
2
- import { InvalidSourceConfigError, getOutputPath, isLegacyLogLevel, slugify, transformConfig } from './launch/translate.js';
2
+ import { InvalidSourceConfigError, getOutputPath, isLegacyLogLevel, slugify, transformConfig, } from './launch/translate.js';
3
3
  const SOURCE_NAME = 'launch';
4
4
  const state = { apiKey: null, droppedOverrides: new Map(), envIdMap: null, skippedConfigs: [] };
5
5
  class MissingAuthError extends Error {