quicktype 24.0.1 → 25.0.0-pre1

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/README.md CHANGED
@@ -189,6 +189,42 @@ main();
189
189
 
190
190
  The argument to `quicktype` is a complex object with many optional properties. [Explore its definition](https://github.com/quicktype/quicktype/blob/master/packages/quicktype-core/src/Run.ts#L637) to understand what options are allowed.
191
191
 
192
+ #### TypeScript: the `lang` option is a `LanguageName`, not a `string`
193
+
194
+ In TypeScript, the `lang` option of `quicktype` and the argument of `jsonInputForTargetLanguage` are typed as `LanguageName`, a union of all supported language names — passing a plain `string` is a compile-time error. If the language name is known statically, just pass the literal (`lang: "swift"`). For wrappers that take the language name at runtime — from CLI arguments or configuration — validate it with the `isLanguageName` type guard instead of casting:
195
+
196
+ ```typescript
197
+ import { type LanguageName, isLanguageName, quicktype } from "quicktype-core";
198
+
199
+ async function quicktypeJSON(targetLanguage: LanguageName, typeName: string, jsonString: string) {
200
+ // same body as above
201
+ }
202
+
203
+ const lang = process.argv[2]; // untrusted string
204
+ if (!isLanguageName(lang)) {
205
+ throw new Error(`Unknown language: ${lang}`);
206
+ }
207
+ // lang now has type LanguageName
208
+ const { lines } = await quicktypeJSON(lang, "Person", jsonString);
209
+ ```
210
+
211
+ #### Bundling `quicktype-core` as ESM
212
+
213
+ `quicktype-core` ships both CommonJS and ESM builds. If you bundle it into an ESM output for Node with esbuild (`--format=esm --platform=node`), the bundle may throw at runtime:
214
+
215
+ ```
216
+ Error: Dynamic require of "process" is not supported
217
+ ```
218
+
219
+ This is not specific to quicktype: some of its dependencies (e.g. `yaml`) expose an ESM entry that wraps a CommonJS core, and esbuild replaces `require` calls inside inlined CommonJS with a shim that throws in ESM output. The standard workaround is to inject a `createRequire` banner:
220
+
221
+ ```bash
222
+ esbuild main.js --bundle --format=esm --platform=node \
223
+ --banner:js="import { createRequire } from 'module'; const require = createRequire(import.meta.url);"
224
+ ```
225
+
226
+ Bundling to CommonJS output (`--format=cjs`) works without any workaround.
227
+
192
228
  ### Adding Custom logic or Rendering:
193
229
 
194
230
  Quicktype supports creating your own custom languages and rendering output, you can extend existing classes or create your own to be using by the `quicktype function`.<br/>
@@ -26,7 +26,7 @@ async function introspectServer(url, method, headerStrings) {
26
26
  try {
27
27
  const response = await globalThis.fetch(url, {
28
28
  method,
29
- headers: headers,
29
+ headers,
30
30
  body: JSON.stringify({ query: (0, graphql_1.getIntrospectionQuery)() }),
31
31
  });
32
32
  result = (await response.json());
package/dist/index.js CHANGED
@@ -68,7 +68,8 @@ async function sourceFromFileOrUrlArray(name, filesOrUrls, httpHeaders) {
68
68
  }
69
69
  function typeNameFromFilename(filename) {
70
70
  const name = path.basename(filename);
71
- return name.substring(0, name.lastIndexOf("."));
71
+ const extIndex = name.lastIndexOf(".");
72
+ return extIndex === -1 ? "" : name.slice(0, extIndex);
72
73
  }
73
74
  async function samplesFromDirectory(dataDir, httpHeaders) {
74
75
  async function readFilesOrURLsInDirectory(d) {
@@ -79,8 +80,8 @@ async function samplesFromDirectory(dataDir, httpHeaders) {
79
80
  // Each file is a (Name, JSON | URL)
80
81
  const sourcesInDir = [];
81
82
  const graphQLSources = [];
82
- let graphQLSchema = undefined;
83
- let graphQLSchemaFileName = undefined;
83
+ let graphQLSchema;
84
+ let graphQLSchemaFileName;
84
85
  for (let file of files) {
85
86
  const name = typeNameFromFilename(file);
86
87
  let fileOrUrl = file;
@@ -160,14 +161,14 @@ async function samplesFromDirectory(dataDir, httpHeaders) {
160
161
  if (jsonSamples.length > 0 &&
161
162
  schemaSources.length + graphQLSources.length > 0) {
162
163
  return (0, quicktype_core_1.messageError)("DriverCannotMixJSONWithOtherSamples", {
163
- dir: dir,
164
+ dir,
164
165
  });
165
166
  }
166
167
  // FIXME: rewrite this to be clearer
167
168
  const oneUnlessEmpty = (xs) => Math.sign(xs.length);
168
169
  if (oneUnlessEmpty(schemaSources) + oneUnlessEmpty(graphQLSources) >
169
170
  1) {
170
- return (0, quicktype_core_1.messageError)("DriverCannotMixNonJSONInputs", { dir: dir });
171
+ return (0, quicktype_core_1.messageError)("DriverCannotMixNonJSONInputs", { dir });
171
172
  }
172
173
  if (jsonSamples.length > 0) {
173
174
  sources.push({
@@ -242,7 +243,7 @@ function inferCLIOptions(opts, targetLanguage) {
242
243
  const options = {
243
244
  src: opts.src ?? [],
244
245
  srcUrls: opts.srcUrls,
245
- srcLang: srcLang,
246
+ srcLang,
246
247
  lang: language.name,
247
248
  topLevel: opts.topLevel ?? inferTopLevel(opts),
248
249
  noRender: !!opts.noRender,
@@ -279,7 +280,7 @@ function negatedInferenceFlagName(name) {
279
280
  if (name.startsWith(prefix)) {
280
281
  name = name.slice(prefix.length);
281
282
  }
282
- return "no" + (0, quicktype_core_1.capitalize)(name);
283
+ return `no${(0, quicktype_core_1.capitalize)(name)}`;
283
284
  }
284
285
  function dashedFromCamelCase(name) {
285
286
  return (0, quicktype_core_1.splitIntoWords)(name)
@@ -348,7 +349,7 @@ function makeOptionDefinitions(targetLanguages) {
348
349
  return {
349
350
  name: dashedFromCamelCase(negatedInferenceFlagName(name)),
350
351
  optionType: "boolean",
351
- description: flag.negationDescription + ".",
352
+ description: `${flag.negationDescription}.`,
352
353
  kind: "cli",
353
354
  };
354
355
  }).values());
@@ -638,7 +639,10 @@ async function getSources(options) {
638
639
  return sources;
639
640
  }
640
641
  function makeTypeScriptSource(fileNames) {
641
- return Object.assign({ kind: "schema" }, (0, quicktype_typescript_input_1.schemaForTypeScriptSources)(fileNames));
642
+ return {
643
+ kind: "schema",
644
+ ...(0, quicktype_typescript_input_1.schemaForTypeScriptSources)(fileNames),
645
+ };
642
646
  }
643
647
  function jsonInputForTargetLanguage(targetLanguage, languages, handleJSONRefs = false) {
644
648
  if (typeof targetLanguage === "string") {
@@ -694,11 +698,11 @@ async function makeQuicktypeOptions(options, targetLanguages) {
694
698
  return undefined;
695
699
  }
696
700
  let sources = [];
697
- let leadingComments = undefined;
701
+ let leadingComments;
698
702
  let fixedTopLevels = false;
699
703
  switch (options.srcLang) {
700
- case "graphql":
701
- let schemaString = undefined;
704
+ case "graphql": {
705
+ let schemaString;
702
706
  let wroteSchemaToFile = false;
703
707
  if (options.graphqlIntrospect !== undefined) {
704
708
  schemaString = await (0, GraphQLIntrospection_1.introspectServer)(options.graphqlIntrospect, (0, collection_utils_1.withDefault)(options.httpMethod, "POST"), (0, collection_utils_1.withDefault)(options.httpHeader, []));
@@ -723,7 +727,7 @@ async function makeQuicktypeOptions(options, targetLanguages) {
723
727
  }
724
728
  const gqlSources = [];
725
729
  for (const queryFile of options.src) {
726
- let schemaFileName = undefined;
730
+ let schemaFileName;
727
731
  if (schemaString === undefined) {
728
732
  schemaFileName = (0, quicktype_core_1.defined)(options.graphqlSchema);
729
733
  schemaString = fs.readFileSync(schemaFileName, "utf8");
@@ -737,6 +741,7 @@ async function makeQuicktypeOptions(options, targetLanguages) {
737
741
  }
738
742
  sources = gqlSources;
739
743
  break;
744
+ }
740
745
  case "json":
741
746
  case "schema":
742
747
  sources = await getSources(options);
@@ -749,7 +754,10 @@ async function makeQuicktypeOptions(options, targetLanguages) {
749
754
  const collectionJSON = fs.readFileSync(collectionFile, "utf8");
750
755
  const { sources: postmanSources, description } = (0, quicktype_core_1.sourcesFromPostmanCollection)(collectionJSON, collectionFile);
751
756
  for (const src of postmanSources) {
752
- sources.push(Object.assign({ kind: "json" }, stringSourceDataToStreamSourceData(src)));
757
+ sources.push({
758
+ kind: "json",
759
+ ...stringSourceDataToStreamSourceData(src),
760
+ });
753
761
  }
754
762
  if (postmanSources.length > 1) {
755
763
  fixedTopLevels = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quicktype",
3
- "version": "24.0.1",
3
+ "version": "25.0.0-pre1",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,12 +17,12 @@
17
17
  "test:unit": "vitest run",
18
18
  "test:unit:watch": "vitest",
19
19
  "test:fixtures": "script/test",
20
- "test:release": "ts-node test/release-version.ts",
20
+ "test:release": "tsx test/release-version.ts",
21
21
  "start": "script/watch",
22
22
  "clean": "rm -rf dist *~ packages/*/{dist,out}",
23
23
  "debug": "node --inspect-brk --max-old-space-size=4096 ./dist/index.js",
24
- "lint": "eslint src/** packages/*/src/**",
25
- "lint:fix": "eslint --fix src/** packages/*/src/**"
24
+ "lint": "biome check .",
25
+ "lint:fix": "biome check --write ."
26
26
  },
27
27
  "workspaces": [
28
28
  "./packages/quicktype-core",
@@ -40,16 +40,16 @@
40
40
  "graphql": "^16.11.0",
41
41
  "lodash": "^4.18.1",
42
42
  "moment": "^2.30.1",
43
- "quicktype-core": "24.0.1",
44
- "quicktype-graphql-input": "24.0.1",
45
- "quicktype-typescript-input": "24.0.1",
43
+ "quicktype-core": "25.0.0-pre1",
44
+ "quicktype-graphql-input": "25.0.0-pre1",
45
+ "quicktype-typescript-input": "25.0.0-pre1",
46
46
  "readable-stream": "^4.5.2",
47
47
  "stream-json": "1.8.0",
48
48
  "string-to-stream": "^3.0.1",
49
- "typescript": "~5.8.3"
49
+ "wordwrap": "^1.0.0"
50
50
  },
51
51
  "devDependencies": {
52
- "@biomejs/biome": "^1.9.4",
52
+ "@biomejs/biome": "^2.5.3",
53
53
  "@tsconfig/node20": "^20.1.6",
54
54
  "@types/command-line-args": "^5.2.0",
55
55
  "@types/command-line-usage": "^5.0.4",
@@ -60,12 +60,9 @@
60
60
  "@types/stream-json": "^1.7.3",
61
61
  "@types/urijs": "^1.19.25",
62
62
  "@types/wordwrap": "^1.0.3",
63
- "@typescript-eslint/eslint-plugin": "^6.3.0",
64
- "@typescript-eslint/parser": "^6.3.0",
65
63
  "ajv": "^5.5.2",
66
64
  "deep-equal": "^2.2.3",
67
65
  "esbuild": "^0.28.1",
68
- "exit": "^0.1.2",
69
66
  "promise-timeout": "^1.3.0",
70
67
  "semver": "^7.5.4",
71
68
  "shelljs": "^0.10.0",
@@ -81,7 +78,8 @@
81
78
  "tree-sitter-rust": "^0.24.0",
82
79
  "tree-sitter-scala": "^0.24.0",
83
80
  "tree-sitter-typescript": "^0.23.2",
84
- "ts-node": "^10.9.2",
81
+ "tsx": "^4.23.1",
82
+ "typescript": "~7.0.2",
85
83
  "vitest": "^4.1.10",
86
84
  "watch": "^1.0.2",
87
85
  "web-tree-sitter": "^0.26.9"