@palantir/pack.sdkgen 0.0.1-beta.1

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.
Files changed (80) hide show
  1. package/LICENSE.txt +13 -0
  2. package/README.md +589 -0
  3. package/bin/cli.ts +7 -0
  4. package/build/esm/__tests__/createCommand.test.js +157 -0
  5. package/build/esm/__tests__/createCommand.test.js.map +1 -0
  6. package/build/esm/__tests__/generator.test.js +190 -0
  7. package/build/esm/__tests__/generator.test.js.map +1 -0
  8. package/build/esm/__tests__/schemaParser.test.js +67 -0
  9. package/build/esm/__tests__/schemaParser.test.js.map +1 -0
  10. package/build/esm/__tests__/templateLoader.test.js +67 -0
  11. package/build/esm/__tests__/templateLoader.test.js.map +1 -0
  12. package/build/esm/__tests__/templateUtils.test.js +94 -0
  13. package/build/esm/__tests__/templateUtils.test.js.map +1 -0
  14. package/build/esm/__tests__/types/testTypes.js +2 -0
  15. package/build/esm/__tests__/types/testTypes.js.map +1 -0
  16. package/build/esm/cli.js +25 -0
  17. package/build/esm/cli.js.map +1 -0
  18. package/build/esm/commands/create.js +173 -0
  19. package/build/esm/commands/create.js.map +1 -0
  20. package/build/esm/core/contextBuilder.js +33 -0
  21. package/build/esm/core/contextBuilder.js.map +1 -0
  22. package/build/esm/core/generator.js +248 -0
  23. package/build/esm/core/generator.js.map +1 -0
  24. package/build/esm/core/hookRunner.js +68 -0
  25. package/build/esm/core/hookRunner.js.map +1 -0
  26. package/build/esm/core/schemaParser.js +50 -0
  27. package/build/esm/core/schemaParser.js.map +1 -0
  28. package/build/esm/core/templateLoader.js +99 -0
  29. package/build/esm/core/templateLoader.js.map +1 -0
  30. package/build/esm/index.js +26 -0
  31. package/build/esm/index.js.map +1 -0
  32. package/build/esm/types/index.js +2 -0
  33. package/build/esm/types/index.js.map +1 -0
  34. package/build/esm/utils/fileSystem.js +72 -0
  35. package/build/esm/utils/fileSystem.js.map +1 -0
  36. package/build/esm/utils/logger.js +44 -0
  37. package/build/esm/utils/logger.js.map +1 -0
  38. package/build/esm/utils/prompts.js +25 -0
  39. package/build/esm/utils/prompts.js.map +1 -0
  40. package/build/esm/utils/templateUtils.js +61 -0
  41. package/build/esm/utils/templateUtils.js.map +1 -0
  42. package/build/types/__tests__/createCommand.test.d.ts +2 -0
  43. package/build/types/__tests__/createCommand.test.d.ts.map +1 -0
  44. package/build/types/__tests__/generator.test.d.ts +2 -0
  45. package/build/types/__tests__/generator.test.d.ts.map +1 -0
  46. package/build/types/__tests__/schemaParser.test.d.ts +2 -0
  47. package/build/types/__tests__/schemaParser.test.d.ts.map +1 -0
  48. package/build/types/__tests__/templateLoader.test.d.ts +2 -0
  49. package/build/types/__tests__/templateLoader.test.d.ts.map +1 -0
  50. package/build/types/__tests__/templateUtils.test.d.ts +2 -0
  51. package/build/types/__tests__/templateUtils.test.d.ts.map +1 -0
  52. package/build/types/__tests__/types/testTypes.d.ts +38 -0
  53. package/build/types/__tests__/types/testTypes.d.ts.map +1 -0
  54. package/build/types/cli.d.ts +2 -0
  55. package/build/types/cli.d.ts.map +1 -0
  56. package/build/types/commands/create.d.ts +3 -0
  57. package/build/types/commands/create.d.ts.map +1 -0
  58. package/build/types/core/contextBuilder.d.ts +5 -0
  59. package/build/types/core/contextBuilder.d.ts.map +1 -0
  60. package/build/types/core/generator.d.ts +15 -0
  61. package/build/types/core/generator.d.ts.map +1 -0
  62. package/build/types/core/hookRunner.d.ts +3 -0
  63. package/build/types/core/hookRunner.d.ts.map +1 -0
  64. package/build/types/core/schemaParser.d.ts +7 -0
  65. package/build/types/core/schemaParser.d.ts.map +1 -0
  66. package/build/types/core/templateLoader.d.ts +12 -0
  67. package/build/types/core/templateLoader.d.ts.map +1 -0
  68. package/build/types/index.d.ts +11 -0
  69. package/build/types/index.d.ts.map +1 -0
  70. package/build/types/types/index.d.ts +68 -0
  71. package/build/types/types/index.d.ts.map +1 -0
  72. package/build/types/utils/fileSystem.d.ts +8 -0
  73. package/build/types/utils/fileSystem.d.ts.map +1 -0
  74. package/build/types/utils/logger.d.ts +11 -0
  75. package/build/types/utils/logger.d.ts.map +1 -0
  76. package/build/types/utils/prompts.d.ts +3 -0
  77. package/build/types/utils/prompts.d.ts.map +1 -0
  78. package/build/types/utils/templateUtils.d.ts +3 -0
  79. package/build/types/utils/templateUtils.d.ts.map +1 -0
  80. package/package.json +61 -0
