@formspec/build 0.1.0-alpha.52 → 0.1.0-alpha.53

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/cli.js CHANGED
@@ -1719,11 +1719,16 @@ var init_ir_generator = __esm({
1719
1719
  });
1720
1720
 
1721
1721
  // src/json-schema/generator.ts
1722
+ import { noopLogger as noopLogger2 } from "@formspec/core";
1722
1723
  function generateJsonSchema(form, options) {
1724
+ const logger = (options?.logger ?? noopLogger2).child({ stage: "ir" });
1723
1725
  const metadata = options?.metadata;
1724
1726
  const vendorPrefix = options?.vendorPrefix;
1725
1727
  const enumSerialization = options?.enumSerialization;
1728
+ logger.debug("canonicalizing chain DSL to IR");
1726
1729
  const ir = canonicalizeChainDSL(form, metadata !== void 0 ? { metadata } : void 0);
1730
+ const schemaLogger = (options?.logger ?? noopLogger2).child({ stage: "schema" });
1731
+ schemaLogger.debug("generating JSON Schema from IR");
1727
1732
  const internalOptions = vendorPrefix === void 0 && enumSerialization === void 0 ? void 0 : {
1728
1733
  ...vendorPrefix !== void 0 && { vendorPrefix },
1729
1734
  ...enumSerialization !== void 0 && { enumSerialization }
@@ -2010,11 +2015,16 @@ var init_ir_generator2 = __esm({
2010
2015
  });
2011
2016
 
2012
2017
  // src/ui-schema/generator.ts
2018
+ import { noopLogger as noopLogger3 } from "@formspec/core";
2013
2019
  function generateUiSchema(form, options) {
2020
+ const logger = (options?.logger ?? noopLogger3).child({ stage: "ir" });
2021
+ logger.debug("canonicalizing chain DSL to IR for UI Schema generation");
2014
2022
  const ir = canonicalizeChainDSL(
2015
2023
  form,
2016
2024
  options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
2017
2025
  );
2026
+ const schemaLogger = (options?.logger ?? noopLogger3).child({ stage: "schema" });
2027
+ schemaLogger.debug("generating UI Schema from IR");
2018
2028
  return generateUiSchemaFromIR(ir);
2019
2029
  }
2020
2030
  var init_generator2 = __esm({
@@ -2493,39 +2503,85 @@ function isNonReferenceIdentifier(node) {
2493
2503
  }
2494
2504
  return false;
2495
2505
  }
2496
- function statementReferencesImportedName(statement, importedNames) {
2506
+ function astReferencesImportedName(root, importedNames) {
2497
2507
  if (importedNames.size === 0) {
2498
2508
  return false;
2499
2509
  }
2500
- let referencesImportedName = false;
2510
+ let found = false;
2501
2511
  const visit = (node) => {
2502
- if (referencesImportedName) {
2503
- return;
2504
- }
2512
+ if (found) return;
2505
2513
  if (ts4.isIdentifier(node) && importedNames.has(node.text) && !isNonReferenceIdentifier(node)) {
2506
- referencesImportedName = true;
2514
+ found = true;
2507
2515
  return;
2508
2516
  }
2509
2517
  ts4.forEachChild(node, visit);
2510
2518
  };
2511
- visit(statement);
2512
- return referencesImportedName;
2519
+ visit(root);
2520
+ return found;
2521
+ }
2522
+ function getObjectMembers(statement) {
2523
+ if (ts4.isInterfaceDeclaration(statement)) {
2524
+ return statement.members;
2525
+ }
2526
+ if (ts4.isTypeLiteralNode(statement.type)) {
2527
+ return statement.type.members;
2528
+ }
2529
+ return void 0;
2530
+ }
2531
+ function rewriteImportedMemberTypes(statement, sourceFile, importedNames) {
2532
+ const members = getObjectMembers(statement);
2533
+ if (members === void 0) {
2534
+ return null;
2535
+ }
2536
+ const replacements = [];
2537
+ for (const member of members) {
2538
+ if (!ts4.isPropertySignature(member)) {
2539
+ if (astReferencesImportedName(member, importedNames)) {
2540
+ return null;
2541
+ }
2542
+ continue;
2543
+ }
2544
+ const typeAnnotation = member.type;
2545
+ if (typeAnnotation === void 0) continue;
2546
+ if (astReferencesImportedName(typeAnnotation, importedNames)) {
2547
+ replacements.push({
2548
+ start: typeAnnotation.getStart(sourceFile),
2549
+ end: typeAnnotation.getEnd()
2550
+ });
2551
+ }
2552
+ }
2553
+ if (replacements.length === 0) {
2554
+ return statement.getText(sourceFile);
2555
+ }
2556
+ const stmtStart = statement.getStart(sourceFile);
2557
+ let result = statement.getText(sourceFile);
2558
+ for (const { start, end } of [...replacements].reverse()) {
2559
+ result = result.slice(0, start - stmtStart) + "unknown" + result.slice(end - stmtStart);
2560
+ }
2561
+ return result;
2513
2562
  }
2514
2563
  function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2515
2564
  const importedNames = collectImportedNames(sourceFile);
2516
2565
  const importedNamesToSkip = new Set(
2517
2566
  [...importedNames].filter((name) => !extensionTypeNames.has(name))
2518
2567
  );
2519
- return sourceFile.statements.filter((statement) => {
2520
- if (ts4.isImportDeclaration(statement)) return false;
2521
- if (ts4.isImportEqualsDeclaration(statement)) return false;
2522
- if (ts4.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
2523
- return false;
2524
- if (statementReferencesImportedName(statement, importedNamesToSkip)) {
2525
- return false;
2568
+ const result = [];
2569
+ for (const statement of sourceFile.statements) {
2570
+ if (ts4.isImportDeclaration(statement)) continue;
2571
+ if (ts4.isImportEqualsDeclaration(statement)) continue;
2572
+ if (ts4.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0) continue;
2573
+ if (!astReferencesImportedName(statement, importedNamesToSkip)) {
2574
+ result.push(statement.getText(sourceFile));
2575
+ continue;
2526
2576
  }
2527
- return true;
2528
- }).map((statement) => statement.getText(sourceFile));
2577
+ if (ts4.isInterfaceDeclaration(statement) || ts4.isTypeAliasDeclaration(statement)) {
2578
+ const rewritten = rewriteImportedMemberTypes(statement, sourceFile, importedNamesToSkip);
2579
+ if (rewritten !== null) {
2580
+ result.push(rewritten);
2581
+ }
2582
+ }
2583
+ }
2584
+ return result;
2529
2585
  }
2530
2586
  function pushUniqueCompilerDiagnostics(target, additions) {
2531
2587
  for (const diagnostic of additions) {
@@ -6927,9 +6983,12 @@ __export(index_exports, {
6927
6983
  uiSchemaSchema: () => uiSchema,
6928
6984
  writeSchemas: () => writeSchemas
6929
6985
  });
6986
+ import { noopLogger as noopLogger4 } from "@formspec/core";
6930
6987
  import * as fs from "fs";
6931
6988
  import * as path3 from "path";
6932
6989
  function buildFormSchemas(form, options) {
6990
+ const logger = options?.logger ?? noopLogger4;
6991
+ logger.debug("buildFormSchemas: starting schema generation");
6933
6992
  return {
6934
6993
  jsonSchema: generateJsonSchema(form, options),
6935
6994
  uiSchema: generateUiSchema(form, options)
@@ -6942,12 +7001,15 @@ function writeSchemas(form, options) {
6942
7001
  indent = 2,
6943
7002
  vendorPrefix,
6944
7003
  enumSerialization,
6945
- metadata
7004
+ metadata,
7005
+ logger: rawLogger
6946
7006
  } = options;
6947
- const buildOptions = vendorPrefix === void 0 && enumSerialization === void 0 && metadata === void 0 ? void 0 : {
7007
+ const logger = (rawLogger ?? noopLogger4).child({ stage: "write" });
7008
+ const buildOptions = vendorPrefix === void 0 && enumSerialization === void 0 && metadata === void 0 ? { logger: rawLogger } : {
6948
7009
  ...vendorPrefix !== void 0 && { vendorPrefix },
6949
7010
  ...enumSerialization !== void 0 && { enumSerialization },
6950
- ...metadata !== void 0 && { metadata }
7011
+ ...metadata !== void 0 && { metadata },
7012
+ logger: rawLogger
6951
7013
  };
6952
7014
  const { jsonSchema, uiSchema: uiSchema2 } = buildFormSchemas(form, buildOptions);
6953
7015
  if (!fs.existsSync(outDir)) {
@@ -6955,7 +7017,9 @@ function writeSchemas(form, options) {
6955
7017
  }
6956
7018
  const jsonSchemaPath = path3.join(outDir, `${name}-schema.json`);
6957
7019
  const uiSchemaPath = path3.join(outDir, `${name}-uischema.json`);
7020
+ logger.debug("writing JSON Schema", { path: jsonSchemaPath });
6958
7021
  fs.writeFileSync(jsonSchemaPath, JSON.stringify(jsonSchema, null, indent));
7022
+ logger.debug("writing UI Schema", { path: uiSchemaPath });
6959
7023
  fs.writeFileSync(uiSchemaPath, JSON.stringify(uiSchema2, null, indent));
6960
7024
  return { jsonSchemaPath, uiSchemaPath };
6961
7025
  }
@@ -6983,6 +7047,33 @@ var init_index = __esm({
6983
7047
  // src/cli.ts
6984
7048
  import * as path4 from "path";
6985
7049
  import { pathToFileURL } from "url";
7050
+
7051
+ // src/cli/logger.ts
7052
+ import { createRequire } from "module";
7053
+ import { isNamespaceEnabled, noopLogger } from "@formspec/core";
7054
+ var require2 = createRequire(import.meta.url);
7055
+ function createLogger(namespace) {
7056
+ const debugEnv = process.env["DEBUG"] ?? "";
7057
+ if (!isNamespaceEnabled(debugEnv, namespace)) {
7058
+ return noopLogger;
7059
+ }
7060
+ const pinoModule = require2("pino");
7061
+ const pino = typeof pinoModule === "function" ? pinoModule : pinoModule.default;
7062
+ const isTTY = process.stderr.isTTY;
7063
+ if (isTTY) {
7064
+ const pinoPretty = require2("pino-pretty");
7065
+ const prettyTransport = pinoPretty.default ?? pinoPretty;
7066
+ const stream = prettyTransport({ destination: 2, colorize: true, sync: true });
7067
+ return pino({ name: namespace, level: "debug" }, stream);
7068
+ }
7069
+ return pino(
7070
+ { name: namespace, level: "debug" },
7071
+ pino.destination({ dest: 2, sync: true })
7072
+ );
7073
+ }
7074
+
7075
+ // src/cli.ts
7076
+ var log = createLogger("formspec:build");
6986
7077
  function printHelp() {
6987
7078
  console.log(`
6988
7079
  FormSpec Build CLI - Generate JSON Schema and UI Schema
@@ -7072,6 +7163,7 @@ function parseArgs(args) {
7072
7163
  if (!name) {
7073
7164
  name = path4.basename(inputFile, path4.extname(inputFile));
7074
7165
  }
7166
+ log.debug("Arguments parsed", { inputFile, outDir, name, enumSerialization });
7075
7167
  return { inputFile, outDir, name, enumSerialization };
7076
7168
  }
7077
7169
  async function main() {
@@ -7082,11 +7174,14 @@ async function main() {
7082
7174
  }
7083
7175
  const { inputFile, outDir, name, enumSerialization } = options;
7084
7176
  const absoluteInput = path4.resolve(process.cwd(), inputFile);
7177
+ log.debug("Resolved input file", { absoluteInput });
7085
7178
  try {
7086
7179
  const fileUrl = pathToFileURL(absoluteInput).href;
7180
+ log.debug("Loading form module", { fileUrl });
7087
7181
  const module = await import(fileUrl);
7088
7182
  const form = module["default"] ?? module["form"];
7089
7183
  if (!form || typeof form !== "object" || !("elements" in form)) {
7184
+ log.error("Input file does not export a valid FormSpec", { fileUrl });
7090
7185
  console.error("Error: Input file must export a FormSpec as default export or as 'form'");
7091
7186
  console.error("Example:");
7092
7187
  console.error(' export default formspec(field.text("name"));');
@@ -7094,18 +7189,22 @@ async function main() {
7094
7189
  console.error(' export const form = formspec(field.text("name"));');
7095
7190
  process.exit(1);
7096
7191
  }
7192
+ log.debug("Form module loaded, generating schemas");
7097
7193
  const { writeSchemas: writeSchemas2 } = await Promise.resolve().then(() => (init_index(), index_exports));
7098
7194
  const { jsonSchemaPath, uiSchemaPath } = writeSchemas2(
7099
7195
  form,
7100
7196
  { outDir, name, enumSerialization }
7101
7197
  );
7198
+ log.debug("Schemas written", { jsonSchemaPath, uiSchemaPath });
7102
7199
  console.log("Generated:");
7103
7200
  console.log(` ${jsonSchemaPath}`);
7104
7201
  console.log(` ${uiSchemaPath}`);
7105
7202
  } catch (error) {
7106
7203
  if (error instanceof Error) {
7204
+ log.child({ err: error.message }).error("Schema generation failed");
7107
7205
  console.error(`Error: ${error.message}`);
7108
7206
  } else {
7207
+ log.error("Schema generation failed with unknown error");
7109
7208
  console.error("Error:", error);
7110
7209
  }
7111
7210
  process.exit(1);