@appixar/xpg 1.0.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/__tests__/core.test.d.ts +2 -0
- package/dist/__tests__/core.test.d.ts.map +1 -0
- package/dist/__tests__/core.test.js +228 -0
- package/dist/__tests__/core.test.js.map +1 -0
- package/dist/builder.d.ts +23 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +262 -0
- package/dist/builder.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +119 -0
- package/dist/cli.js.map +1 -0
- package/dist/configLoader.d.ts +22 -0
- package/dist/configLoader.d.ts.map +1 -0
- package/dist/configLoader.js +97 -0
- package/dist/configLoader.js.map +1 -0
- package/dist/defaultNormalizer.d.ts +29 -0
- package/dist/defaultNormalizer.d.ts.map +1 -0
- package/dist/defaultNormalizer.js +124 -0
- package/dist/defaultNormalizer.js.map +1 -0
- package/dist/diffEngine.d.ts +21 -0
- package/dist/diffEngine.d.ts.map +1 -0
- package/dist/diffEngine.js +233 -0
- package/dist/diffEngine.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +63 -0
- package/dist/logger.js.map +1 -0
- package/dist/pgService.d.ts +42 -0
- package/dist/pgService.d.ts.map +1 -0
- package/dist/pgService.js +219 -0
- package/dist/pgService.js.map +1 -0
- package/dist/schemaParser.d.ts +10 -0
- package/dist/schemaParser.d.ts.map +1 -0
- package/dist/schemaParser.js +118 -0
- package/dist/schemaParser.js.map +1 -0
- package/dist/sqlGenerator.d.ts +18 -0
- package/dist/sqlGenerator.d.ts.map +1 -0
- package/dist/sqlGenerator.js +104 -0
- package/dist/sqlGenerator.js.map +1 -0
- package/dist/typeDictionary.d.ts +2 -0
- package/dist/typeDictionary.d.ts.map +1 -0
- package/dist/typeDictionary.js +27 -0
- package/dist/typeDictionary.js.map +1 -0
- package/dist/types.d.ts +72 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
- package/xpg.config.yml-sample +42 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgService.js","sourceRoot":"","sources":["../src/pgService.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,yBAAyB;AACzB,gDAAgD;AAChD,yCAAyC;AACzC,mDAAmD;AACnD,qDAAqD;AAErD,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AASpB,iEAAiE;AACjE,uDAAuD;AACvD,MAAM,YAAY,GAAyB,IAAI,GAAG,EAAE,CAAC;AAErD;;GAEG;AACH,SAAS,cAAc,CACnB,WAA0C;IAE1C,sBAAsB;IACtB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,SAAS,GAAwB,IAAI,CAAC;IAC1C,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACxB,SAAS,GAAG,IAAI,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC9B,uCAAuC;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACvB,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;QACL,CAAC;IACL,CAAC;IAED,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAClE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEtD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,IAAkB,EAAE,GAAW;IAC5C,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;IAEzD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAEjE,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;QAClB,IAAI;QACJ,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;QACzE,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,IAAI;QACnB,GAAG,EAAE,EAAE;QACP,iBAAiB,EAAE,KAAK;KAC3B,CAAC,CAAC;IAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,4BAA4B,GAAG,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAE5D,SAAS,UAAU,CAAC,GAAW;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,OAAO,SAAS;IAOlB,YACI,WAA0C,EAC1C,WAAmB,EACnB,UAA4B,EAAE;QAL3B,UAAK,GAAkB,IAAI,CAAC;QAO/B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;QAC7C,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;IAEO,YAAY;QAChB,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,WAAW,QAAQ,CAAC,CAAC;IAChE,CAAC;IAEO,WAAW;QACf,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;QAClD,gCAAgC;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9D,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,WAAW,SAAS,GAAG,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED;;;OAGG;IACH,YAAY;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,QAAQ,CAAC;QACxC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,YAAY,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QAEzD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;YAClB,IAAI;YACJ,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI;YACzE,QAAQ,EAAE,UAAU,EAAE,kCAAkC;YACxD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,GAAG,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACrB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CACP,GAAW,EACX,MAAgC;QAEhC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY;YAC9C,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;YACpB,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAE1B,IAAI,CAAC;YACD,oDAAoD;YACpD,IAAI,KAAK,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAc,EAAE,CAAC;YAE7B,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,IAAI,UAAU,GAAG,CAAC,CAAC;gBACnB,8DAA8D;gBAC9D,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;oBAC1D,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;wBAC5B,UAAU,EAAE,CAAC;wBACb,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;wBACzB,OAAO,IAAI,UAAU,EAAE,CAAC;oBAC5B,CAAC;oBACD,OAAO,MAAM,CAAC;gBAClB,CAAC,CAAC,CAAC;YACP,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC/E,OAAO,MAAM,CAAC,IAAW,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,GAAI,GAAa,CAAC,OAAO,CAAC;YACpC,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,IAA6B;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,IAAI,CAAC;YAC1D,OAAO,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,gBAAgB,KAAK,MAAM,IAAI,aAAa,YAAY,eAAe,CAAC;QAEpF,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,GAAI,GAAa,CAAC,OAAO,CAAC;YACpC,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACR,KAAa,EACb,IAA6B,EAC7B,SAA2C;QAE3C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACjC,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,IAAI,GAAG,GAAG,CAAC,CAAC;QAEZ,aAAa;QACb,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;YACnD,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,IAAI,CAAC,UAAU,CAAC;YACrE,GAAG,EAAE,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,IAAI,WAAmB,CAAC;QACxB,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChC,WAAW,GAAG,SAAS,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBACxD,IAAI,CAAC,KAAK,MAAM;oBAAE,OAAO,IAAI,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,KAAK,EAAE;oBAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;gBACnC,GAAG,EAAE,CAAC;gBACN,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACb,OAAO,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YAC9B,CAAC,CAAC,CAAC;YACH,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,GAAG,GAAG,WAAW,KAAK,SAAS,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,WAAW,EAAE,CAAC;QAElF,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC3C,OAAO,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,GAAI,GAAa,CAAC,OAAO,CAAC;YACpC,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ;QACjB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YAChC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;YACjB,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CustomFieldDef, ParsedSchema } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse YAML table columns (the raw field map from a .yml table entry)
|
|
4
|
+
* into a structured ParsedSchema with typed fields, indexes, and constraints.
|
|
5
|
+
*
|
|
6
|
+
* @param fields - Raw YAML fields: `{ column_name: "type modifier1 modifier2 ..." }`
|
|
7
|
+
* @param customFields - Custom field type definitions from config
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseSchema(fields: Record<string, string> | null | undefined, customFields: Record<string, CustomFieldDef>): ParsedSchema;
|
|
10
|
+
//# sourceMappingURL=schemaParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaParser.d.ts","sourceRoot":"","sources":["../src/schemaParser.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAmB,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhF;;;;;;GAMG;AACH,wBAAgB,WAAW,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,EACjD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAC7C,YAAY,CA+Gd"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────
|
|
2
|
+
// x-postgres — YAML schema parser
|
|
3
|
+
// ─────────────────────────────────────────────
|
|
4
|
+
// Parses the YAML field DSL into structured ParsedSchema.
|
|
5
|
+
// Port of PHP convertField().
|
|
6
|
+
/**
|
|
7
|
+
* Parse YAML table columns (the raw field map from a .yml table entry)
|
|
8
|
+
* into a structured ParsedSchema with typed fields, indexes, and constraints.
|
|
9
|
+
*
|
|
10
|
+
* @param fields - Raw YAML fields: `{ column_name: "type modifier1 modifier2 ..." }`
|
|
11
|
+
* @param customFields - Custom field type definitions from config
|
|
12
|
+
*/
|
|
13
|
+
export function parseSchema(fields, customFields) {
|
|
14
|
+
const result = {
|
|
15
|
+
fields: {},
|
|
16
|
+
individualIndexes: [],
|
|
17
|
+
compositeIndexes: {},
|
|
18
|
+
compositeUniqueIndexes: {},
|
|
19
|
+
};
|
|
20
|
+
if (!fields || typeof fields !== 'object')
|
|
21
|
+
return result;
|
|
22
|
+
for (const [fieldName, rawValue] of Object.entries(fields)) {
|
|
23
|
+
// Skip meta keys like ~ignore
|
|
24
|
+
if (fieldName.startsWith('~'))
|
|
25
|
+
continue;
|
|
26
|
+
if (typeof rawValue !== 'string')
|
|
27
|
+
continue;
|
|
28
|
+
const parts = rawValue.split(/\s+/);
|
|
29
|
+
const typePart = parts[0];
|
|
30
|
+
// Extract base type and optional length: "type/length" → type, length
|
|
31
|
+
const [typeAlias, lengthStr] = typePart.split('/');
|
|
32
|
+
// Resolve custom field type
|
|
33
|
+
const customDef = customFields[typeAlias];
|
|
34
|
+
let typeReal = customDef?.Type ?? typeAlias;
|
|
35
|
+
// Apply explicit length override
|
|
36
|
+
if (lengthStr) {
|
|
37
|
+
// Remove any existing (N) from the type
|
|
38
|
+
typeReal = typeReal.replace(/\(\d+(?:,\d+)?\)/, '');
|
|
39
|
+
typeReal = `${typeReal}(${lengthStr})`;
|
|
40
|
+
}
|
|
41
|
+
// ─── Default ───
|
|
42
|
+
let defaultRaw = null;
|
|
43
|
+
for (const part of parts) {
|
|
44
|
+
if (part.startsWith('default/')) {
|
|
45
|
+
defaultRaw = part.substring('default/'.length);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Fallback: default from custom field definition
|
|
50
|
+
if (defaultRaw === null && customDef?.Default) {
|
|
51
|
+
defaultRaw = customDef.Default;
|
|
52
|
+
}
|
|
53
|
+
// ─── Nullable ───
|
|
54
|
+
let nullable;
|
|
55
|
+
if (typeAlias === 'id' || typeReal.toUpperCase().includes('SERIAL')) {
|
|
56
|
+
nullable = ''; // SERIAL = implicit NOT NULL
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
nullable = parts.includes('required') ? 'NOT NULL' : 'NULL';
|
|
60
|
+
}
|
|
61
|
+
// ─── Key ───
|
|
62
|
+
let key = '';
|
|
63
|
+
const customKey = customDef?.Key;
|
|
64
|
+
if (parts.includes('unique'))
|
|
65
|
+
key = 'UNI'; // simple unique (no group)
|
|
66
|
+
if (customKey)
|
|
67
|
+
key = customKey;
|
|
68
|
+
// ─── Extra ───
|
|
69
|
+
const extra = (customDef?.Extra ?? '').toUpperCase();
|
|
70
|
+
// ─── Build field definition ───
|
|
71
|
+
result.fields[fieldName] = {
|
|
72
|
+
field: fieldName,
|
|
73
|
+
type: typeReal.toUpperCase(),
|
|
74
|
+
nullable,
|
|
75
|
+
key,
|
|
76
|
+
defaultValue: defaultRaw,
|
|
77
|
+
extra,
|
|
78
|
+
};
|
|
79
|
+
// ─── Indexes ───
|
|
80
|
+
for (const part of parts) {
|
|
81
|
+
// "index" or "index/group1,group2"
|
|
82
|
+
if (part === 'index' || part.startsWith('index/')) {
|
|
83
|
+
const indexParts = part.split('/');
|
|
84
|
+
if (indexParts[1]) {
|
|
85
|
+
// Composite index
|
|
86
|
+
const groupNames = indexParts[1].split(',');
|
|
87
|
+
for (const groupName of groupNames) {
|
|
88
|
+
if (!result.compositeIndexes[groupName]) {
|
|
89
|
+
result.compositeIndexes[groupName] = [];
|
|
90
|
+
}
|
|
91
|
+
result.compositeIndexes[groupName].push(fieldName);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Individual index
|
|
96
|
+
if (!result.individualIndexes.includes(fieldName)) {
|
|
97
|
+
result.individualIndexes.push(fieldName);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// "unique/group" = composite unique
|
|
102
|
+
if (part.startsWith('unique/')) {
|
|
103
|
+
const uniqueParts = part.split('/');
|
|
104
|
+
if (uniqueParts[1]) {
|
|
105
|
+
const groupNames = uniqueParts[1].split(',');
|
|
106
|
+
for (const groupName of groupNames) {
|
|
107
|
+
if (!result.compositeUniqueIndexes[groupName]) {
|
|
108
|
+
result.compositeUniqueIndexes[groupName] = [];
|
|
109
|
+
}
|
|
110
|
+
result.compositeUniqueIndexes[groupName].push(fieldName);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=schemaParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaParser.js","sourceRoot":"","sources":["../src/schemaParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ParsedSchema, QueuedQuery } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generate CREATE TABLE + all related indexes/constraints for a new table.
|
|
4
|
+
*
|
|
5
|
+
* ⚠ NOTE: Index creation uses CONCURRENTLY which **cannot run inside a transaction**.
|
|
6
|
+
* The builder executes each query individually (no BEGIN/COMMIT wrapping) to avoid this.
|
|
7
|
+
* If you call these queries programmatically, do NOT wrap them in a transaction block.
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateCreateTable(table: string, schema: ParsedSchema, mute: boolean): QueuedQuery[];
|
|
10
|
+
/**
|
|
11
|
+
* Generate DROP TABLE CASCADE statement.
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateDropTable(table: string, mute: boolean): QueuedQuery;
|
|
14
|
+
/**
|
|
15
|
+
* Generate CREATE DATABASE statement.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateCreateDatabase(name: string): QueuedQuery;
|
|
18
|
+
//# sourceMappingURL=sqlGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlGenerator.d.ts","sourceRoot":"","sources":["../src/sqlGenerator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI5D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,OAAO,GACd,WAAW,EAAE,CAuEf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,WAAW,CAM3E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAIhE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────
|
|
2
|
+
// x-postgres — SQL generator
|
|
3
|
+
// ─────────────────────────────────────────────
|
|
4
|
+
// Generates CREATE TABLE, indexes, constraints, DROP TABLE, CREATE DATABASE.
|
|
5
|
+
import { buildDefaultClause } from './defaultNormalizer.js';
|
|
6
|
+
import * as log from './logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Generate CREATE TABLE + all related indexes/constraints for a new table.
|
|
9
|
+
*
|
|
10
|
+
* ⚠ NOTE: Index creation uses CONCURRENTLY which **cannot run inside a transaction**.
|
|
11
|
+
* The builder executes each query individually (no BEGIN/COMMIT wrapping) to avoid this.
|
|
12
|
+
* If you call these queries programmatically, do NOT wrap them in a transaction block.
|
|
13
|
+
*/
|
|
14
|
+
export function generateCreateTable(table, schema, mute) {
|
|
15
|
+
const queries = [];
|
|
16
|
+
if (!mute)
|
|
17
|
+
log.header(`∴ ${table}`, 'blue');
|
|
18
|
+
const { fields, individualIndexes, compositeIndexes, compositeUniqueIndexes } = schema;
|
|
19
|
+
// ─── CREATE TABLE ───
|
|
20
|
+
const colDefs = [];
|
|
21
|
+
const uniqueFields = [];
|
|
22
|
+
for (const [k, v] of Object.entries(fields)) {
|
|
23
|
+
const type = v.type;
|
|
24
|
+
const nullable = v.nullable === 'NOT NULL' ? 'NOT NULL' : v.nullable === 'NULL' ? 'NULL' : '';
|
|
25
|
+
const extra = v.extra;
|
|
26
|
+
// SERIAL auto-creates default nextval, don't force DEFAULT
|
|
27
|
+
let defaultClause = '';
|
|
28
|
+
if (!type.includes('SERIAL')) {
|
|
29
|
+
defaultClause = buildDefaultClause(v.defaultValue, type);
|
|
30
|
+
}
|
|
31
|
+
let colSql = `"${k}" ${type}`;
|
|
32
|
+
if (nullable)
|
|
33
|
+
colSql += ` ${nullable}`;
|
|
34
|
+
if (defaultClause)
|
|
35
|
+
colSql += ` ${defaultClause}`;
|
|
36
|
+
if (extra)
|
|
37
|
+
colSql += ` ${extra}`;
|
|
38
|
+
if (v.key === 'PRI')
|
|
39
|
+
colSql += ' PRIMARY KEY';
|
|
40
|
+
if (v.key === 'UNI')
|
|
41
|
+
uniqueFields.push(k);
|
|
42
|
+
colDefs.push(colSql);
|
|
43
|
+
}
|
|
44
|
+
const createSql = `CREATE TABLE "${table}" (\n${colDefs.join(',\n')}\n);`;
|
|
45
|
+
queries.push({ sql: createSql, mini: `CREATE TABLE "${table}" ...`, color: 'green' });
|
|
46
|
+
if (!mute)
|
|
47
|
+
log.say(`→ ${createSql}`, 'green');
|
|
48
|
+
// ─── UNIQUE constraints ───
|
|
49
|
+
for (const field of uniqueFields) {
|
|
50
|
+
const sql = `ALTER TABLE "${table}" ADD CONSTRAINT "${table}_${field}_unique" UNIQUE ("${field}");`;
|
|
51
|
+
const mini = `ADD UNIQUE "${table}_${field}_unique" ...`;
|
|
52
|
+
queries.push({ sql, mini, color: 'cyan' });
|
|
53
|
+
if (!mute)
|
|
54
|
+
log.say(`→ ${sql}`, 'cyan');
|
|
55
|
+
}
|
|
56
|
+
// ─── Individual indexes ───
|
|
57
|
+
for (const field of individualIndexes) {
|
|
58
|
+
const sql = `CREATE INDEX CONCURRENTLY "${table}_${field}_idx" ON "${table}" ("${field}");`;
|
|
59
|
+
const mini = `ADD INDEX "${table}_${field}_idx" ...`;
|
|
60
|
+
queries.push({ sql, mini, color: 'cyan' });
|
|
61
|
+
if (!mute)
|
|
62
|
+
log.say(`→ ${sql}`, 'cyan');
|
|
63
|
+
}
|
|
64
|
+
// ─── Composite indexes ───
|
|
65
|
+
for (const [indexName, columns] of Object.entries(compositeIndexes)) {
|
|
66
|
+
const colsStr = columns.map(c => `"${c}"`).join(', ');
|
|
67
|
+
const sql = `CREATE INDEX CONCURRENTLY "${table}_${indexName}_idx" ON "${table}" (${colsStr});`;
|
|
68
|
+
const mini = `ADD INDEX "${table}_${indexName}_idx" ...`;
|
|
69
|
+
queries.push({ sql, mini, color: 'cyan' });
|
|
70
|
+
if (!mute)
|
|
71
|
+
log.say(`→ ${sql}`, 'cyan');
|
|
72
|
+
}
|
|
73
|
+
// ─── Composite unique indexes ───
|
|
74
|
+
for (const [indexName, columns] of Object.entries(compositeUniqueIndexes)) {
|
|
75
|
+
const colsStr = columns.map(c => `"${c}"`).join(', ');
|
|
76
|
+
const sql = `CREATE UNIQUE INDEX CONCURRENTLY "${table}_${indexName}_unique_idx" ON "${table}" (${colsStr});`;
|
|
77
|
+
const mini = `ADD UNIQUE INDEX "${table}_${indexName}_unique_idx" ...`;
|
|
78
|
+
queries.push({ sql, mini, color: 'cyan' });
|
|
79
|
+
if (!mute)
|
|
80
|
+
log.say(`→ ${sql}`, 'cyan');
|
|
81
|
+
}
|
|
82
|
+
return queries;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate DROP TABLE CASCADE statement.
|
|
86
|
+
*/
|
|
87
|
+
export function generateDropTable(table, mute) {
|
|
88
|
+
if (!mute)
|
|
89
|
+
log.header(`∴ ${table}`, 'blue');
|
|
90
|
+
const sql = `DROP TABLE IF EXISTS "${table}" CASCADE;`;
|
|
91
|
+
const mini = `DROP TABLE "${table}" ...`;
|
|
92
|
+
if (!mute)
|
|
93
|
+
log.say(`→ ${sql}`, 'yellow');
|
|
94
|
+
return { sql, mini, color: 'yellow' };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Generate CREATE DATABASE statement.
|
|
98
|
+
*/
|
|
99
|
+
export function generateCreateDatabase(name) {
|
|
100
|
+
const sql = `CREATE DATABASE "${name}" ENCODING 'UTF8';`;
|
|
101
|
+
const mini = `CREATE DATABASE "${name}" ...`;
|
|
102
|
+
return { sql, mini, color: 'green' };
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=sqlGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlGenerator.js","sourceRoot":"","sources":["../src/sqlGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeDictionary.d.ts","sourceRoot":"","sources":["../src/typeDictionary.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmB3D,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────
|
|
2
|
+
// x-postgres — Postgres type dictionary
|
|
3
|
+
// ─────────────────────────────────────────────
|
|
4
|
+
// Maps YAML/config type names to their PostgreSQL
|
|
5
|
+
// information_schema.columns data_type equivalents.
|
|
6
|
+
// Used by the diff engine for accurate comparison.
|
|
7
|
+
export const POSTGRES_TYPE_DICTIONARY = {
|
|
8
|
+
SERIAL: 'integer',
|
|
9
|
+
VARCHAR: 'character varying',
|
|
10
|
+
INT: 'integer',
|
|
11
|
+
INTEGER: 'integer',
|
|
12
|
+
TEXT: 'text',
|
|
13
|
+
TIMESTAMP: 'timestamp without time zone',
|
|
14
|
+
DATE: 'date',
|
|
15
|
+
TIME: 'time without time zone',
|
|
16
|
+
BOOLEAN: 'boolean',
|
|
17
|
+
SMALLINT: 'smallint',
|
|
18
|
+
BIGINT: 'bigint',
|
|
19
|
+
REAL: 'real',
|
|
20
|
+
DOUBLE: 'double precision',
|
|
21
|
+
NUMERIC: 'numeric',
|
|
22
|
+
DECIMAL: 'numeric',
|
|
23
|
+
JSON: 'json',
|
|
24
|
+
JSONB: 'jsonb',
|
|
25
|
+
UUID: 'uuid',
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=typeDictionary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeDictionary.js","sourceRoot":"","sources":["../src/typeDictionary.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,wCAAwC;AACxC,gDAAgD;AAChD,kDAAkD;AAClD,oDAAoD;AACpD,mDAAmD;AAEnD,MAAM,CAAC,MAAM,wBAAwB,GAA2B;IAC5D,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,mBAAmB;IAC5B,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,6BAA6B;IACxC,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,wBAAwB;IAC9B,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACf,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** Parsed field definition from YAML DSL */
|
|
2
|
+
export interface FieldDefinition {
|
|
3
|
+
field: string;
|
|
4
|
+
type: string;
|
|
5
|
+
nullable: string;
|
|
6
|
+
key: string;
|
|
7
|
+
defaultValue: string | null;
|
|
8
|
+
extra: string;
|
|
9
|
+
}
|
|
10
|
+
/** Result of parsing a full table's field list from YAML */
|
|
11
|
+
export interface ParsedSchema {
|
|
12
|
+
fields: Record<string, FieldDefinition>;
|
|
13
|
+
individualIndexes: string[];
|
|
14
|
+
compositeIndexes: Record<string, string[]>;
|
|
15
|
+
compositeUniqueIndexes: Record<string, string[]>;
|
|
16
|
+
}
|
|
17
|
+
/** Custom field type definition (from custom_fields.yml) */
|
|
18
|
+
export interface CustomFieldDef {
|
|
19
|
+
Type: string;
|
|
20
|
+
Null?: string;
|
|
21
|
+
Default?: string;
|
|
22
|
+
Key?: string;
|
|
23
|
+
Extra?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Single node in a database cluster */
|
|
26
|
+
export interface DbNodeConfig {
|
|
27
|
+
TYPE?: 'write' | 'read';
|
|
28
|
+
NAME: string;
|
|
29
|
+
HOST: string | string[];
|
|
30
|
+
USER: string;
|
|
31
|
+
PASS: string;
|
|
32
|
+
PORT: number | string;
|
|
33
|
+
PREF?: string;
|
|
34
|
+
PATH?: string | string[];
|
|
35
|
+
TENANT_KEYS?: TenantKeysConfig;
|
|
36
|
+
}
|
|
37
|
+
/** Tenant key resolution config */
|
|
38
|
+
export interface TenantKeysConfig {
|
|
39
|
+
DBKEY?: string;
|
|
40
|
+
TABLE?: string;
|
|
41
|
+
FIELD?: string;
|
|
42
|
+
WHERE?: string;
|
|
43
|
+
CONTROLLER?: string;
|
|
44
|
+
JSON_URL?: string;
|
|
45
|
+
}
|
|
46
|
+
/** Top-level postgres config shape */
|
|
47
|
+
export interface PostgresConfig {
|
|
48
|
+
POSTGRES: {
|
|
49
|
+
DB: Record<string, DbNodeConfig | DbNodeConfig[]>;
|
|
50
|
+
CUSTOM_FIELDS?: Record<string, CustomFieldDef>;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Row from information_schema.columns */
|
|
54
|
+
export interface DbColumnInfo {
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
column_name: string;
|
|
57
|
+
data_type: string;
|
|
58
|
+
is_nullable: string;
|
|
59
|
+
character_maximum_length: number | null;
|
|
60
|
+
column_default: string | null;
|
|
61
|
+
numeric_precision: number | null;
|
|
62
|
+
numeric_scale: number | null;
|
|
63
|
+
}
|
|
64
|
+
/** Valid colors for terminal output */
|
|
65
|
+
export type LogColor = 'green' | 'yellow' | 'cyan' | 'gray' | 'red' | 'magenta' | 'blue' | 'white';
|
|
66
|
+
/** A queued SQL action */
|
|
67
|
+
export interface QueuedQuery {
|
|
68
|
+
sql: string;
|
|
69
|
+
mini: string;
|
|
70
|
+
color: LogColor;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACpD;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED,mCAAmC;AACnC,MAAM,WAAW,gBAAgB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE;QACN,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;KAClD,CAAC;CACL;AAED,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,uCAAuC;AACvC,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnG,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,CAAC;CACnB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,gCAAgC;AAChC,gDAAgD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@appixar/xpg",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "YAML-driven PostgreSQL schema management, diff-based migrations, and query service",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"xpg": "./dist/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsx src/cli.ts",
|
|
20
|
+
"start": "node dist/cli.js",
|
|
21
|
+
"test": "tsx --test src/__tests__/*.test.ts"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18.0.0"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"chalk": "^5.3.0",
|
|
28
|
+
"commander": "^12.1.0",
|
|
29
|
+
"pg": "^8.13.1",
|
|
30
|
+
"yaml": "^2.6.1"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^22.10.0",
|
|
34
|
+
"@types/pg": "^8.11.10",
|
|
35
|
+
"tsx": "^4.19.0",
|
|
36
|
+
"typescript": "^5.7.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"xpg.config.yml-sample"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT"
|
|
43
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#────────────────────────────────────
|
|
2
|
+
# xpg configuration sample.
|
|
3
|
+
#────────────────────────────────────
|
|
4
|
+
# Copy this file to xpg.config.yml and fill in your credentials.
|
|
5
|
+
# Environment variables are interpolated with <ENV.VAR_NAME> syntax.
|
|
6
|
+
|
|
7
|
+
POSTGRES:
|
|
8
|
+
DB:
|
|
9
|
+
"main":
|
|
10
|
+
NAME: my_database
|
|
11
|
+
HOST: <ENV.DB_HOST>
|
|
12
|
+
USER: <ENV.DB_USER>
|
|
13
|
+
PASS: <ENV.DB_PASS>
|
|
14
|
+
PORT: <ENV.DB_PORT>
|
|
15
|
+
PREF: app_
|
|
16
|
+
PATH: [database]
|
|
17
|
+
|
|
18
|
+
CUSTOM_FIELDS:
|
|
19
|
+
"id":
|
|
20
|
+
Type: serial
|
|
21
|
+
Key: PRI
|
|
22
|
+
"str":
|
|
23
|
+
Type: varchar(64)
|
|
24
|
+
"text":
|
|
25
|
+
Type: text
|
|
26
|
+
"int":
|
|
27
|
+
Type: integer
|
|
28
|
+
"float":
|
|
29
|
+
Type: real
|
|
30
|
+
"date":
|
|
31
|
+
Type: timestamp
|
|
32
|
+
"email":
|
|
33
|
+
Type: varchar(128)
|
|
34
|
+
"phone":
|
|
35
|
+
Type: varchar(11)
|
|
36
|
+
"now":
|
|
37
|
+
Type: timestamp
|
|
38
|
+
Default: now()
|
|
39
|
+
"pid":
|
|
40
|
+
Type: varchar(12)
|
|
41
|
+
Key: UNI
|
|
42
|
+
Default: '"left"(md5((random())::text), 12)'
|