@farming-labs/orm-cli 0.0.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.
package/dist/bin.cjs ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/bin.ts
27
+ var import_commander = require("commander");
28
+
29
+ // src/index.ts
30
+ var import_promises = require("fs/promises");
31
+ var import_node_fs = require("fs");
32
+ var import_node_path = __toESM(require("path"), 1);
33
+ var import_jiti = require("jiti");
34
+ var import_orm = require("@farming-labs/orm");
35
+ async function loadConfig(configPath = "farm-orm.config.ts") {
36
+ const absolutePath = import_node_path.default.resolve(process.cwd(), configPath);
37
+ const jiti = (0, import_jiti.createJiti)(process.cwd());
38
+ const mod = await jiti.import(absolutePath);
39
+ const config = mod.default ?? mod;
40
+ if (!config?.schemas?.length) {
41
+ throw new Error(`No schemas found in ${absolutePath}`);
42
+ }
43
+ return { absolutePath, config };
44
+ }
45
+ function mergeSchemas(schemas) {
46
+ const models = {};
47
+ for (const schema of schemas) {
48
+ for (const [modelName, definition] of Object.entries(schema.models)) {
49
+ if (models[modelName]) {
50
+ throw new Error(`Duplicate model "${modelName}" detected while merging schemas.`);
51
+ }
52
+ models[modelName] = definition;
53
+ }
54
+ }
55
+ return {
56
+ _tag: "schema",
57
+ models
58
+ };
59
+ }
60
+ async function ensureFileDirectory(filePath) {
61
+ await (0, import_promises.mkdir)(import_node_path.default.dirname(filePath), { recursive: true });
62
+ }
63
+ async function readIfExists(filePath) {
64
+ if (!(0, import_node_fs.existsSync)(filePath)) return "";
65
+ return (0, import_promises.readFile)(filePath, "utf8");
66
+ }
67
+ async function generateTarget(target, configPath) {
68
+ const { config } = await loadConfig(configPath);
69
+ const schema = mergeSchemas(config.schemas);
70
+ if (target === "prisma") {
71
+ const targetConfig2 = config.targets.prisma;
72
+ if (!targetConfig2) {
73
+ throw new Error(`Target "${target}" is not configured.`);
74
+ }
75
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
76
+ const rendered = (0, import_orm.renderPrismaSchema)(schema, targetConfig2);
77
+ const mode = targetConfig2.mode ?? "block";
78
+ const current = await readIfExists(outputPath2);
79
+ const next = mode === "replace" || current.trim().length === 0 ? rendered : (0, import_orm.replaceGeneratedBlock)({
80
+ current,
81
+ label: "prisma",
82
+ content: rendered
83
+ });
84
+ await ensureFileDirectory(outputPath2);
85
+ await (0, import_promises.writeFile)(outputPath2, next, "utf8");
86
+ return outputPath2;
87
+ }
88
+ if (target === "drizzle") {
89
+ const targetConfig2 = config.targets.drizzle;
90
+ if (!targetConfig2) {
91
+ throw new Error(`Target "${target}" is not configured.`);
92
+ }
93
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
94
+ await ensureFileDirectory(outputPath2);
95
+ await (0, import_promises.writeFile)(outputPath2, (0, import_orm.renderDrizzleSchema)(schema, targetConfig2), "utf8");
96
+ return outputPath2;
97
+ }
98
+ const targetConfig = config.targets.sql;
99
+ if (!targetConfig) {
100
+ throw new Error(`Target "${target}" is not configured.`);
101
+ }
102
+ const outputPath = import_node_path.default.resolve(process.cwd(), targetConfig.out);
103
+ await ensureFileDirectory(outputPath);
104
+ await (0, import_promises.writeFile)(outputPath, (0, import_orm.renderSafeSql)(schema, targetConfig), "utf8");
105
+ return outputPath;
106
+ }
107
+ async function checkTarget(target, configPath) {
108
+ const { config } = await loadConfig(configPath);
109
+ const schema = mergeSchemas(config.schemas);
110
+ if (target === "prisma") {
111
+ const targetConfig2 = config.targets.prisma;
112
+ if (!targetConfig2) {
113
+ throw new Error(`Target "${target}" is not configured.`);
114
+ }
115
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
116
+ const current2 = await readIfExists(outputPath2);
117
+ const next2 = targetConfig2.mode === "replace" || !current2.trim() ? (0, import_orm.renderPrismaSchema)(schema, targetConfig2) : (0, import_orm.replaceGeneratedBlock)({
118
+ current: current2,
119
+ label: "prisma",
120
+ content: (0, import_orm.renderPrismaSchema)(schema, targetConfig2)
121
+ });
122
+ return {
123
+ path: outputPath2,
124
+ matches: current2 === next2
125
+ };
126
+ }
127
+ if (target === "drizzle") {
128
+ const targetConfig2 = config.targets.drizzle;
129
+ if (!targetConfig2) {
130
+ throw new Error(`Target "${target}" is not configured.`);
131
+ }
132
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
133
+ const current2 = await readIfExists(outputPath2);
134
+ const next2 = (0, import_orm.renderDrizzleSchema)(schema, targetConfig2);
135
+ return {
136
+ path: outputPath2,
137
+ matches: current2 === next2
138
+ };
139
+ }
140
+ const targetConfig = config.targets.sql;
141
+ if (!targetConfig) {
142
+ throw new Error(`Target "${target}" is not configured.`);
143
+ }
144
+ const outputPath = import_node_path.default.resolve(process.cwd(), targetConfig.out);
145
+ const current = await readIfExists(outputPath);
146
+ const next = (0, import_orm.renderSafeSql)(schema, targetConfig);
147
+ return {
148
+ path: outputPath,
149
+ matches: current === next
150
+ };
151
+ }
152
+
153
+ // src/bin.ts
154
+ var program = new import_commander.Command();
155
+ program.name("farm-orm").description("Generate Prisma, Drizzle, or safe SQL artifacts from @farming-labs/orm schemas.");
156
+ program.command("generate").argument("<target>", "Target to generate: prisma, drizzle, or sql").option("-c, --config <path>", "Path to the farm-orm config file", "farm-orm.config.ts").action(async (target, options) => {
157
+ const outputPath = await generateTarget(target, options.config);
158
+ console.log(`Generated ${target} output at ${outputPath}`);
159
+ });
160
+ program.command("check").argument("<target>", "Target to validate: prisma, drizzle, or sql").option("-c, --config <path>", "Path to the farm-orm config file", "farm-orm.config.ts").action(async (target, options) => {
161
+ const result = await checkTarget(target, options.config);
162
+ if (!result.matches) {
163
+ console.error(`${target} output is out of date: ${result.path}`);
164
+ process.exitCode = 1;
165
+ return;
166
+ }
167
+ console.log(`${target} output is up to date.`);
168
+ });
169
+ program.parseAsync(process.argv);
170
+ //# sourceMappingURL=bin.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bin.ts","../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { checkTarget, generateTarget } from \"./index\";\n\nconst program = new Command();\n\nprogram\n .name(\"farm-orm\")\n .description(\"Generate Prisma, Drizzle, or safe SQL artifacts from @farming-labs/orm schemas.\");\n\nprogram\n .command(\"generate\")\n .argument(\"<target>\", \"Target to generate: prisma, drizzle, or sql\")\n .option(\"-c, --config <path>\", \"Path to the farm-orm config file\", \"farm-orm.config.ts\")\n .action(async (target: \"prisma\" | \"drizzle\" | \"sql\", options) => {\n const outputPath = await generateTarget(target, options.config);\n console.log(`Generated ${target} output at ${outputPath}`);\n });\n\nprogram\n .command(\"check\")\n .argument(\"<target>\", \"Target to validate: prisma, drizzle, or sql\")\n .option(\"-c, --config <path>\", \"Path to the farm-orm config file\", \"farm-orm.config.ts\")\n .action(async (target: \"prisma\" | \"drizzle\" | \"sql\", options) => {\n const result = await checkTarget(target, options.config);\n if (!result.matches) {\n console.error(`${target} output is out of date: ${result.path}`);\n process.exitCode = 1;\n return;\n }\n console.log(`${target} output is up to date.`);\n });\n\nprogram.parseAsync(process.argv);\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { createJiti } from \"jiti\";\nimport {\n replaceGeneratedBlock,\n renderDrizzleSchema,\n renderPrismaSchema,\n renderSafeSql,\n type DrizzleGenerationOptions,\n type PrismaGenerationOptions,\n type SchemaDefinition,\n type SqlGenerationOptions,\n} from \"@farming-labs/orm\";\n\nexport type FarmOrmConfig = {\n schemas: Array<SchemaDefinition<any>>;\n targets: {\n prisma?: PrismaGenerationOptions & {\n out: string;\n mode?: \"block\" | \"replace\";\n };\n drizzle?: DrizzleGenerationOptions & {\n out: string;\n };\n sql?: SqlGenerationOptions & {\n out: string;\n };\n };\n};\n\nexport function defineConfig(config: FarmOrmConfig) {\n return config;\n}\n\nexport async function loadConfig(configPath = \"farm-orm.config.ts\") {\n const absolutePath = path.resolve(process.cwd(), configPath);\n const jiti = createJiti(process.cwd());\n const mod = (await jiti.import(absolutePath)) as any;\n const config = (mod.default ?? mod) as FarmOrmConfig;\n\n if (!config?.schemas?.length) {\n throw new Error(`No schemas found in ${absolutePath}`);\n }\n\n return { absolutePath, config };\n}\n\nfunction mergeSchemas(schemas: Array<SchemaDefinition<any>>) {\n const models: Record<string, any> = {};\n for (const schema of schemas) {\n for (const [modelName, definition] of Object.entries(schema.models)) {\n if (models[modelName]) {\n throw new Error(`Duplicate model \"${modelName}\" detected while merging schemas.`);\n }\n models[modelName] = definition;\n }\n }\n return {\n _tag: \"schema\",\n models,\n } as SchemaDefinition<any>;\n}\n\nasync function ensureFileDirectory(filePath: string) {\n await mkdir(path.dirname(filePath), { recursive: true });\n}\n\nasync function readIfExists(filePath: string) {\n if (!existsSync(filePath)) return \"\";\n return readFile(filePath, \"utf8\");\n}\n\nexport async function generateTarget(target: keyof FarmOrmConfig[\"targets\"], configPath?: string) {\n const { config } = await loadConfig(configPath);\n const schema = mergeSchemas(config.schemas);\n\n if (target === \"prisma\") {\n const targetConfig = config.targets.prisma;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const rendered = renderPrismaSchema(schema, targetConfig);\n const mode = targetConfig.mode ?? \"block\";\n const current = await readIfExists(outputPath);\n const next =\n mode === \"replace\" || current.trim().length === 0\n ? rendered\n : replaceGeneratedBlock({\n current,\n label: \"prisma\",\n content: rendered,\n });\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, next, \"utf8\");\n return outputPath;\n }\n\n if (target === \"drizzle\") {\n const targetConfig = config.targets.drizzle;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, renderDrizzleSchema(schema, targetConfig), \"utf8\");\n return outputPath;\n }\n\n const targetConfig = config.targets.sql;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, renderSafeSql(schema, targetConfig), \"utf8\");\n return outputPath;\n}\n\nexport async function checkTarget(target: keyof FarmOrmConfig[\"targets\"], configPath?: string) {\n const { config } = await loadConfig(configPath);\n const schema = mergeSchemas(config.schemas);\n\n if (target === \"prisma\") {\n const targetConfig = config.targets.prisma;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next =\n targetConfig.mode === \"replace\" || !current.trim()\n ? renderPrismaSchema(schema, targetConfig)\n : replaceGeneratedBlock({\n current,\n label: \"prisma\",\n content: renderPrismaSchema(schema, targetConfig),\n });\n\n return {\n path: outputPath,\n matches: current === next,\n };\n }\n\n if (target === \"drizzle\") {\n const targetConfig = config.targets.drizzle;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next = renderDrizzleSchema(schema, targetConfig);\n return {\n path: outputPath,\n matches: current === next,\n };\n }\n\n const targetConfig = config.targets.sql;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next = renderSafeSql(schema, targetConfig);\n return {\n path: outputPath,\n matches: current === next,\n };\n}\n"],"mappings":"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","names":["path","targetConfig","outputPath","current","next"]}
package/dist/bin.d.cts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/bin.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/bin.js ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ checkTarget,
4
+ generateTarget
5
+ } from "./chunk-SXWQQY5L.js";
6
+
7
+ // src/bin.ts
8
+ import { Command } from "commander";
9
+ var program = new Command();
10
+ program.name("farm-orm").description("Generate Prisma, Drizzle, or safe SQL artifacts from @farming-labs/orm schemas.");
11
+ program.command("generate").argument("<target>", "Target to generate: prisma, drizzle, or sql").option("-c, --config <path>", "Path to the farm-orm config file", "farm-orm.config.ts").action(async (target, options) => {
12
+ const outputPath = await generateTarget(target, options.config);
13
+ console.log(`Generated ${target} output at ${outputPath}`);
14
+ });
15
+ program.command("check").argument("<target>", "Target to validate: prisma, drizzle, or sql").option("-c, --config <path>", "Path to the farm-orm config file", "farm-orm.config.ts").action(async (target, options) => {
16
+ const result = await checkTarget(target, options.config);
17
+ if (!result.matches) {
18
+ console.error(`${target} output is out of date: ${result.path}`);
19
+ process.exitCode = 1;
20
+ return;
21
+ }
22
+ console.log(`${target} output is up to date.`);
23
+ });
24
+ program.parseAsync(process.argv);
25
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { checkTarget, generateTarget } from \"./index\";\n\nconst program = new Command();\n\nprogram\n .name(\"farm-orm\")\n .description(\"Generate Prisma, Drizzle, or safe SQL artifacts from @farming-labs/orm schemas.\");\n\nprogram\n .command(\"generate\")\n .argument(\"<target>\", \"Target to generate: prisma, drizzle, or sql\")\n .option(\"-c, --config <path>\", \"Path to the farm-orm config file\", \"farm-orm.config.ts\")\n .action(async (target: \"prisma\" | \"drizzle\" | \"sql\", options) => {\n const outputPath = await generateTarget(target, options.config);\n console.log(`Generated ${target} output at ${outputPath}`);\n });\n\nprogram\n .command(\"check\")\n .argument(\"<target>\", \"Target to validate: prisma, drizzle, or sql\")\n .option(\"-c, --config <path>\", \"Path to the farm-orm config file\", \"farm-orm.config.ts\")\n .action(async (target: \"prisma\" | \"drizzle\" | \"sql\", options) => {\n const result = await checkTarget(target, options.config);\n if (!result.matches) {\n console.error(`${target} output is out of date: ${result.path}`);\n process.exitCode = 1;\n return;\n }\n console.log(`${target} output is up to date.`);\n });\n\nprogram.parseAsync(process.argv);\n"],"mappings":";;;;;;;AAEA,SAAS,eAAe;AAGxB,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,iFAAiF;AAEhG,QACG,QAAQ,UAAU,EAClB,SAAS,YAAY,6CAA6C,EAClE,OAAO,uBAAuB,oCAAoC,oBAAoB,EACtF,OAAO,OAAO,QAAsC,YAAY;AAC/D,QAAM,aAAa,MAAM,eAAe,QAAQ,QAAQ,MAAM;AAC9D,UAAQ,IAAI,aAAa,MAAM,cAAc,UAAU,EAAE;AAC3D,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,SAAS,YAAY,6CAA6C,EAClE,OAAO,uBAAuB,oCAAoC,oBAAoB,EACtF,OAAO,OAAO,QAAsC,YAAY;AAC/D,QAAM,SAAS,MAAM,YAAY,QAAQ,QAAQ,MAAM;AACvD,MAAI,CAAC,OAAO,SAAS;AACnB,YAAQ,MAAM,GAAG,MAAM,2BAA2B,OAAO,IAAI,EAAE;AAC/D,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,UAAQ,IAAI,GAAG,MAAM,wBAAwB;AAC/C,CAAC;AAEH,QAAQ,WAAW,QAAQ,IAAI;","names":[]}
@@ -0,0 +1,139 @@
1
+ // src/index.ts
2
+ import { mkdir, readFile, writeFile } from "fs/promises";
3
+ import { existsSync } from "fs";
4
+ import path from "path";
5
+ import { createJiti } from "jiti";
6
+ import {
7
+ replaceGeneratedBlock,
8
+ renderDrizzleSchema,
9
+ renderPrismaSchema,
10
+ renderSafeSql
11
+ } from "@farming-labs/orm";
12
+ function defineConfig(config) {
13
+ return config;
14
+ }
15
+ async function loadConfig(configPath = "farm-orm.config.ts") {
16
+ const absolutePath = path.resolve(process.cwd(), configPath);
17
+ const jiti = createJiti(process.cwd());
18
+ const mod = await jiti.import(absolutePath);
19
+ const config = mod.default ?? mod;
20
+ if (!config?.schemas?.length) {
21
+ throw new Error(`No schemas found in ${absolutePath}`);
22
+ }
23
+ return { absolutePath, config };
24
+ }
25
+ function mergeSchemas(schemas) {
26
+ const models = {};
27
+ for (const schema of schemas) {
28
+ for (const [modelName, definition] of Object.entries(schema.models)) {
29
+ if (models[modelName]) {
30
+ throw new Error(`Duplicate model "${modelName}" detected while merging schemas.`);
31
+ }
32
+ models[modelName] = definition;
33
+ }
34
+ }
35
+ return {
36
+ _tag: "schema",
37
+ models
38
+ };
39
+ }
40
+ async function ensureFileDirectory(filePath) {
41
+ await mkdir(path.dirname(filePath), { recursive: true });
42
+ }
43
+ async function readIfExists(filePath) {
44
+ if (!existsSync(filePath)) return "";
45
+ return readFile(filePath, "utf8");
46
+ }
47
+ async function generateTarget(target, configPath) {
48
+ const { config } = await loadConfig(configPath);
49
+ const schema = mergeSchemas(config.schemas);
50
+ if (target === "prisma") {
51
+ const targetConfig2 = config.targets.prisma;
52
+ if (!targetConfig2) {
53
+ throw new Error(`Target "${target}" is not configured.`);
54
+ }
55
+ const outputPath2 = path.resolve(process.cwd(), targetConfig2.out);
56
+ const rendered = renderPrismaSchema(schema, targetConfig2);
57
+ const mode = targetConfig2.mode ?? "block";
58
+ const current = await readIfExists(outputPath2);
59
+ const next = mode === "replace" || current.trim().length === 0 ? rendered : replaceGeneratedBlock({
60
+ current,
61
+ label: "prisma",
62
+ content: rendered
63
+ });
64
+ await ensureFileDirectory(outputPath2);
65
+ await writeFile(outputPath2, next, "utf8");
66
+ return outputPath2;
67
+ }
68
+ if (target === "drizzle") {
69
+ const targetConfig2 = config.targets.drizzle;
70
+ if (!targetConfig2) {
71
+ throw new Error(`Target "${target}" is not configured.`);
72
+ }
73
+ const outputPath2 = path.resolve(process.cwd(), targetConfig2.out);
74
+ await ensureFileDirectory(outputPath2);
75
+ await writeFile(outputPath2, renderDrizzleSchema(schema, targetConfig2), "utf8");
76
+ return outputPath2;
77
+ }
78
+ const targetConfig = config.targets.sql;
79
+ if (!targetConfig) {
80
+ throw new Error(`Target "${target}" is not configured.`);
81
+ }
82
+ const outputPath = path.resolve(process.cwd(), targetConfig.out);
83
+ await ensureFileDirectory(outputPath);
84
+ await writeFile(outputPath, renderSafeSql(schema, targetConfig), "utf8");
85
+ return outputPath;
86
+ }
87
+ async function checkTarget(target, configPath) {
88
+ const { config } = await loadConfig(configPath);
89
+ const schema = mergeSchemas(config.schemas);
90
+ if (target === "prisma") {
91
+ const targetConfig2 = config.targets.prisma;
92
+ if (!targetConfig2) {
93
+ throw new Error(`Target "${target}" is not configured.`);
94
+ }
95
+ const outputPath2 = path.resolve(process.cwd(), targetConfig2.out);
96
+ const current2 = await readIfExists(outputPath2);
97
+ const next2 = targetConfig2.mode === "replace" || !current2.trim() ? renderPrismaSchema(schema, targetConfig2) : replaceGeneratedBlock({
98
+ current: current2,
99
+ label: "prisma",
100
+ content: renderPrismaSchema(schema, targetConfig2)
101
+ });
102
+ return {
103
+ path: outputPath2,
104
+ matches: current2 === next2
105
+ };
106
+ }
107
+ if (target === "drizzle") {
108
+ const targetConfig2 = config.targets.drizzle;
109
+ if (!targetConfig2) {
110
+ throw new Error(`Target "${target}" is not configured.`);
111
+ }
112
+ const outputPath2 = path.resolve(process.cwd(), targetConfig2.out);
113
+ const current2 = await readIfExists(outputPath2);
114
+ const next2 = renderDrizzleSchema(schema, targetConfig2);
115
+ return {
116
+ path: outputPath2,
117
+ matches: current2 === next2
118
+ };
119
+ }
120
+ const targetConfig = config.targets.sql;
121
+ if (!targetConfig) {
122
+ throw new Error(`Target "${target}" is not configured.`);
123
+ }
124
+ const outputPath = path.resolve(process.cwd(), targetConfig.out);
125
+ const current = await readIfExists(outputPath);
126
+ const next = renderSafeSql(schema, targetConfig);
127
+ return {
128
+ path: outputPath,
129
+ matches: current === next
130
+ };
131
+ }
132
+
133
+ export {
134
+ defineConfig,
135
+ loadConfig,
136
+ generateTarget,
137
+ checkTarget
138
+ };
139
+ //# sourceMappingURL=chunk-SXWQQY5L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { createJiti } from \"jiti\";\nimport {\n replaceGeneratedBlock,\n renderDrizzleSchema,\n renderPrismaSchema,\n renderSafeSql,\n type DrizzleGenerationOptions,\n type PrismaGenerationOptions,\n type SchemaDefinition,\n type SqlGenerationOptions,\n} from \"@farming-labs/orm\";\n\nexport type FarmOrmConfig = {\n schemas: Array<SchemaDefinition<any>>;\n targets: {\n prisma?: PrismaGenerationOptions & {\n out: string;\n mode?: \"block\" | \"replace\";\n };\n drizzle?: DrizzleGenerationOptions & {\n out: string;\n };\n sql?: SqlGenerationOptions & {\n out: string;\n };\n };\n};\n\nexport function defineConfig(config: FarmOrmConfig) {\n return config;\n}\n\nexport async function loadConfig(configPath = \"farm-orm.config.ts\") {\n const absolutePath = path.resolve(process.cwd(), configPath);\n const jiti = createJiti(process.cwd());\n const mod = (await jiti.import(absolutePath)) as any;\n const config = (mod.default ?? mod) as FarmOrmConfig;\n\n if (!config?.schemas?.length) {\n throw new Error(`No schemas found in ${absolutePath}`);\n }\n\n return { absolutePath, config };\n}\n\nfunction mergeSchemas(schemas: Array<SchemaDefinition<any>>) {\n const models: Record<string, any> = {};\n for (const schema of schemas) {\n for (const [modelName, definition] of Object.entries(schema.models)) {\n if (models[modelName]) {\n throw new Error(`Duplicate model \"${modelName}\" detected while merging schemas.`);\n }\n models[modelName] = definition;\n }\n }\n return {\n _tag: \"schema\",\n models,\n } as SchemaDefinition<any>;\n}\n\nasync function ensureFileDirectory(filePath: string) {\n await mkdir(path.dirname(filePath), { recursive: true });\n}\n\nasync function readIfExists(filePath: string) {\n if (!existsSync(filePath)) return \"\";\n return readFile(filePath, \"utf8\");\n}\n\nexport async function generateTarget(target: keyof FarmOrmConfig[\"targets\"], configPath?: string) {\n const { config } = await loadConfig(configPath);\n const schema = mergeSchemas(config.schemas);\n\n if (target === \"prisma\") {\n const targetConfig = config.targets.prisma;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const rendered = renderPrismaSchema(schema, targetConfig);\n const mode = targetConfig.mode ?? \"block\";\n const current = await readIfExists(outputPath);\n const next =\n mode === \"replace\" || current.trim().length === 0\n ? rendered\n : replaceGeneratedBlock({\n current,\n label: \"prisma\",\n content: rendered,\n });\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, next, \"utf8\");\n return outputPath;\n }\n\n if (target === \"drizzle\") {\n const targetConfig = config.targets.drizzle;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, renderDrizzleSchema(schema, targetConfig), \"utf8\");\n return outputPath;\n }\n\n const targetConfig = config.targets.sql;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, renderSafeSql(schema, targetConfig), \"utf8\");\n return outputPath;\n}\n\nexport async function checkTarget(target: keyof FarmOrmConfig[\"targets\"], configPath?: string) {\n const { config } = await loadConfig(configPath);\n const schema = mergeSchemas(config.schemas);\n\n if (target === \"prisma\") {\n const targetConfig = config.targets.prisma;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next =\n targetConfig.mode === \"replace\" || !current.trim()\n ? renderPrismaSchema(schema, targetConfig)\n : replaceGeneratedBlock({\n current,\n label: \"prisma\",\n content: renderPrismaSchema(schema, targetConfig),\n });\n\n return {\n path: outputPath,\n matches: current === next,\n };\n }\n\n if (target === \"drizzle\") {\n const targetConfig = config.targets.drizzle;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next = renderDrizzleSchema(schema, targetConfig);\n return {\n path: outputPath,\n matches: current === next,\n };\n }\n\n const targetConfig = config.targets.sql;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next = renderSafeSql(schema, targetConfig);\n return {\n path: outputPath,\n matches: current === next,\n };\n}\n"],"mappings":"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","names":["targetConfig","outputPath","current","next"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ checkTarget: () => checkTarget,
34
+ defineConfig: () => defineConfig,
35
+ generateTarget: () => generateTarget,
36
+ loadConfig: () => loadConfig
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+ var import_promises = require("fs/promises");
40
+ var import_node_fs = require("fs");
41
+ var import_node_path = __toESM(require("path"), 1);
42
+ var import_jiti = require("jiti");
43
+ var import_orm = require("@farming-labs/orm");
44
+ function defineConfig(config) {
45
+ return config;
46
+ }
47
+ async function loadConfig(configPath = "farm-orm.config.ts") {
48
+ const absolutePath = import_node_path.default.resolve(process.cwd(), configPath);
49
+ const jiti = (0, import_jiti.createJiti)(process.cwd());
50
+ const mod = await jiti.import(absolutePath);
51
+ const config = mod.default ?? mod;
52
+ if (!config?.schemas?.length) {
53
+ throw new Error(`No schemas found in ${absolutePath}`);
54
+ }
55
+ return { absolutePath, config };
56
+ }
57
+ function mergeSchemas(schemas) {
58
+ const models = {};
59
+ for (const schema of schemas) {
60
+ for (const [modelName, definition] of Object.entries(schema.models)) {
61
+ if (models[modelName]) {
62
+ throw new Error(`Duplicate model "${modelName}" detected while merging schemas.`);
63
+ }
64
+ models[modelName] = definition;
65
+ }
66
+ }
67
+ return {
68
+ _tag: "schema",
69
+ models
70
+ };
71
+ }
72
+ async function ensureFileDirectory(filePath) {
73
+ await (0, import_promises.mkdir)(import_node_path.default.dirname(filePath), { recursive: true });
74
+ }
75
+ async function readIfExists(filePath) {
76
+ if (!(0, import_node_fs.existsSync)(filePath)) return "";
77
+ return (0, import_promises.readFile)(filePath, "utf8");
78
+ }
79
+ async function generateTarget(target, configPath) {
80
+ const { config } = await loadConfig(configPath);
81
+ const schema = mergeSchemas(config.schemas);
82
+ if (target === "prisma") {
83
+ const targetConfig2 = config.targets.prisma;
84
+ if (!targetConfig2) {
85
+ throw new Error(`Target "${target}" is not configured.`);
86
+ }
87
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
88
+ const rendered = (0, import_orm.renderPrismaSchema)(schema, targetConfig2);
89
+ const mode = targetConfig2.mode ?? "block";
90
+ const current = await readIfExists(outputPath2);
91
+ const next = mode === "replace" || current.trim().length === 0 ? rendered : (0, import_orm.replaceGeneratedBlock)({
92
+ current,
93
+ label: "prisma",
94
+ content: rendered
95
+ });
96
+ await ensureFileDirectory(outputPath2);
97
+ await (0, import_promises.writeFile)(outputPath2, next, "utf8");
98
+ return outputPath2;
99
+ }
100
+ if (target === "drizzle") {
101
+ const targetConfig2 = config.targets.drizzle;
102
+ if (!targetConfig2) {
103
+ throw new Error(`Target "${target}" is not configured.`);
104
+ }
105
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
106
+ await ensureFileDirectory(outputPath2);
107
+ await (0, import_promises.writeFile)(outputPath2, (0, import_orm.renderDrizzleSchema)(schema, targetConfig2), "utf8");
108
+ return outputPath2;
109
+ }
110
+ const targetConfig = config.targets.sql;
111
+ if (!targetConfig) {
112
+ throw new Error(`Target "${target}" is not configured.`);
113
+ }
114
+ const outputPath = import_node_path.default.resolve(process.cwd(), targetConfig.out);
115
+ await ensureFileDirectory(outputPath);
116
+ await (0, import_promises.writeFile)(outputPath, (0, import_orm.renderSafeSql)(schema, targetConfig), "utf8");
117
+ return outputPath;
118
+ }
119
+ async function checkTarget(target, configPath) {
120
+ const { config } = await loadConfig(configPath);
121
+ const schema = mergeSchemas(config.schemas);
122
+ if (target === "prisma") {
123
+ const targetConfig2 = config.targets.prisma;
124
+ if (!targetConfig2) {
125
+ throw new Error(`Target "${target}" is not configured.`);
126
+ }
127
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
128
+ const current2 = await readIfExists(outputPath2);
129
+ const next2 = targetConfig2.mode === "replace" || !current2.trim() ? (0, import_orm.renderPrismaSchema)(schema, targetConfig2) : (0, import_orm.replaceGeneratedBlock)({
130
+ current: current2,
131
+ label: "prisma",
132
+ content: (0, import_orm.renderPrismaSchema)(schema, targetConfig2)
133
+ });
134
+ return {
135
+ path: outputPath2,
136
+ matches: current2 === next2
137
+ };
138
+ }
139
+ if (target === "drizzle") {
140
+ const targetConfig2 = config.targets.drizzle;
141
+ if (!targetConfig2) {
142
+ throw new Error(`Target "${target}" is not configured.`);
143
+ }
144
+ const outputPath2 = import_node_path.default.resolve(process.cwd(), targetConfig2.out);
145
+ const current2 = await readIfExists(outputPath2);
146
+ const next2 = (0, import_orm.renderDrizzleSchema)(schema, targetConfig2);
147
+ return {
148
+ path: outputPath2,
149
+ matches: current2 === next2
150
+ };
151
+ }
152
+ const targetConfig = config.targets.sql;
153
+ if (!targetConfig) {
154
+ throw new Error(`Target "${target}" is not configured.`);
155
+ }
156
+ const outputPath = import_node_path.default.resolve(process.cwd(), targetConfig.out);
157
+ const current = await readIfExists(outputPath);
158
+ const next = (0, import_orm.renderSafeSql)(schema, targetConfig);
159
+ return {
160
+ path: outputPath,
161
+ matches: current === next
162
+ };
163
+ }
164
+ // Annotate the CommonJS export names for ESM import in node:
165
+ 0 && (module.exports = {
166
+ checkTarget,
167
+ defineConfig,
168
+ generateTarget,
169
+ loadConfig
170
+ });
171
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { createJiti } from \"jiti\";\nimport {\n replaceGeneratedBlock,\n renderDrizzleSchema,\n renderPrismaSchema,\n renderSafeSql,\n type DrizzleGenerationOptions,\n type PrismaGenerationOptions,\n type SchemaDefinition,\n type SqlGenerationOptions,\n} from \"@farming-labs/orm\";\n\nexport type FarmOrmConfig = {\n schemas: Array<SchemaDefinition<any>>;\n targets: {\n prisma?: PrismaGenerationOptions & {\n out: string;\n mode?: \"block\" | \"replace\";\n };\n drizzle?: DrizzleGenerationOptions & {\n out: string;\n };\n sql?: SqlGenerationOptions & {\n out: string;\n };\n };\n};\n\nexport function defineConfig(config: FarmOrmConfig) {\n return config;\n}\n\nexport async function loadConfig(configPath = \"farm-orm.config.ts\") {\n const absolutePath = path.resolve(process.cwd(), configPath);\n const jiti = createJiti(process.cwd());\n const mod = (await jiti.import(absolutePath)) as any;\n const config = (mod.default ?? mod) as FarmOrmConfig;\n\n if (!config?.schemas?.length) {\n throw new Error(`No schemas found in ${absolutePath}`);\n }\n\n return { absolutePath, config };\n}\n\nfunction mergeSchemas(schemas: Array<SchemaDefinition<any>>) {\n const models: Record<string, any> = {};\n for (const schema of schemas) {\n for (const [modelName, definition] of Object.entries(schema.models)) {\n if (models[modelName]) {\n throw new Error(`Duplicate model \"${modelName}\" detected while merging schemas.`);\n }\n models[modelName] = definition;\n }\n }\n return {\n _tag: \"schema\",\n models,\n } as SchemaDefinition<any>;\n}\n\nasync function ensureFileDirectory(filePath: string) {\n await mkdir(path.dirname(filePath), { recursive: true });\n}\n\nasync function readIfExists(filePath: string) {\n if (!existsSync(filePath)) return \"\";\n return readFile(filePath, \"utf8\");\n}\n\nexport async function generateTarget(target: keyof FarmOrmConfig[\"targets\"], configPath?: string) {\n const { config } = await loadConfig(configPath);\n const schema = mergeSchemas(config.schemas);\n\n if (target === \"prisma\") {\n const targetConfig = config.targets.prisma;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const rendered = renderPrismaSchema(schema, targetConfig);\n const mode = targetConfig.mode ?? \"block\";\n const current = await readIfExists(outputPath);\n const next =\n mode === \"replace\" || current.trim().length === 0\n ? rendered\n : replaceGeneratedBlock({\n current,\n label: \"prisma\",\n content: rendered,\n });\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, next, \"utf8\");\n return outputPath;\n }\n\n if (target === \"drizzle\") {\n const targetConfig = config.targets.drizzle;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, renderDrizzleSchema(schema, targetConfig), \"utf8\");\n return outputPath;\n }\n\n const targetConfig = config.targets.sql;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n await ensureFileDirectory(outputPath);\n await writeFile(outputPath, renderSafeSql(schema, targetConfig), \"utf8\");\n return outputPath;\n}\n\nexport async function checkTarget(target: keyof FarmOrmConfig[\"targets\"], configPath?: string) {\n const { config } = await loadConfig(configPath);\n const schema = mergeSchemas(config.schemas);\n\n if (target === \"prisma\") {\n const targetConfig = config.targets.prisma;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next =\n targetConfig.mode === \"replace\" || !current.trim()\n ? renderPrismaSchema(schema, targetConfig)\n : replaceGeneratedBlock({\n current,\n label: \"prisma\",\n content: renderPrismaSchema(schema, targetConfig),\n });\n\n return {\n path: outputPath,\n matches: current === next,\n };\n }\n\n if (target === \"drizzle\") {\n const targetConfig = config.targets.drizzle;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next = renderDrizzleSchema(schema, targetConfig);\n return {\n path: outputPath,\n matches: current === next,\n };\n }\n\n const targetConfig = config.targets.sql;\n if (!targetConfig) {\n throw new Error(`Target \"${target}\" is not configured.`);\n }\n const outputPath = path.resolve(process.cwd(), targetConfig.out);\n const current = await readIfExists(outputPath);\n const next = renderSafeSql(schema, targetConfig);\n return {\n path: outputPath,\n matches: current === next,\n };\n}\n"],"mappings":"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","names":["path","targetConfig","outputPath","current","next"]}
@@ -0,0 +1,29 @@
1
+ import { SchemaDefinition, PrismaGenerationOptions, DrizzleGenerationOptions, SqlGenerationOptions } from '@farming-labs/orm';
2
+
3
+ type FarmOrmConfig = {
4
+ schemas: Array<SchemaDefinition<any>>;
5
+ targets: {
6
+ prisma?: PrismaGenerationOptions & {
7
+ out: string;
8
+ mode?: "block" | "replace";
9
+ };
10
+ drizzle?: DrizzleGenerationOptions & {
11
+ out: string;
12
+ };
13
+ sql?: SqlGenerationOptions & {
14
+ out: string;
15
+ };
16
+ };
17
+ };
18
+ declare function defineConfig(config: FarmOrmConfig): FarmOrmConfig;
19
+ declare function loadConfig(configPath?: string): Promise<{
20
+ absolutePath: string;
21
+ config: FarmOrmConfig;
22
+ }>;
23
+ declare function generateTarget(target: keyof FarmOrmConfig["targets"], configPath?: string): Promise<string>;
24
+ declare function checkTarget(target: keyof FarmOrmConfig["targets"], configPath?: string): Promise<{
25
+ path: string;
26
+ matches: boolean;
27
+ }>;
28
+
29
+ export { type FarmOrmConfig, checkTarget, defineConfig, generateTarget, loadConfig };
@@ -0,0 +1,29 @@
1
+ import { SchemaDefinition, PrismaGenerationOptions, DrizzleGenerationOptions, SqlGenerationOptions } from '@farming-labs/orm';
2
+
3
+ type FarmOrmConfig = {
4
+ schemas: Array<SchemaDefinition<any>>;
5
+ targets: {
6
+ prisma?: PrismaGenerationOptions & {
7
+ out: string;
8
+ mode?: "block" | "replace";
9
+ };
10
+ drizzle?: DrizzleGenerationOptions & {
11
+ out: string;
12
+ };
13
+ sql?: SqlGenerationOptions & {
14
+ out: string;
15
+ };
16
+ };
17
+ };
18
+ declare function defineConfig(config: FarmOrmConfig): FarmOrmConfig;
19
+ declare function loadConfig(configPath?: string): Promise<{
20
+ absolutePath: string;
21
+ config: FarmOrmConfig;
22
+ }>;
23
+ declare function generateTarget(target: keyof FarmOrmConfig["targets"], configPath?: string): Promise<string>;
24
+ declare function checkTarget(target: keyof FarmOrmConfig["targets"], configPath?: string): Promise<{
25
+ path: string;
26
+ matches: boolean;
27
+ }>;
28
+
29
+ export { type FarmOrmConfig, checkTarget, defineConfig, generateTarget, loadConfig };
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import {
2
+ checkTarget,
3
+ defineConfig,
4
+ generateTarget,
5
+ loadConfig
6
+ } from "./chunk-SXWQQY5L.js";
7
+ export {
8
+ checkTarget,
9
+ defineConfig,
10
+ generateTarget,
11
+ loadConfig
12
+ };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@farming-labs/orm-cli",
3
+ "version": "0.0.1",
4
+ "bin": {
5
+ "farm-orm": "./dist/bin.js"
6
+ },
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "type": "module",
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "require": "./dist/index.cjs"
19
+ }
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "dependencies": {
25
+ "commander": "^13.1.0",
26
+ "jiti": "^2.4.2",
27
+ "@farming-labs/orm": "0.0.1"
28
+ },
29
+ "devDependencies": {
30
+ "tsup": "^8.4.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsx ./scripts/build.ts",
34
+ "test": "pnpm --filter @farming-labs/orm build && vitest run",
35
+ "typecheck": "tsc --noEmit"
36
+ }
37
+ }