@@ -0,0 +1,94 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { describe, expect, it } from "vitest";
18
+ import { createTemplateUtils } from "../utils/templateUtils.js";
19
+ describe("templateUtils", () => {
20
+ const utils = createTemplateUtils();
21
+ describe("camelCase", () => {
22
+ it("should convert to camelCase", () => {
23
+ expect(utils.camelCase("hello-world")).toBe("helloWorld");
24
+ expect(utils.camelCase("hello_world")).toBe("helloWorld");
25
+ expect(utils.camelCase("Hello World")).toBe("helloWorld");
26
+ expect(utils.camelCase("HelloWorld")).toBe("helloWorld");
27
+ expect(utils.camelCase("HELLO_WORLD")).toBe("helloWorld");
28
+ });
29
+ });
30
+ describe("pascalCase", () => {
31
+ it("should convert to PascalCase", () => {
32
+ expect(utils.pascalCase("hello-world")).toBe("HelloWorld");
33
+ expect(utils.pascalCase("hello_world")).toBe("HelloWorld");
34
+ expect(utils.pascalCase("hello world")).toBe("HelloWorld");
35
+ expect(utils.pascalCase("helloWorld")).toBe("HelloWorld");
36
+ });
37
+ });
38
+ describe("kebabCase", () => {
39
+ it("should convert to kebab-case", () => {
40
+ expect(utils.kebabCase("HelloWorld")).toBe("hello-world");
41
+ expect(utils.kebabCase("helloWorld")).toBe("hello-world");
42
+ expect(utils.kebabCase("hello_world")).toBe("hello-world");
43
+ expect(utils.kebabCase("Hello World")).toBe("hello-world");
44
+ });
45
+ });
46
+ describe("snakeCase", () => {
47
+ it("should convert to snake_case", () => {
48
+ expect(utils.snakeCase("HelloWorld")).toBe("hello_world");
49
+ expect(utils.snakeCase("helloWorld")).toBe("hello_world");
50
+ expect(utils.snakeCase("hello-world")).toBe("hello_world");
51
+ expect(utils.snakeCase("Hello World")).toBe("hello_world");
52
+ });
53
+ });
54
+ describe("pluralize", () => {
55
+ it("should pluralize words", () => {
56
+ expect(utils.pluralize("user")).toBe("users");
57
+ expect(utils.pluralize("users")).toBe("users");
58
+ expect(utils.pluralize("city")).toBe("cities");
59
+ expect(utils.pluralize("box")).toBe("boxes");
60
+ expect(utils.pluralize("church")).toBe("churches");
61
+ expect(utils.pluralize("bush")).toBe("bushes");
62
+ });
63
+ });
64
+ describe("singularize", () => {
65
+ it("should singularize words", () => {
66
+ expect(utils.singularize("users")).toBe("user");
67
+ expect(utils.singularize("cities")).toBe("city");
68
+ /* cspell:disable-next-line */
69
+ expect(utils.singularize("boxes")).toBe("boxe");
70
+ /* cspell:disable-next-line */
71
+ expect(utils.singularize("churches")).toBe("churche");
72
+ });
73
+ });
74
+ describe("capitalize", () => {
75
+ it("should capitalize first letter", () => {
76
+ expect(utils.capitalize("hello")).toBe("Hello");
77
+ expect(utils.capitalize("HELLO")).toBe("HELLO");
78
+ expect(utils.capitalize("hello world")).toBe("Hello world");
79
+ });
80
+ });
81
+ describe("lower", () => {
82
+ it("should convert to lowercase", () => {
83
+ expect(utils.lower("HELLO")).toBe("hello");
84
+ expect(utils.lower("Hello World")).toBe("hello world");
85
+ });
86
+ });
87
+ describe("upper", () => {
88
+ it("should convert to uppercase", () => {
89
+ expect(utils.upper("hello")).toBe("HELLO");
90
+ expect(utils.upper("Hello World")).toBe("HELLO WORLD");
91
+ });
92
+ });
93
+ });
94
+ //# sourceMappingURL=templateUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateUtils.test.js","names":["describe","expect","it","createTemplateUtils","utils","camelCase","toBe","pascalCase","kebabCase","snakeCase","pluralize","singularize","capitalize","lower","upper"],"sources":["templateUtils.test.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { describe, expect, it } from \"vitest\";\nimport { createTemplateUtils } from \"../utils/templateUtils.js\";\n\ndescribe(\"templateUtils\", () => {\n const utils = createTemplateUtils();\n\n describe(\"camelCase\", () => {\n it(\"should convert to camelCase\", () => {\n expect(utils.camelCase(\"hello-world\")).toBe(\"helloWorld\");\n expect(utils.camelCase(\"hello_world\")).toBe(\"helloWorld\");\n expect(utils.camelCase(\"Hello World\")).toBe(\"helloWorld\");\n expect(utils.camelCase(\"HelloWorld\")).toBe(\"helloWorld\");\n expect(utils.camelCase(\"HELLO_WORLD\")).toBe(\"helloWorld\");\n });\n });\n\n describe(\"pascalCase\", () => {\n it(\"should convert to PascalCase\", () => {\n expect(utils.pascalCase(\"hello-world\")).toBe(\"HelloWorld\");\n expect(utils.pascalCase(\"hello_world\")).toBe(\"HelloWorld\");\n expect(utils.pascalCase(\"hello world\")).toBe(\"HelloWorld\");\n expect(utils.pascalCase(\"helloWorld\")).toBe(\"HelloWorld\");\n });\n });\n\n describe(\"kebabCase\", () => {\n it(\"should convert to kebab-case\", () => {\n expect(utils.kebabCase(\"HelloWorld\")).toBe(\"hello-world\");\n expect(utils.kebabCase(\"helloWorld\")).toBe(\"hello-world\");\n expect(utils.kebabCase(\"hello_world\")).toBe(\"hello-world\");\n expect(utils.kebabCase(\"Hello World\")).toBe(\"hello-world\");\n });\n });\n\n describe(\"snakeCase\", () => {\n it(\"should convert to snake_case\", () => {\n expect(utils.snakeCase(\"HelloWorld\")).toBe(\"hello_world\");\n expect(utils.snakeCase(\"helloWorld\")).toBe(\"hello_world\");\n expect(utils.snakeCase(\"hello-world\")).toBe(\"hello_world\");\n expect(utils.snakeCase(\"Hello World\")).toBe(\"hello_world\");\n });\n });\n\n describe(\"pluralize\", () => {\n it(\"should pluralize words\", () => {\n expect(utils.pluralize(\"user\")).toBe(\"users\");\n expect(utils.pluralize(\"users\")).toBe(\"users\");\n expect(utils.pluralize(\"city\")).toBe(\"cities\");\n expect(utils.pluralize(\"box\")).toBe(\"boxes\");\n expect(utils.pluralize(\"church\")).toBe(\"churches\");\n expect(utils.pluralize(\"bush\")).toBe(\"bushes\");\n });\n });\n\n describe(\"singularize\", () => {\n it(\"should singularize words\", () => {\n expect(utils.singularize(\"users\")).toBe(\"user\");\n expect(utils.singularize(\"cities\")).toBe(\"city\");\n /* cspell:disable-next-line */\n expect(utils.singularize(\"boxes\")).toBe(\"boxe\");\n /* cspell:disable-next-line */\n expect(utils.singularize(\"churches\")).toBe(\"churche\");\n });\n });\n\n describe(\"capitalize\", () => {\n it(\"should capitalize first letter\", () => {\n expect(utils.capitalize(\"hello\")).toBe(\"Hello\");\n expect(utils.capitalize(\"HELLO\")).toBe(\"HELLO\");\n expect(utils.capitalize(\"hello world\")).toBe(\"Hello world\");\n });\n });\n\n describe(\"lower\", () => {\n it(\"should convert to lowercase\", () => {\n expect(utils.lower(\"HELLO\")).toBe(\"hello\");\n expect(utils.lower(\"Hello World\")).toBe(\"hello world\");\n });\n });\n\n describe(\"upper\", () => {\n it(\"should convert to uppercase\", () => {\n expect(utils.upper(\"hello\")).toBe(\"HELLO\");\n expect(utils.upper(\"Hello World\")).toBe(\"HELLO WORLD\");\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=testTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testTypes.js","names":[],"sources":["testTypes.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface TestSchema {\n version: string;\n description: string;\n types: {\n User: {\n id: string;\n name: string;\n email: string;\n createdAt: string;\n };\n Post: {\n id: string;\n title: string;\n content: string;\n authorId: string;\n };\n Comment: {\n id: string;\n postId: string;\n userId: string;\n content: string;\n createdAt: string;\n };\n };\n}\n\nexport interface PackageJson {\n name: string;\n version: string;\n description: string;\n author: string;\n license: string;\n main?: string;\n types?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { Command } from "commander";
18
+ import { createCommand } from "./commands/create.js";
19
+ export function cli(args) {
20
+ const program = new Command();
21
+ program.name("sdkgen").description("Generate TypeScript/JavaScript SDKs from schema definitions").version("0.0.1");
22
+ program.command("create <project-name>").description("Create a new SDK project").option("-t, --template <template>", "template to use", "default").option("-s, --schema <path>", "path to schema file").option("--skip-install", "skip dependency installation").option("--verbose", "enable verbose logging").option("--dry-run", "preview without writing files").option("--non-interactive", "run in non-interactive mode using defaults").option("--config <path>", "path to JSON config file with template configuration").option("--overwrite", "overwrite existing directory").action(createCommand);
23
+ program.parse(args);
24
+ }
25
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","names":["Command","createCommand","cli","args","program","name","description","version","command","option","action","parse"],"sources":["cli.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Command } from \"commander\";\nimport { createCommand } from \"./commands/create.js\";\n\nexport function cli(args: string[]): void {\n const program = new Command();\n\n program\n .name(\"sdkgen\")\n .description(\"Generate TypeScript/JavaScript SDKs from schema definitions\")\n .version(\"0.0.1\");\n\n program\n .command(\"create <project-name>\")\n .description(\"Create a new SDK project\")\n .option(\"-t, --template <template>\", \"template to use\", \"default\")\n .option(\"-s, --schema <path>\", \"path to schema file\")\n .option(\"--skip-install\", \"skip dependency installation\")\n .option(\"--verbose\", \"enable verbose logging\")\n .option(\"--dry-run\", \"preview without writing files\")\n .option(\"--non-interactive\", \"run in non-interactive mode using defaults\")\n .option(\"--config <path>\", \"path to JSON config file with template configuration\")\n .option(\"--overwrite\", \"overwrite existing directory\")\n .action(createCommand);\n\n program.parse(args);\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,QAAQ,WAAW;AACnC,SAASC,aAAa,QAAQ,sBAAsB;AAEpD,OAAO,SAASC,GAAGA,CAACC,IAAc,EAAQ;EACxC,MAAMC,OAAO,GAAG,IAAIJ,OAAO,CAAC,CAAC;EAE7BI,OAAO,CACJC,IAAI,CAAC,QAAQ,CAAC,CACdC,WAAW,CAAC,6DAA6D,CAAC,CAC1EC,OAAO,CAAC,OAAO,CAAC;EAEnBH,OAAO,CACJI,OAAO,CAAC,uBAAuB,CAAC,CAChCF,WAAW,CAAC,0BAA0B,CAAC,CACvCG,MAAM,CAAC,2BAA2B,EAAE,iBAAiB,EAAE,SAAS,CAAC,CACjEA,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CACpDA,MAAM,CAAC,gBAAgB,EAAE,8BAA8B,CAAC,CACxDA,MAAM,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAC7CA,MAAM,CAAC,WAAW,EAAE,+BAA+B,CAAC,CACpDA,MAAM,CAAC,mBAAmB,EAAE,4CAA4C,CAAC,CACzEA,MAAM,CAAC,iBAAiB,EAAE,sDAAsD,CAAC,CACjFA,MAAM,CAAC,aAAa,EAAE,8BAA8B,CAAC,CACrDC,MAAM,CAACT,aAAa,CAAC;EAExBG,OAAO,CAACO,KAAK,CAACR,IAAI,CAAC;AACrB","ignoreList":[]}
@@ -0,0 +1,173 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import fs from "fs-extra";
18
+ import path from "path";
19
+ import { ContextBuilder } from "../core/contextBuilder.js";
20
+ import { Generator } from "../core/generator.js";
21
+ import { SchemaParser } from "../core/schemaParser.js";
22
+ import { TemplateLoader } from "../core/templateLoader.js";
23
+ import { Logger } from "../utils/logger.js";
24
+ import { promptUser } from "../utils/prompts.js";
25
+ export async function createCommand(projectName, options) {
26
+ const logger = new Logger(options.verbose);
27
+ try {
28
+ logger.info(`Creating SDK project: ${projectName}`);
29
+
30
+ // Set output path
31
+ const outputPath = path.resolve(projectName);
32
+
33
+ // Check if directory already exists
34
+ if (await fs.pathExists(outputPath)) {
35
+ if (options.overwrite) {
36
+ logger.info(`Directory ${projectName} exists, continuing with overwrite`);
37
+ } else {
38
+ throw new Error(`Directory ${projectName} already exists`);
39
+ }
40
+ }
41
+
42
+ // Load template
43
+ const templateLoader = new TemplateLoader(logger);
44
+ const templateName = options.template || "default";
45
+ logger.debug(`Loading template: ${templateName}`);
46
+ const {
47
+ config: templateConfig,
48
+ templateDir
49
+ } = await templateLoader.loadTemplate(templateName);
50
+ logger.success(`Template loaded: ${templateConfig.name}`);
51
+
52
+ // Load schema
53
+ const schemaParser = new SchemaParser(logger);
54
+ const schema = await schemaParser.loadSchema(options.schema);
55
+ if (options.schema) {
56
+ logger.success("Schema loaded successfully");
57
+ }
58
+
59
+ // Prompt user for additional configuration
60
+ let answers = {};
61
+
62
+ // Load config from file or object if provided
63
+ if (options.config) {
64
+ if (typeof options.config === "string") {
65
+ // Load from file path
66
+ try {
67
+ const configPath = path.resolve(options.config);
68
+ const configContent = await fs.readFile(configPath, "utf-8");
69
+ answers = JSON.parse(configContent);
70
+ logger.debug(`Using config from ${configPath}: ${JSON.stringify(answers)}`);
71
+ } catch (error) {
72
+ throw new Error(`Failed to load config file: ${error instanceof Error ? error.message : String(error)}`);
73
+ }
74
+ } else {
75
+ // Use provided object directly
76
+ answers = options.config;
77
+ logger.debug(`Using config object: ${JSON.stringify(answers)}`);
78
+ }
79
+ }
80
+
81
+ // Transform schema if transformer is defined
82
+ let transformedSchema = schema;
83
+ if (templateConfig.transformers?.default) {
84
+ logger.debug("Applying schema transformer");
85
+ const transformer = templateConfig.transformers.default;
86
+ if (typeof transformer === "string") {
87
+ // Load transformer from file
88
+ const transformerPath = path.join(templateDir, transformer);
89
+ const {
90
+ default: transformFn
91
+ } = await import(transformerPath);
92
+ transformedSchema = await transformFn(schema, {
93
+ projectName,
94
+ schema,
95
+ answers,
96
+ templateConfig,
97
+ schemaPath: options.schema,
98
+ outputPath,
99
+ options: {
100
+ skipInstall: options.skipInstall,
101
+ verbose: options.verbose,
102
+ dryRun: options.dryRun
103
+ },
104
+ utils: {}
105
+ });
106
+ } else if (typeof transformer === "function") {
107
+ transformedSchema = await transformer(schema, {
108
+ projectName,
109
+ schema,
110
+ answers,
111
+ templateConfig,
112
+ schemaPath: options.schema,
113
+ outputPath,
114
+ options: {
115
+ skipInstall: options.skipInstall,
116
+ verbose: options.verbose,
117
+ dryRun: options.dryRun
118
+ },
119
+ utils: {}
120
+ });
121
+ }
122
+ }
123
+ if (templateConfig.prompts && templateConfig.prompts.length > 0) {
124
+ if (options.nonInteractive || process.env.CI) {
125
+ // Use default values from prompts for missing answers
126
+ for (const prompt of templateConfig.prompts) {
127
+ if (!(prompt.name in answers) && prompt.default !== undefined) {
128
+ answers[prompt.name] = prompt.default;
129
+ }
130
+ }
131
+ logger.debug("Running in non-interactive mode with defaults");
132
+ } else {
133
+ // Filter out prompts that already have answers
134
+ const unansweredPrompts = templateConfig.prompts.filter(prompt => !(prompt.name in answers));
135
+ if (unansweredPrompts.length > 0) {
136
+ logger.info("Please answer the following questions:");
137
+ const newAnswers = await promptUser(unansweredPrompts);
138
+ answers = {
139
+ ...answers,
140
+ ...newAnswers
141
+ };
142
+ }
143
+ }
144
+ }
145
+
146
+ // Build generator context
147
+ const contextBuilder = new ContextBuilder();
148
+ const context = contextBuilder.build(projectName, transformedSchema, answers, templateConfig, outputPath, {
149
+ skipInstall: options.skipInstall,
150
+ verbose: options.verbose,
151
+ dryRun: options.dryRun
152
+ }, options.schema);
153
+
154
+ // Generate SDK
155
+ const generator = new Generator(context, templateDir, logger);
156
+ await generator.generate();
157
+ if (!options.dryRun) {
158
+ logger.success(`🎉 SDK project created successfully!`);
159
+ logger.info(`Next steps:`);
160
+ logger.info(` cd ${projectName}`);
161
+ if (options.skipInstall) {
162
+ logger.info(` npm install`);
163
+ }
164
+ logger.info(` npm run build`);
165
+ } else {
166
+ logger.success("✨ Dry run completed. No files were written.");
167
+ }
168
+ } catch (error) {
169
+ logger.error(`Failed to create SDK: ${error instanceof Error ? error.message : String(error)}`);
170
+ process.exit(1);
171
+ }
172
+ }
173
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","names":["fs","path","ContextBuilder","Generator","SchemaParser","TemplateLoader","Logger","promptUser","createCommand","projectName","options","logger","verbose","info","outputPath","resolve","pathExists","overwrite","Error","templateLoader","templateName","template","debug","config","templateConfig","templateDir","loadTemplate","success","name","schemaParser","schema","loadSchema","answers","configPath","configContent","readFile","JSON","parse","stringify","error","message","String","transformedSchema","transformers","default","transformer","transformerPath","join","transformFn","schemaPath","skipInstall","dryRun","utils","prompts","length","nonInteractive","process","env","CI","prompt","undefined","unansweredPrompts","filter","newAnswers","contextBuilder","context","build","generator","generate","exit"],"sources":["create.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport { ContextBuilder } from \"../core/contextBuilder.js\";\nimport { Generator } from \"../core/generator.js\";\nimport { SchemaParser } from \"../core/schemaParser.js\";\nimport { TemplateLoader } from \"../core/templateLoader.js\";\nimport type { CreateCommandOptions, TemplateUtils } from \"../types/index.js\";\nimport { Logger } from \"../utils/logger.js\";\nimport { promptUser } from \"../utils/prompts.js\";\n\nexport async function createCommand(\n projectName: string,\n options: CreateCommandOptions,\n): Promise<void> {\n const logger = new Logger(options.verbose);\n\n try {\n logger.info(`Creating SDK project: ${projectName}`);\n\n // Set output path\n const outputPath = path.resolve(projectName);\n\n // Check if directory already exists\n if (await fs.pathExists(outputPath)) {\n if (options.overwrite) {\n logger.info(`Directory ${projectName} exists, continuing with overwrite`);\n } else {\n throw new Error(`Directory ${projectName} already exists`);\n }\n }\n\n // Load template\n const templateLoader = new TemplateLoader(logger);\n const templateName = options.template || \"default\";\n logger.debug(`Loading template: ${templateName}`);\n\n const { config: templateConfig, templateDir } = await templateLoader.loadTemplate(templateName);\n logger.success(`Template loaded: ${templateConfig.name}`);\n\n // Load schema\n const schemaParser = new SchemaParser(logger);\n const schema = await schemaParser.loadSchema(options.schema);\n if (options.schema) {\n logger.success(\"Schema loaded successfully\");\n }\n\n // Prompt user for additional configuration\n let answers: Record<string, unknown> = {};\n\n // Load config from file or object if provided\n if (options.config) {\n if (typeof options.config === \"string\") {\n // Load from file path\n try {\n const configPath = path.resolve(options.config);\n const configContent = await fs.readFile(configPath, \"utf-8\");\n answers = JSON.parse(configContent) as Record<string, unknown>;\n logger.debug(`Using config from ${configPath}: ${JSON.stringify(answers)}`);\n } catch (error) {\n throw new Error(\n `Failed to load config file: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n } else {\n // Use provided object directly\n answers = options.config;\n logger.debug(`Using config object: ${JSON.stringify(answers)}`);\n }\n }\n\n // Transform schema if transformer is defined\n let transformedSchema = schema;\n if (templateConfig.transformers?.default) {\n logger.debug(\"Applying schema transformer\");\n const transformer = templateConfig.transformers.default;\n\n if (typeof transformer === \"string\") {\n // Load transformer from file\n const transformerPath = path.join(templateDir, transformer);\n const { default: transformFn } = await import(transformerPath) as {\n default: (schema: unknown, context: unknown) => Promise<unknown>;\n };\n transformedSchema = await transformFn(schema, {\n projectName,\n schema,\n answers,\n templateConfig,\n schemaPath: options.schema,\n outputPath,\n options: {\n skipInstall: options.skipInstall,\n verbose: options.verbose,\n dryRun: options.dryRun,\n },\n utils: {} as TemplateUtils,\n });\n } else if (typeof transformer === \"function\") {\n transformedSchema = await transformer(schema, {\n projectName,\n schema,\n answers,\n templateConfig,\n schemaPath: options.schema,\n outputPath,\n options: {\n skipInstall: options.skipInstall,\n verbose: options.verbose,\n dryRun: options.dryRun,\n },\n utils: {} as TemplateUtils,\n });\n }\n }\n\n if (templateConfig.prompts && templateConfig.prompts.length > 0) {\n if (options.nonInteractive || process.env.CI) {\n // Use default values from prompts for missing answers\n for (const prompt of templateConfig.prompts) {\n if (!(prompt.name in answers) && prompt.default !== undefined) {\n answers[prompt.name] = prompt.default;\n }\n }\n logger.debug(\"Running in non-interactive mode with defaults\");\n } else {\n // Filter out prompts that already have answers\n const unansweredPrompts = templateConfig.prompts.filter(\n prompt => !(prompt.name in answers),\n );\n if (unansweredPrompts.length > 0) {\n logger.info(\"Please answer the following questions:\");\n const newAnswers = await promptUser(unansweredPrompts);\n answers = { ...answers, ...newAnswers };\n }\n }\n }\n\n // Build generator context\n const contextBuilder = new ContextBuilder();\n const context = contextBuilder.build(\n projectName,\n transformedSchema,\n answers,\n templateConfig,\n outputPath,\n {\n skipInstall: options.skipInstall,\n verbose: options.verbose,\n dryRun: options.dryRun,\n },\n options.schema,\n );\n\n // Generate SDK\n const generator = new Generator(context, templateDir, logger);\n await generator.generate();\n\n if (!options.dryRun) {\n logger.success(`🎉 SDK project created successfully!`);\n logger.info(`Next steps:`);\n logger.info(` cd ${projectName}`);\n if (options.skipInstall) {\n logger.info(` npm install`);\n }\n logger.info(` npm run build`);\n } else {\n logger.success(\"✨ Dry run completed. No files were written.\");\n }\n } catch (error) {\n logger.error(`Failed to create SDK: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { createTemplateUtils } from "../utils/templateUtils.js";
18
+ export class ContextBuilder {
19
+ build(projectName, schema, answers, templateConfig, outputPath, options, schemaPath) {
20
+ return {
21
+ projectName,
22
+ schema,
23
+ answers,
24
+ templateConfig,
25
+ schemaPath,
26
+ outputPath,
27
+ options,
28
+ utils: createTemplateUtils(),
29
+ additionalData: {}
30
+ };
31
+ }
32
+ }
33
+ //# sourceMappingURL=contextBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextBuilder.js","names":["createTemplateUtils","ContextBuilder","build","projectName","schema","answers","templateConfig","outputPath","options","schemaPath","utils","additionalData"],"sources":["contextBuilder.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { GeneratorContext, GeneratorOptions, TemplateConfig } from \"../types/index.js\";\nimport { createTemplateUtils } from \"../utils/templateUtils.js\";\n\nexport class ContextBuilder {\n build(\n projectName: string,\n schema: unknown,\n answers: Record<string, unknown>,\n templateConfig: TemplateConfig,\n outputPath: string,\n options: GeneratorOptions,\n schemaPath?: string,\n ): GeneratorContext {\n return {\n projectName,\n schema,\n answers,\n templateConfig,\n schemaPath,\n outputPath,\n options,\n utils: createTemplateUtils(),\n additionalData: {},\n };\n }\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,mBAAmB,QAAQ,2BAA2B;AAE/D,OAAO,MAAMC,cAAc,CAAC;EAC1BC,KAAKA,CACHC,WAAmB,EACnBC,MAAe,EACfC,OAAgC,EAChCC,cAA8B,EAC9BC,UAAkB,EAClBC,OAAyB,EACzBC,UAAmB,EACD;IAClB,OAAO;MACLN,WAAW;MACXC,MAAM;MACNC,OAAO;MACPC,cAAc;MACdG,UAAU;MACVF,UAAU;MACVC,OAAO;MACPE,KAAK,EAAEV,mBAAmB,CAAC,CAAC;MAC5BW,cAAc,EAAE,CAAC;IACnB,CAAC;EACH;AACF","ignoreList":[]}
@@ -0,0 +1,248 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { spawnSync } from "child_process";
18
+ import ejs from "ejs";
19
+ import { findUp } from "find-up";
20
+ import fs from "fs-extra";
21
+ import { glob } from "glob";
22
+ import path from "path";
23
+ import { fileURLToPath } from "url";
24
+ import * as fileSystem from "../utils/fileSystem.js";
25
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
26
+ export class Generator {
27
+ constructor(context, templateDir, logger) {
28
+ this.context = context;
29
+ this.templateDir = templateDir;
30
+ this.logger = logger;
31
+ }
32
+ async generate() {
33
+ const {
34
+ outputPath,
35
+ options
36
+ } = this.context;
37
+
38
+ // Create output directory
39
+ if (!options.dryRun) {
40
+ await fs.ensureDir(outputPath);
41
+ }
42
+
43
+ // Run beforeGenerate hook
44
+ await this.runHook("beforeGenerate");
45
+
46
+ // Process template files
47
+ await this.processTemplateFiles();
48
+
49
+ // Copy static files
50
+ await this.copyStaticFiles();
51
+
52
+ // Copy schema directory if provided
53
+ await this.copySchemaDirectory();
54
+
55
+ // Run afterGenerate hook
56
+ await this.runHook("afterGenerate");
57
+
58
+ // Install dependencies if not skipped
59
+ if (!options.skipInstall && !options.dryRun) {
60
+ await this.installDependencies();
61
+ }
62
+ this.logger.success(`✨ SDK generated successfully at ${outputPath}`);
63
+ }
64
+ async processTemplateFiles() {
65
+ const {
66
+ templateConfig,
67
+ outputPath,
68
+ options
69
+ } = this.context;
70
+ const templateFiles = templateConfig.templateFiles || ["**/*.ejs"];
71
+ const templatePath = path.join(this.templateDir, "template");
72
+ for (const pattern of templateFiles) {
73
+ const files = glob.globSync(pattern, {
74
+ cwd: templatePath,
75
+ nodir: true,
76
+ dot: true
77
+ });
78
+ for (const file of files) {
79
+ const sourcePath = path.join(templatePath, file);
80
+ const destPath = path.join(outputPath, file.replace(/\.ejs$/, ""));
81
+ this.logger.debug(`Processing template: ${file}`);
82
+
83
+ // Read and render template
84
+ const template = await fs.readFile(sourcePath, "utf8");
85
+ const rendered = ejs.render(template, this.context);
86
+
87
+ // Write rendered file
88
+ if (!options.dryRun) {
89
+ await fileSystem.writeFile(destPath, rendered);
90
+ } else {
91
+ this.logger.debug(`Would write to: ${destPath}`);
92
+ }
93
+ }
94
+ }
95
+ }
96
+ async copyStaticFiles() {
97
+ const {
98
+ templateConfig,
99
+ outputPath,
100
+ options
101
+ } = this.context;
102
+ const staticFiles = templateConfig.staticFiles || [];
103
+ const templatePath = path.join(this.templateDir, "template");
104
+ if (staticFiles.length === 0) {
105
+ return;
106
+ }
107
+ await fileSystem.copyFiles(templatePath, outputPath, staticFiles, options.dryRun);
108
+ }
109
+ async copySchemaDirectory() {
110
+ const {
111
+ schemaPath,
112
+ outputPath,
113
+ options
114
+ } = this.context;
115
+ if (!schemaPath) {
116
+ return;
117
+ }
118
+ const schemaStats = await fs.stat(schemaPath).catch(() => null);
119
+ if (!schemaStats) {
120
+ return;
121
+ }
122
+ const destSchemaPath = path.join(outputPath, "schema");
123
+ if (schemaStats.isDirectory()) {
124
+ // Copy entire schema directory
125
+ if (!options.dryRun) {
126
+ await fs.ensureDir(destSchemaPath);
127
+ await fs.copy(schemaPath, destSchemaPath);
128
+ this.logger.debug(`Copied schema directory to ${destSchemaPath}`);
129
+ } else {
130
+ this.logger.debug(`Would copy schema directory to ${destSchemaPath}`);
131
+ }
132
+ } else if (schemaStats.isFile()) {
133
+ // Copy single schema file
134
+ if (!options.dryRun) {
135
+ await fs.ensureDir(destSchemaPath);
136
+ const fileName = path.basename(schemaPath);
137
+ await fs.copy(schemaPath, path.join(destSchemaPath, fileName));
138
+ this.logger.debug(`Copied schema file to ${destSchemaPath}`);
139
+ } else {
140
+ this.logger.debug(`Would copy schema file to ${destSchemaPath}`);
141
+ }
142
+ }
143
+ }
144
+ async runHook(hookName) {
145
+ const {
146
+ templateConfig
147
+ } = this.context;
148
+ const hook = templateConfig.hooks?.[hookName];
149
+ if (!hook) {
150
+ return;
151
+ }
152
+ this.logger.debug(`Running ${hookName} hook`);
153
+ if (typeof hook === "string") {
154
+ // Execute hook as child process
155
+ const hookPath = path.join(this.templateDir, hook);
156
+ if (await fs.pathExists(hookPath)) {
157
+ try {
158
+ // Find the package root by locating package.json
159
+ const packageJsonPath = await findUp("package.json", {
160
+ cwd: __dirname
161
+ });
162
+ if (!packageJsonPath) {
163
+ throw new Error("Could not find package.json");
164
+ }
165
+ const packageRoot = path.dirname(packageJsonPath);
166
+ const hookRunnerPath = path.join(packageRoot, "build/esm/core/hookRunner.js");
167
+ if (!(await fs.pathExists(hookRunnerPath))) {
168
+ throw new Error(`Hook runner not found at ${hookRunnerPath}. ` + `Please run 'pnpm build' in the sdkgen-cli package.`);
169
+ }
170
+
171
+ // Serialize context to JSON
172
+ const contextJson = JSON.stringify(this.context);
173
+
174
+ // Run hook as child process in template directory
175
+ // Use spawnSync for better output streaming
176
+ const result = spawnSync("node", [hookRunnerPath, hookPath, hookName, contextJson], {
177
+ cwd: this.templateDir,
178
+ encoding: "utf8",
179
+ // 'inherit' for stderr allows errors to stream immediately
180
+ // 'pipe' for stdout so we can capture the result for beforeGenerate
181
+ stdio: ["pipe", "pipe", "inherit"]
182
+ });
183
+ if (result.error) {
184
+ throw result.error;
185
+ }
186
+ if (result.status !== 0) {
187
+ throw new Error(`Hook ${hookName} failed with exit code ${result.status}`);
188
+ }
189
+
190
+ // Parse result and update context if needed
191
+ if (hookName === "beforeGenerate" && result.stdout) {
192
+ try {
193
+ const updatedContext = JSON.parse(result.stdout);
194
+ this.context = updatedContext;
195
+ } catch {
196
+ // If result is not valid JSON, ignore it
197
+ this.logger.debug("Hook did not return valid JSON, keeping original context");
198
+ }
199
+ }
200
+ } catch (error) {
201
+ this.logger.error(`Failed to execute ${hookName} hook: ${error instanceof Error ? error.message : String(error)}`);
202
+ throw error;
203
+ }
204
+ } else {
205
+ this.logger.warning(`Hook file not found: ${hookPath}`);
206
+ }
207
+ } else if (typeof hook === "function") {
208
+ // Execute inline hook (for backward compatibility and testing)
209
+ if (hookName === "beforeGenerate") {
210
+ const result = await hook(this.context);
211
+ this.context = result;
212
+ } else {
213
+ await hook(this.context, this.context.outputPath);
214
+ }
215
+ }
216
+ }
217
+ async installDependencies() {
218
+ const {
219
+ outputPath,
220
+ projectName
221
+ } = this.context;
222
+ this.logger.info("Installing dependencies...");
223
+
224
+ // Check which package manager to use
225
+ const hasPackageJson = await fs.pathExists(path.join(outputPath, "package.json"));
226
+ if (!hasPackageJson) {
227
+ this.logger.debug("No package.json found, skipping dependency installation");
228
+ return;
229
+ }
230
+
231
+ // Detect package manager (simplified - just use npm for now)
232
+ try {
233
+ const result = spawnSync("npm", ["install"], {
234
+ cwd: outputPath,
235
+ stdio: "inherit"
236
+ });
237
+ if (result.status === 0) {
238
+ this.logger.success("Dependencies installed successfully");
239
+ } else {
240
+ throw new Error(`npm install failed with exit code ${result.status}`);
241
+ }
242
+ } catch (_error) {
243
+ this.logger.warning("Failed to install dependencies automatically");
244
+ this.logger.info(`Please run 'npm install' in ${projectName} directory`);
245
+ }
246
+ }
247
+ }
248
+ //# sourceMappingURL=generator.js.map