@mesob/pg 0.2.0
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.d.ts +2 -0
- package/dist/cli.js +132 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
5
|
+
import yargs from "yargs";
|
|
6
|
+
import { hideBin } from "yargs/helpers";
|
|
7
|
+
|
|
8
|
+
// src/config.ts
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
var aiReviewConfigSchema = z.object({
|
|
11
|
+
apiKey: z.string(),
|
|
12
|
+
model: z.string().optional()
|
|
13
|
+
});
|
|
14
|
+
var configSchema = z.object({
|
|
15
|
+
source: z.string().describe("Source database connection string"),
|
|
16
|
+
destination: z.string().describe("Destination database connection string"),
|
|
17
|
+
schemas: z.array(z.string()).optional().describe("Schemas to include"),
|
|
18
|
+
include: z.array(z.string()).optional().describe("Object patterns to include"),
|
|
19
|
+
exclude: z.array(z.string()).optional().describe("Object patterns to exclude"),
|
|
20
|
+
mode: z.enum(["safe", "strict"]).optional().default("safe").describe("Diff mode"),
|
|
21
|
+
aiReview: aiReviewConfigSchema.optional().describe("AI review configuration")
|
|
22
|
+
});
|
|
23
|
+
function parseConfig(input) {
|
|
24
|
+
return configSchema.parse(input);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/lib/differ.ts
|
|
28
|
+
import { run } from "@pgkit/migra";
|
|
29
|
+
async function diffSchemas(input) {
|
|
30
|
+
const { source, destination, options } = input;
|
|
31
|
+
const migration = await run(destination, source, {
|
|
32
|
+
unsafe: options?.mode === "strict",
|
|
33
|
+
schema: options?.schemas?.[0],
|
|
34
|
+
excludeSchema: options?.exclude,
|
|
35
|
+
withPrivileges: true
|
|
36
|
+
});
|
|
37
|
+
const sql = migration.sql;
|
|
38
|
+
return {
|
|
39
|
+
sql,
|
|
40
|
+
isEmpty: !sql.trim()
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/cli.ts
|
|
45
|
+
async function main() {
|
|
46
|
+
const argv = await yargs(hideBin(process.argv)).scriptName("mesob-pg").usage("$0 <command> [options]").command(
|
|
47
|
+
"diff",
|
|
48
|
+
"Generate SQL diff between two PostgreSQL databases",
|
|
49
|
+
(y) => y.option("source", {
|
|
50
|
+
alias: "s",
|
|
51
|
+
type: "string",
|
|
52
|
+
describe: "Source database connection string"
|
|
53
|
+
}).option("dest", {
|
|
54
|
+
alias: "d",
|
|
55
|
+
type: "string",
|
|
56
|
+
describe: "Destination database connection string"
|
|
57
|
+
}).option("config", {
|
|
58
|
+
alias: "c",
|
|
59
|
+
type: "string",
|
|
60
|
+
describe: "Path to db.config.json"
|
|
61
|
+
}).option("mode", {
|
|
62
|
+
alias: "m",
|
|
63
|
+
type: "string",
|
|
64
|
+
choices: ["safe", "strict"],
|
|
65
|
+
default: "safe",
|
|
66
|
+
describe: "Diff mode (safe=no destructive, strict=full sync)"
|
|
67
|
+
}).option("schema", {
|
|
68
|
+
type: "array",
|
|
69
|
+
string: true,
|
|
70
|
+
describe: "Schemas to include (can specify multiple)"
|
|
71
|
+
}).option("include", {
|
|
72
|
+
type: "array",
|
|
73
|
+
string: true,
|
|
74
|
+
describe: "Object patterns to include"
|
|
75
|
+
}).option("exclude", {
|
|
76
|
+
type: "array",
|
|
77
|
+
string: true,
|
|
78
|
+
describe: "Object patterns to exclude"
|
|
79
|
+
}).option("out", {
|
|
80
|
+
alias: "o",
|
|
81
|
+
type: "string",
|
|
82
|
+
describe: "Output file path (default: stdout)"
|
|
83
|
+
}).check((args) => {
|
|
84
|
+
if (!(args.config || args.source && args.dest)) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
"Either --config or both --source and --dest required"
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
})
|
|
91
|
+
).demandCommand(1, "You need to specify a command").strict().help().parse();
|
|
92
|
+
const command = argv._[0];
|
|
93
|
+
if (command === "diff") {
|
|
94
|
+
let source;
|
|
95
|
+
let dest;
|
|
96
|
+
let mode = argv.mode || "safe";
|
|
97
|
+
let schemas = argv.schema;
|
|
98
|
+
let exclude = argv.exclude;
|
|
99
|
+
if (argv.config) {
|
|
100
|
+
const configText = readFileSync(argv.config, "utf-8");
|
|
101
|
+
const config = parseConfig(JSON.parse(configText));
|
|
102
|
+
source = config.source;
|
|
103
|
+
dest = config.destination;
|
|
104
|
+
mode = config.mode || mode;
|
|
105
|
+
schemas = config.schemas || schemas;
|
|
106
|
+
exclude = config.exclude || exclude;
|
|
107
|
+
} else {
|
|
108
|
+
source = argv.source;
|
|
109
|
+
dest = argv.dest;
|
|
110
|
+
}
|
|
111
|
+
const result = await diffSchemas({
|
|
112
|
+
source,
|
|
113
|
+
destination: dest,
|
|
114
|
+
options: { mode, schemas, exclude }
|
|
115
|
+
});
|
|
116
|
+
if (result.isEmpty) {
|
|
117
|
+
process.stderr.write("No differences found.\n");
|
|
118
|
+
} else if (argv.out) {
|
|
119
|
+
writeFileSync(argv.out, result.sql, "utf-8");
|
|
120
|
+
process.stderr.write(`Wrote ${argv.out}
|
|
121
|
+
`);
|
|
122
|
+
} else {
|
|
123
|
+
process.stdout.write(result.sql);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
main().catch((err) => {
|
|
128
|
+
process.stderr.write(`Error: ${err.message}
|
|
129
|
+
`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/config.ts","../src/lib/differ.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { parseConfig } from './config';\nimport { diffSchemas } from './lib/differ';\nimport type { DiffMode } from './types';\n\ntype DiffArgs = {\n source?: string;\n dest?: string;\n config?: string;\n mode: DiffMode;\n schema?: string[];\n include?: string[];\n exclude?: string[];\n out?: string;\n _: (string | number)[];\n};\n\nasync function main() {\n const argv = (await yargs(hideBin(process.argv))\n .scriptName('mesob-pg')\n .usage('$0 <command> [options]')\n .command(\n 'diff',\n 'Generate SQL diff between two PostgreSQL databases',\n (y) =>\n y\n .option('source', {\n alias: 's',\n type: 'string',\n describe: 'Source database connection string',\n })\n .option('dest', {\n alias: 'd',\n type: 'string',\n describe: 'Destination database connection string',\n })\n .option('config', {\n alias: 'c',\n type: 'string',\n describe: 'Path to db.config.json',\n })\n .option('mode', {\n alias: 'm',\n type: 'string',\n choices: ['safe', 'strict'] as const,\n default: 'safe' as DiffMode,\n describe: 'Diff mode (safe=no destructive, strict=full sync)',\n })\n .option('schema', {\n type: 'array',\n string: true,\n describe: 'Schemas to include (can specify multiple)',\n })\n .option('include', {\n type: 'array',\n string: true,\n describe: 'Object patterns to include',\n })\n .option('exclude', {\n type: 'array',\n string: true,\n describe: 'Object patterns to exclude',\n })\n .option('out', {\n alias: 'o',\n type: 'string',\n describe: 'Output file path (default: stdout)',\n })\n .check((args) => {\n if (!(args.config || (args.source && args.dest))) {\n throw new Error(\n 'Either --config or both --source and --dest required',\n );\n }\n return true;\n }),\n )\n .demandCommand(1, 'You need to specify a command')\n .strict()\n .help()\n .parse()) as unknown as DiffArgs;\n\n const command = argv._[0];\n\n if (command === 'diff') {\n let source: string;\n let dest: string;\n let mode: DiffMode = argv.mode || 'safe';\n let schemas: string[] | undefined = argv.schema;\n let exclude: string[] | undefined = argv.exclude;\n\n if (argv.config) {\n const configText = readFileSync(argv.config, 'utf-8');\n const config = parseConfig(JSON.parse(configText));\n source = config.source;\n dest = config.destination;\n mode = config.mode || mode;\n schemas = config.schemas || schemas;\n exclude = config.exclude || exclude;\n } else {\n source = argv.source as string;\n dest = argv.dest as string;\n }\n\n const result = await diffSchemas({\n source,\n destination: dest,\n options: { mode, schemas, exclude },\n });\n\n if (result.isEmpty) {\n process.stderr.write('No differences found.\\n');\n } else if (argv.out) {\n writeFileSync(argv.out, result.sql, 'utf-8');\n process.stderr.write(`Wrote ${argv.out}\\n`);\n } else {\n process.stdout.write(result.sql);\n }\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(`Error: ${err.message}\\n`);\n process.exit(1);\n});\n","import { z } from 'zod';\nimport type { PgConfig } from './types';\n\nexport const aiReviewConfigSchema = z.object({\n apiKey: z.string(),\n model: z.string().optional(),\n});\n\nexport const configSchema = z.object({\n source: z.string().describe('Source database connection string'),\n destination: z.string().describe('Destination database connection string'),\n schemas: z.array(z.string()).optional().describe('Schemas to include'),\n include: z\n .array(z.string())\n .optional()\n .describe('Object patterns to include'),\n exclude: z\n .array(z.string())\n .optional()\n .describe('Object patterns to exclude'),\n mode: z\n .enum(['safe', 'strict'])\n .optional()\n .default('safe')\n .describe('Diff mode'),\n aiReview: aiReviewConfigSchema.optional().describe('AI review configuration'),\n});\n\nexport function parseConfig(input: unknown): PgConfig {\n return configSchema.parse(input);\n}\n\nexport function validateConfig(input: unknown): {\n success: boolean;\n data?: PgConfig;\n error?: z.ZodError;\n} {\n const result = configSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as PgConfig };\n }\n return { success: false, error: result.error };\n}\n","import { run } from '@pgkit/migra';\nimport type { DiffOptions } from '../types';\n\nexport type DiffSchemasInput = {\n source: string;\n destination: string;\n options?: DiffOptions;\n};\n\nexport type DiffOutput = {\n sql: string;\n isEmpty: boolean;\n};\n\n/**\n * Diff two PostgreSQL database schemas using @pgkit/migra.\n * Returns SQL to transform destination to match source.\n */\nexport async function diffSchemas(\n input: DiffSchemasInput,\n): Promise<DiffOutput> {\n const { source, destination, options } = input;\n\n const migration = await run(destination, source, {\n unsafe: options?.mode === 'strict',\n schema: options?.schemas?.[0],\n excludeSchema: options?.exclude,\n withPrivileges: true,\n });\n\n const sql = migration.sql;\n\n return {\n sql,\n isEmpty: !sql.trim(),\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export { Migration, run as runMigra } from '@pgkit/migra';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
type DiffMode = 'safe' | 'strict';
|
|
5
|
+
type DiffOptions = {
|
|
6
|
+
mode: DiffMode;
|
|
7
|
+
schemas?: string[];
|
|
8
|
+
include?: string[];
|
|
9
|
+
exclude?: string[];
|
|
10
|
+
};
|
|
11
|
+
type AiReviewConfig = {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
};
|
|
15
|
+
type PgConfig = {
|
|
16
|
+
source: string;
|
|
17
|
+
destination: string;
|
|
18
|
+
schemas?: string[];
|
|
19
|
+
include?: string[];
|
|
20
|
+
exclude?: string[];
|
|
21
|
+
mode?: DiffMode;
|
|
22
|
+
aiReview?: AiReviewConfig;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
declare const configSchema: z.ZodObject<{
|
|
26
|
+
source: z.ZodString;
|
|
27
|
+
destination: z.ZodString;
|
|
28
|
+
schemas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
29
|
+
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
30
|
+
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
31
|
+
mode: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
safe: "safe";
|
|
33
|
+
strict: "strict";
|
|
34
|
+
}>>>;
|
|
35
|
+
aiReview: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
apiKey: z.ZodString;
|
|
37
|
+
model: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
declare function parseConfig(input: unknown): PgConfig;
|
|
41
|
+
declare function validateConfig(input: unknown): {
|
|
42
|
+
success: boolean;
|
|
43
|
+
data?: PgConfig;
|
|
44
|
+
error?: z.ZodError;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Placeholder for AI review functionality.
|
|
49
|
+
* Will use OpenAI SDK to review and improve generated SQL.
|
|
50
|
+
*/
|
|
51
|
+
declare function reviewSqlWithAi(input: {
|
|
52
|
+
sql: string;
|
|
53
|
+
config: AiReviewConfig;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
reviewed: string;
|
|
56
|
+
suggestions: string[];
|
|
57
|
+
}>;
|
|
58
|
+
|
|
59
|
+
type DiffSchemasInput = {
|
|
60
|
+
source: string;
|
|
61
|
+
destination: string;
|
|
62
|
+
options?: DiffOptions;
|
|
63
|
+
};
|
|
64
|
+
type DiffOutput = {
|
|
65
|
+
sql: string;
|
|
66
|
+
isEmpty: boolean;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Diff two PostgreSQL database schemas using @pgkit/migra.
|
|
70
|
+
* Returns SQL to transform destination to match source.
|
|
71
|
+
*/
|
|
72
|
+
declare function diffSchemas(input: DiffSchemasInput): Promise<DiffOutput>;
|
|
73
|
+
|
|
74
|
+
export { type AiReviewConfig, type DiffMode, type DiffOptions, type DiffOutput, type PgConfig, configSchema, diffSchemas, parseConfig, reviewSqlWithAi, validateConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { Migration, run as run2 } from "@pgkit/migra";
|
|
3
|
+
|
|
4
|
+
// src/config.ts
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
var aiReviewConfigSchema = z.object({
|
|
7
|
+
apiKey: z.string(),
|
|
8
|
+
model: z.string().optional()
|
|
9
|
+
});
|
|
10
|
+
var configSchema = z.object({
|
|
11
|
+
source: z.string().describe("Source database connection string"),
|
|
12
|
+
destination: z.string().describe("Destination database connection string"),
|
|
13
|
+
schemas: z.array(z.string()).optional().describe("Schemas to include"),
|
|
14
|
+
include: z.array(z.string()).optional().describe("Object patterns to include"),
|
|
15
|
+
exclude: z.array(z.string()).optional().describe("Object patterns to exclude"),
|
|
16
|
+
mode: z.enum(["safe", "strict"]).optional().default("safe").describe("Diff mode"),
|
|
17
|
+
aiReview: aiReviewConfigSchema.optional().describe("AI review configuration")
|
|
18
|
+
});
|
|
19
|
+
function parseConfig(input) {
|
|
20
|
+
return configSchema.parse(input);
|
|
21
|
+
}
|
|
22
|
+
function validateConfig(input) {
|
|
23
|
+
const result = configSchema.safeParse(input);
|
|
24
|
+
if (result.success) {
|
|
25
|
+
return { success: true, data: result.data };
|
|
26
|
+
}
|
|
27
|
+
return { success: false, error: result.error };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/lib/ai-review.ts
|
|
31
|
+
function reviewSqlWithAi(input) {
|
|
32
|
+
const { sql, config: _config } = input;
|
|
33
|
+
return Promise.resolve({
|
|
34
|
+
reviewed: sql,
|
|
35
|
+
suggestions: [
|
|
36
|
+
"AI review not yet implemented. Add openai dependency and implement reviewSqlWithAi()."
|
|
37
|
+
]
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/lib/differ.ts
|
|
42
|
+
import { run } from "@pgkit/migra";
|
|
43
|
+
async function diffSchemas(input) {
|
|
44
|
+
const { source, destination, options } = input;
|
|
45
|
+
const migration = await run(destination, source, {
|
|
46
|
+
unsafe: options?.mode === "strict",
|
|
47
|
+
schema: options?.schemas?.[0],
|
|
48
|
+
excludeSchema: options?.exclude,
|
|
49
|
+
withPrivileges: true
|
|
50
|
+
});
|
|
51
|
+
const sql = migration.sql;
|
|
52
|
+
return {
|
|
53
|
+
sql,
|
|
54
|
+
isEmpty: !sql.trim()
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
Migration,
|
|
59
|
+
configSchema,
|
|
60
|
+
diffSchemas,
|
|
61
|
+
parseConfig,
|
|
62
|
+
reviewSqlWithAi,
|
|
63
|
+
run2 as runMigra,
|
|
64
|
+
validateConfig
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/lib/ai-review.ts","../src/lib/differ.ts"],"sourcesContent":["// Re-export from @pgkit/migra for advanced usage\nexport { Migration, run as runMigra } from '@pgkit/migra';\nexport { configSchema, parseConfig, validateConfig } from './config';\nexport { reviewSqlWithAi } from './lib/ai-review';\nexport { type DiffOutput, diffSchemas } from './lib/differ';\nexport type {\n AiReviewConfig,\n DiffMode,\n DiffOptions,\n PgConfig,\n} from './types';\n","import { z } from 'zod';\nimport type { PgConfig } from './types';\n\nexport const aiReviewConfigSchema = z.object({\n apiKey: z.string(),\n model: z.string().optional(),\n});\n\nexport const configSchema = z.object({\n source: z.string().describe('Source database connection string'),\n destination: z.string().describe('Destination database connection string'),\n schemas: z.array(z.string()).optional().describe('Schemas to include'),\n include: z\n .array(z.string())\n .optional()\n .describe('Object patterns to include'),\n exclude: z\n .array(z.string())\n .optional()\n .describe('Object patterns to exclude'),\n mode: z\n .enum(['safe', 'strict'])\n .optional()\n .default('safe')\n .describe('Diff mode'),\n aiReview: aiReviewConfigSchema.optional().describe('AI review configuration'),\n});\n\nexport function parseConfig(input: unknown): PgConfig {\n return configSchema.parse(input);\n}\n\nexport function validateConfig(input: unknown): {\n success: boolean;\n data?: PgConfig;\n error?: z.ZodError;\n} {\n const result = configSchema.safeParse(input);\n if (result.success) {\n return { success: true, data: result.data as PgConfig };\n }\n return { success: false, error: result.error };\n}\n","import type { AiReviewConfig } from '../types';\n\n/**\n * Placeholder for AI review functionality.\n * Will use OpenAI SDK to review and improve generated SQL.\n */\nexport function reviewSqlWithAi(input: {\n sql: string;\n config: AiReviewConfig;\n}): Promise<{\n reviewed: string;\n suggestions: string[];\n}> {\n const { sql, config: _config } = input;\n\n // TODO: Implement with OpenAI SDK\n // Example implementation:\n // const openai = new OpenAI({ apiKey: _config.apiKey });\n // const response = await openai.chat.completions.create({\n // model: _config.model || 'gpt-4',\n // messages: [\n // { role: 'system', content: 'You are a PostgreSQL migration expert...' },\n // { role: 'user', content: `Review this migration SQL:\\n\\n${sql}` },\n // ],\n // });\n\n // For now, return unchanged\n return Promise.resolve({\n reviewed: sql,\n suggestions: [\n 'AI review not yet implemented. Add openai dependency and implement reviewSqlWithAi().',\n ],\n });\n}\n","import { run } from '@pgkit/migra';\nimport type { DiffOptions } from '../types';\n\nexport type DiffSchemasInput = {\n source: string;\n destination: string;\n options?: DiffOptions;\n};\n\nexport type DiffOutput = {\n sql: string;\n isEmpty: boolean;\n};\n\n/**\n * Diff two PostgreSQL database schemas using @pgkit/migra.\n * Returns SQL to transform destination to match source.\n */\nexport async function diffSchemas(\n input: DiffSchemasInput,\n): Promise<DiffOutput> {\n const { source, destination, options } = input;\n\n const migration = await run(destination, source, {\n unsafe: options?.mode === 'strict',\n schema: options?.schemas?.[0],\n excludeSchema: options?.exclude,\n withPrivileges: true,\n });\n\n const sql = migration.sql;\n\n return {\n sql,\n isEmpty: !sql.trim(),\n };\n}\n"],"mappings":";AACA,SAAS,WAAkB,OAAPA,YAAuB;;;ACD3C,SAAS,SAAS;AAGX,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,QAAQ,EAAE,OAAO;AAAA,EACjB,OAAO,EAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAEM,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,QAAQ,EAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,EAC/D,aAAa,EAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,EACzE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,EACrE,SAAS,EACN,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT,SAAS,4BAA4B;AAAA,EACxC,SAAS,EACN,MAAM,EAAE,OAAO,CAAC,EAChB,SAAS,EACT,SAAS,4BAA4B;AAAA,EACxC,MAAM,EACH,KAAK,CAAC,QAAQ,QAAQ,CAAC,EACvB,SAAS,EACT,QAAQ,MAAM,EACd,SAAS,WAAW;AAAA,EACvB,UAAU,qBAAqB,SAAS,EAAE,SAAS,yBAAyB;AAC9E,CAAC;AAEM,SAAS,YAAY,OAA0B;AACpD,SAAO,aAAa,MAAM,KAAK;AACjC;AAEO,SAAS,eAAe,OAI7B;AACA,QAAM,SAAS,aAAa,UAAU,KAAK;AAC3C,MAAI,OAAO,SAAS;AAClB,WAAO,EAAE,SAAS,MAAM,MAAM,OAAO,KAAiB;AAAA,EACxD;AACA,SAAO,EAAE,SAAS,OAAO,OAAO,OAAO,MAAM;AAC/C;;;ACpCO,SAAS,gBAAgB,OAM7B;AACD,QAAM,EAAE,KAAK,QAAQ,QAAQ,IAAI;AAcjC,SAAO,QAAQ,QAAQ;AAAA,IACrB,UAAU;AAAA,IACV,aAAa;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACjCA,SAAS,WAAW;AAkBpB,eAAsB,YACpB,OACqB;AACrB,QAAM,EAAE,QAAQ,aAAa,QAAQ,IAAI;AAEzC,QAAM,YAAY,MAAM,IAAI,aAAa,QAAQ;AAAA,IAC/C,QAAQ,SAAS,SAAS;AAAA,IAC1B,QAAQ,SAAS,UAAU,CAAC;AAAA,IAC5B,eAAe,SAAS;AAAA,IACxB,gBAAgB;AAAA,EAClB,CAAC;AAED,QAAM,MAAM,UAAU;AAEtB,SAAO;AAAA,IACL;AAAA,IACA,SAAS,CAAC,IAAI,KAAK;AAAA,EACrB;AACF;","names":["run"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mesob/pg",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"mesob-pg": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./cli": {
|
|
17
|
+
"types": "./dist/cli.d.ts",
|
|
18
|
+
"default": "./dist/cli.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@pgkit/migra": "^0.6.1",
|
|
26
|
+
"yargs": "^18.0.0",
|
|
27
|
+
"zod": "^4.1.12"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22.0.0",
|
|
31
|
+
"@types/yargs": "^17.0.33",
|
|
32
|
+
"tsup": "^8.5.0",
|
|
33
|
+
"typescript": "^5.7.2",
|
|
34
|
+
"vitest": "^2.1.8"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup",
|
|
41
|
+
"dev": "tsup --watch",
|
|
42
|
+
"lint": "biome check --write .",
|
|
43
|
+
"check-types": "tsc --noEmit",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest"
|
|
46
|
+
}
|
|
47
|
+
}
|