relq 1.0.58 → 1.0.60

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.
@@ -597,11 +597,11 @@ function convertToDbSchema(parsed, functions = [], triggers = [], comments = [])
597
597
  partitions: [],
598
598
  functions: functions.map(f => ({
599
599
  ...f,
600
- comment: functionComments.get(f.name) || null,
600
+ comment: functionComments.get(f.name) || undefined,
601
601
  })),
602
602
  triggers: triggers.map(t => ({
603
603
  ...t,
604
- comment: triggerComments.get(`${t.name}.${t.tableName}`) || null,
604
+ comment: triggerComments.get(`${t.name}.${t.tableName}`) || undefined,
605
605
  })),
606
606
  policies: [],
607
607
  foreignServers: [],
@@ -699,6 +699,10 @@ function generateFunctionCode(func, useCamelCase, varNameOverride) {
699
699
  parts.push(` strict: true,`);
700
700
  if (func.securityDefiner)
701
701
  parts.push(` securityDefiner: true,`);
702
+ if (func.comment) {
703
+ const escapedComment = func.comment.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/'/g, "\\'");
704
+ parts.push(` comment: '${escapedComment}',`);
705
+ }
702
706
  parts.push(`})`);
703
707
  if (func.trackingId) {
704
708
  parts[parts.length - 1] = parts[parts.length - 1].replace('})', `}).$id('${func.trackingId}')`);
@@ -716,7 +720,7 @@ function generateTriggerCode(trigger, useCamelCase, functionNames) {
716
720
  const tableName = useCamelCase ? (0, utils_1.toCamelCase)(trigger.table) : trigger.table;
717
721
  const parts = [];
718
722
  parts.push(`export const ${triggerName} = pgTrigger('${trigger.name}', {`);
719
- parts.push(` table: ${tableName},`);
723
+ parts.push(` on: ${tableName},`);
720
724
  parts.push(` timing: '${trigger.timing}',`);
721
725
  parts.push(` events: [${trigger.events.map(e => `'${e}'`).join(', ')}],`);
722
726
  parts.push(` forEach: '${trigger.forEach}',`);
@@ -735,7 +739,14 @@ function generateTriggerCode(trigger, useCamelCase, functionNames) {
735
739
  parts.push(` deferrable: true,`);
736
740
  if (trigger.initiallyDeferred)
737
741
  parts.push(` initiallyDeferred: true,`);
742
+ if (trigger.comment) {
743
+ const escapedComment = trigger.comment.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/'/g, "\\'");
744
+ parts.push(` comment: '${escapedComment}',`);
745
+ }
738
746
  parts.push(`})`);
747
+ if (trigger.trackingId) {
748
+ parts[parts.length - 1] = parts[parts.length - 1].replace('})', `}).$id('${trigger.trackingId}')`);
749
+ }
739
750
  return parts.join('\n');
740
751
  }
741
752
  function generateTypeScriptFromAST(schema, options = {}) {
@@ -1273,12 +1284,16 @@ function generateTriggersFile(schema, options = {}) {
1273
1284
  parts.push(` deferrable: true,`);
1274
1285
  if (trigger.initiallyDeferred)
1275
1286
  parts.push(` initially: 'DEFERRED',`);
1276
- if (trigger.trackingId) {
1277
- parts.push(`}).$id('${trigger.trackingId}');`);
1287
+ let closing = '})';
1288
+ if (trigger.comment) {
1289
+ const escapedComment = trigger.comment.replace(/'/g, "\\'");
1290
+ closing += `.$comment('${escapedComment}')`;
1278
1291
  }
1279
- else {
1280
- parts.push(`});`);
1292
+ if (trigger.trackingId) {
1293
+ closing += `.$id('${trigger.trackingId}')`;
1281
1294
  }
1295
+ closing += ';';
1296
+ parts.push(closing);
1282
1297
  parts.push('');
1283
1298
  }
1284
1299
  parts.push('// =============================================================================');
@@ -715,6 +715,7 @@ async function introspectedToParsedSchema(schema) {
715
715
  volatility: f.volatility,
716
716
  isStrict: false,
717
717
  securityDefiner: false,
718
+ comment: f.comment,
718
719
  });
719
720
  }
720
721
  for (const t of schema.triggers || []) {
@@ -726,6 +727,7 @@ async function introspectedToParsedSchema(schema) {
726
727
  forEach: t.forEach || 'ROW',
727
728
  functionName: t.functionName || '',
728
729
  isConstraint: false,
730
+ comment: t.comment,
729
731
  });
730
732
  }
731
733
  return parsed;
@@ -809,9 +811,26 @@ function parseArgTypes(argTypes) {
809
811
  if (!argTypes)
810
812
  return [];
811
813
  const parts = Array.isArray(argTypes) ? argTypes : argTypes.split(',');
812
- return parts.map(arg => ({
813
- type: typeof arg === 'string' ? arg.trim() : String(arg),
814
- }));
814
+ return parts.map(arg => {
815
+ const trimmed = typeof arg === 'string' ? arg.trim() : String(arg);
816
+ if (!trimmed)
817
+ return { type: '' };
818
+ const firstSpace = trimmed.indexOf(' ');
819
+ if (firstSpace === -1) {
820
+ return { type: trimmed };
821
+ }
822
+ const firstPart = trimmed.substring(0, firstSpace);
823
+ const restPart = trimmed.substring(firstSpace + 1).trim();
824
+ const commonTypeStarts = ['integer', 'bigint', 'smallint', 'text', 'varchar', 'char', 'boolean',
825
+ 'timestamp', 'date', 'time', 'interval', 'numeric', 'decimal', 'real', 'double', 'uuid',
826
+ 'json', 'jsonb', 'bytea', 'inet', 'cidr', 'macaddr', 'point', 'line', 'circle', 'box',
827
+ 'tsvector', 'tsquery', 'void', 'trigger', 'record', 'setof', 'array'];
828
+ const lowerFirst = firstPart.toLowerCase();
829
+ if (commonTypeStarts.some(t => lowerFirst === t || lowerFirst.startsWith(t + '['))) {
830
+ return { type: trimmed };
831
+ }
832
+ return { name: firstPart, type: restPart };
833
+ }).filter(arg => arg.type !== '');
815
834
  }
816
835
  function extractFunctionBody(definition) {
817
836
  if (!definition)
@@ -931,6 +950,8 @@ function normalizedToParsedSchema(schema) {
931
950
  volatility: f.volatility || 'VOLATILE',
932
951
  isStrict: f.isStrict ?? false,
933
952
  securityDefiner: f.securityDefiner ?? false,
953
+ comment: f.comment,
954
+ trackingId: f.trackingId,
934
955
  })),
935
956
  triggers: (schema.triggers || []).map(t => ({
936
957
  name: t.name,
@@ -941,6 +962,8 @@ function normalizedToParsedSchema(schema) {
941
962
  functionName: t.functionName || '',
942
963
  whenClause: t.when,
943
964
  isConstraint: false,
965
+ comment: t.comment,
966
+ trackingId: t.trackingId,
944
967
  })),
945
968
  };
946
969
  }
@@ -294,7 +294,8 @@ async function introspectDatabase(connection, onProgress, options) {
294
294
  l.lanname as language,
295
295
  pg_get_functiondef(p.oid) as definition,
296
296
  p.prokind = 'a' as is_aggregate,
297
- p.provolatile as volatility
297
+ p.provolatile as volatility,
298
+ obj_description(p.oid, 'pg_proc') as comment
298
299
  FROM pg_proc p
299
300
  JOIN pg_namespace n ON p.pronamespace = n.oid
300
301
  JOIN pg_language l ON p.prolang = l.oid
@@ -322,6 +323,7 @@ async function introspectDatabase(connection, onProgress, options) {
322
323
  definition: f.definition || '',
323
324
  isAggregate: f.is_aggregate || false,
324
325
  volatility: f.volatility === 'i' ? 'IMMUTABLE' : f.volatility === 's' ? 'STABLE' : 'VOLATILE',
326
+ comment: f.comment || undefined,
325
327
  }));
326
328
  }
327
329
  let triggers = [];
@@ -347,7 +349,8 @@ async function introspectDatabase(connection, onProgress, options) {
347
349
  END as for_each,
348
350
  p.proname as function_name,
349
351
  pg_get_triggerdef(t.oid) as definition,
350
- t.tgenabled != 'D' as is_enabled
352
+ t.tgenabled != 'D' as is_enabled,
353
+ obj_description(t.oid, 'pg_trigger') as comment
351
354
  FROM pg_trigger t
352
355
  JOIN pg_class c ON t.tgrelid = c.oid
353
356
  JOIN pg_namespace n ON c.relnamespace = n.oid
@@ -370,6 +373,7 @@ async function introspectDatabase(connection, onProgress, options) {
370
373
  functionName: t.function_name,
371
374
  definition: t.definition || '',
372
375
  isEnabled: t.is_enabled,
376
+ comment: t.comment || undefined,
373
377
  }));
374
378
  }
375
379
  const policiesResult = await pool.query(`
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.json = exports.xml = exports.uuid = exports.tsquery = exports.tsvector = exports.varbit = exports.bitVarying = exports.bit = exports.macaddr8 = exports.macaddr = exports.inet = exports.cidr = exports.circle = exports.polygon = exports.path = exports.box = exports.lseg = exports.line = exports.point = exports.bool = exports.boolean = exports.timeWithTimeZone = exports.date = exports.timestampWithTimeZone = exports.bytea = exports.text = exports.character = exports.characterVarying = exports.money = exports.float8 = exports.doublePrecision = exports.float4 = exports.real = exports.numeric = exports.decimal = exports.serial8 = exports.bigserial = exports.serial2 = exports.smallserial = exports.serial4 = exports.serial = exports.int8 = exports.bigint = exports.int2 = exports.smallint = exports.int4 = exports.int = exports.integer = exports.EMPTY_ARRAY = exports.EMPTY_OBJECT = void 0;
4
- exports.index = exports.raw = exports.emptyArray = exports.emptyObject = exports.currentDate = exports.currentTimestamp = exports.now = exports.uuidV4 = exports.genRandomUuid = exports.SQL_BRAND = exports.compositeType = exports.domainType = exports.enumType = exports.customType = exports.box3d = exports.box2d = exports.geoPoint = exports.geography = exports.geometry = exports.semver = exports.cube = exports.hstore = exports.ltxtquery = exports.lquery = exports.ltree = exports.citext = exports.pgSnapshot = exports.pgLsn = exports.regtype = exports.regproc = exports.regclass = exports.oid = exports.datemultirange = exports.tstzmultirange = exports.tsmultirange = exports.nummultirange = exports.int8multirange = exports.int4multirange = exports.daterange = exports.tstzrange = exports.tsrange = exports.numrange = exports.int8range = exports.int4range = exports.jsonb = void 0;
3
+ exports.xml = exports.uuid = exports.tsquery = exports.tsvector = exports.varbit = exports.bitVarying = exports.bit = exports.macaddr8 = exports.macaddr = exports.inet = exports.cidr = exports.circle = exports.polygon = exports.path = exports.box = exports.lseg = exports.line = exports.point = exports.bool = exports.boolean = exports.timeWithTimeZone = exports.date = exports.timestampWithTimeZone = exports.bytea = exports.text = exports.character = exports.characterVarying = exports.money = exports.float8 = exports.doublePrecision = exports.float4 = exports.real = exports.numeric = exports.decimal = exports.epoch = exports.serial8 = exports.bigserial = exports.serial2 = exports.smallserial = exports.serial4 = exports.serial = exports.int8 = exports.bigint = exports.int2 = exports.smallint = exports.int4 = exports.int = exports.integer = exports.EMPTY_ARRAY = exports.EMPTY_OBJECT = void 0;
4
+ exports.index = exports.raw = exports.emptyArray = exports.emptyObject = exports.currentDate = exports.currentTimestamp = exports.now = exports.uuidV4 = exports.genRandomUuid = exports.SQL_BRAND = exports.compositeType = exports.domainType = exports.enumType = exports.customType = exports.box3d = exports.box2d = exports.geoPoint = exports.geography = exports.geometry = exports.semver = exports.cube = exports.hstore = exports.ltxtquery = exports.lquery = exports.ltree = exports.citext = exports.pgSnapshot = exports.pgLsn = exports.regtype = exports.regproc = exports.regclass = exports.oid = exports.datemultirange = exports.tstzmultirange = exports.tsmultirange = exports.nummultirange = exports.int8multirange = exports.int4multirange = exports.daterange = exports.tstzrange = exports.tsrange = exports.numrange = exports.int8range = exports.int4range = exports.jsonb = exports.json = void 0;
5
5
  exports.createFluentGenExpr = createFluentGenExpr;
6
6
  exports.varchar = varchar;
7
7
  exports.char = char;
@@ -653,6 +653,8 @@ exports.serial2 = exports.smallserial;
653
653
  const bigserial = (columnName) => createColumnWithName('BIGSERIAL', columnName);
654
654
  exports.bigserial = bigserial;
655
655
  exports.serial8 = exports.bigserial;
656
+ const epoch = (columnName) => createColumnWithName('BIGINT', columnName);
657
+ exports.epoch = epoch;
656
658
  const decimal = (columnNameOrOpts, scale) => {
657
659
  if (typeof columnNameOrOpts === 'string' && !columnNameOrOpts.includes('.')) {
658
660
  return createColumnWithName('DECIMAL', columnNameOrOpts);
@@ -21,6 +21,8 @@ exports.DEFAULT = {
21
21
  clockTimestamp: () => createDefault('clock_timestamp()'),
22
22
  timeofday: () => createDefault('timeofday()'),
23
23
  interval: (value) => createDefault(`INTERVAL '${value}'`),
24
+ epochNow: () => createDefault('(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint'),
25
+ epochSeconds: () => createDefault('EXTRACT(EPOCH FROM NOW())::bigint'),
24
26
  currentUser: () => createDefault('CURRENT_USER'),
25
27
  sessionUser: () => createDefault('SESSION_USER'),
26
28
  user: () => createDefault('USER'),
@@ -13,7 +13,12 @@ function generateFunctionSQL(config) {
13
13
  if (arg.mode && arg.mode !== 'IN') {
14
14
  argStr += arg.mode + ' ';
15
15
  }
16
- argStr += arg.name + ' ' + arg.type;
16
+ if (arg.name) {
17
+ argStr += arg.name + ' ' + arg.type;
18
+ }
19
+ else {
20
+ argStr += arg.type;
21
+ }
17
22
  if (arg.default !== undefined) {
18
23
  argStr += ' DEFAULT ' + arg.default;
19
24
  }
@@ -561,11 +561,11 @@ function convertToDbSchema(parsed, functions = [], triggers = [], comments = [])
561
561
  partitions: [],
562
562
  functions: functions.map(f => ({
563
563
  ...f,
564
- comment: functionComments.get(f.name) || null,
564
+ comment: functionComments.get(f.name) || undefined,
565
565
  })),
566
566
  triggers: triggers.map(t => ({
567
567
  ...t,
568
- comment: triggerComments.get(`${t.name}.${t.tableName}`) || null,
568
+ comment: triggerComments.get(`${t.name}.${t.tableName}`) || undefined,
569
569
  })),
570
570
  policies: [],
571
571
  foreignServers: [],
@@ -691,6 +691,10 @@ function generateFunctionCode(func, useCamelCase, varNameOverride) {
691
691
  parts.push(` strict: true,`);
692
692
  if (func.securityDefiner)
693
693
  parts.push(` securityDefiner: true,`);
694
+ if (func.comment) {
695
+ const escapedComment = func.comment.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/'/g, "\\'");
696
+ parts.push(` comment: '${escapedComment}',`);
697
+ }
694
698
  parts.push(`})`);
695
699
  if (func.trackingId) {
696
700
  parts[parts.length - 1] = parts[parts.length - 1].replace('})', `}).$id('${func.trackingId}')`);
@@ -708,7 +712,7 @@ function generateTriggerCode(trigger, useCamelCase, functionNames) {
708
712
  const tableName = useCamelCase ? toCamelCase(trigger.table) : trigger.table;
709
713
  const parts = [];
710
714
  parts.push(`export const ${triggerName} = pgTrigger('${trigger.name}', {`);
711
- parts.push(` table: ${tableName},`);
715
+ parts.push(` on: ${tableName},`);
712
716
  parts.push(` timing: '${trigger.timing}',`);
713
717
  parts.push(` events: [${trigger.events.map(e => `'${e}'`).join(', ')}],`);
714
718
  parts.push(` forEach: '${trigger.forEach}',`);
@@ -727,7 +731,14 @@ function generateTriggerCode(trigger, useCamelCase, functionNames) {
727
731
  parts.push(` deferrable: true,`);
728
732
  if (trigger.initiallyDeferred)
729
733
  parts.push(` initiallyDeferred: true,`);
734
+ if (trigger.comment) {
735
+ const escapedComment = trigger.comment.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/'/g, "\\'");
736
+ parts.push(` comment: '${escapedComment}',`);
737
+ }
730
738
  parts.push(`})`);
739
+ if (trigger.trackingId) {
740
+ parts[parts.length - 1] = parts[parts.length - 1].replace('})', `}).$id('${trigger.trackingId}')`);
741
+ }
731
742
  return parts.join('\n');
732
743
  }
733
744
  export function generateTypeScriptFromAST(schema, options = {}) {
@@ -1265,12 +1276,16 @@ export function generateTriggersFile(schema, options = {}) {
1265
1276
  parts.push(` deferrable: true,`);
1266
1277
  if (trigger.initiallyDeferred)
1267
1278
  parts.push(` initially: 'DEFERRED',`);
1268
- if (trigger.trackingId) {
1269
- parts.push(`}).$id('${trigger.trackingId}');`);
1279
+ let closing = '})';
1280
+ if (trigger.comment) {
1281
+ const escapedComment = trigger.comment.replace(/'/g, "\\'");
1282
+ closing += `.$comment('${escapedComment}')`;
1270
1283
  }
1271
- else {
1272
- parts.push(`});`);
1284
+ if (trigger.trackingId) {
1285
+ closing += `.$id('${trigger.trackingId}')`;
1273
1286
  }
1287
+ closing += ';';
1288
+ parts.push(closing);
1274
1289
  parts.push('');
1275
1290
  }
1276
1291
  parts.push('// =============================================================================');
@@ -705,6 +705,7 @@ export async function introspectedToParsedSchema(schema) {
705
705
  volatility: f.volatility,
706
706
  isStrict: false,
707
707
  securityDefiner: false,
708
+ comment: f.comment,
708
709
  });
709
710
  }
710
711
  for (const t of schema.triggers || []) {
@@ -716,6 +717,7 @@ export async function introspectedToParsedSchema(schema) {
716
717
  forEach: t.forEach || 'ROW',
717
718
  functionName: t.functionName || '',
718
719
  isConstraint: false,
720
+ comment: t.comment,
719
721
  });
720
722
  }
721
723
  return parsed;
@@ -799,9 +801,26 @@ function parseArgTypes(argTypes) {
799
801
  if (!argTypes)
800
802
  return [];
801
803
  const parts = Array.isArray(argTypes) ? argTypes : argTypes.split(',');
802
- return parts.map(arg => ({
803
- type: typeof arg === 'string' ? arg.trim() : String(arg),
804
- }));
804
+ return parts.map(arg => {
805
+ const trimmed = typeof arg === 'string' ? arg.trim() : String(arg);
806
+ if (!trimmed)
807
+ return { type: '' };
808
+ const firstSpace = trimmed.indexOf(' ');
809
+ if (firstSpace === -1) {
810
+ return { type: trimmed };
811
+ }
812
+ const firstPart = trimmed.substring(0, firstSpace);
813
+ const restPart = trimmed.substring(firstSpace + 1).trim();
814
+ const commonTypeStarts = ['integer', 'bigint', 'smallint', 'text', 'varchar', 'char', 'boolean',
815
+ 'timestamp', 'date', 'time', 'interval', 'numeric', 'decimal', 'real', 'double', 'uuid',
816
+ 'json', 'jsonb', 'bytea', 'inet', 'cidr', 'macaddr', 'point', 'line', 'circle', 'box',
817
+ 'tsvector', 'tsquery', 'void', 'trigger', 'record', 'setof', 'array'];
818
+ const lowerFirst = firstPart.toLowerCase();
819
+ if (commonTypeStarts.some(t => lowerFirst === t || lowerFirst.startsWith(t + '['))) {
820
+ return { type: trimmed };
821
+ }
822
+ return { name: firstPart, type: restPart };
823
+ }).filter(arg => arg.type !== '');
805
824
  }
806
825
  function extractFunctionBody(definition) {
807
826
  if (!definition)
@@ -922,6 +941,8 @@ export function normalizedToParsedSchema(schema) {
922
941
  volatility: f.volatility || 'VOLATILE',
923
942
  isStrict: f.isStrict ?? false,
924
943
  securityDefiner: f.securityDefiner ?? false,
944
+ comment: f.comment,
945
+ trackingId: f.trackingId,
925
946
  })),
926
947
  triggers: (schema.triggers || []).map(t => ({
927
948
  name: t.name,
@@ -932,6 +953,8 @@ export function normalizedToParsedSchema(schema) {
932
953
  functionName: t.functionName || '',
933
954
  whenClause: t.when,
934
955
  isConstraint: false,
956
+ comment: t.comment,
957
+ trackingId: t.trackingId,
935
958
  })),
936
959
  };
937
960
  }
@@ -257,7 +257,8 @@ export async function introspectDatabase(connection, onProgress, options) {
257
257
  l.lanname as language,
258
258
  pg_get_functiondef(p.oid) as definition,
259
259
  p.prokind = 'a' as is_aggregate,
260
- p.provolatile as volatility
260
+ p.provolatile as volatility,
261
+ obj_description(p.oid, 'pg_proc') as comment
261
262
  FROM pg_proc p
262
263
  JOIN pg_namespace n ON p.pronamespace = n.oid
263
264
  JOIN pg_language l ON p.prolang = l.oid
@@ -285,6 +286,7 @@ export async function introspectDatabase(connection, onProgress, options) {
285
286
  definition: f.definition || '',
286
287
  isAggregate: f.is_aggregate || false,
287
288
  volatility: f.volatility === 'i' ? 'IMMUTABLE' : f.volatility === 's' ? 'STABLE' : 'VOLATILE',
289
+ comment: f.comment || undefined,
288
290
  }));
289
291
  }
290
292
  let triggers = [];
@@ -310,7 +312,8 @@ export async function introspectDatabase(connection, onProgress, options) {
310
312
  END as for_each,
311
313
  p.proname as function_name,
312
314
  pg_get_triggerdef(t.oid) as definition,
313
- t.tgenabled != 'D' as is_enabled
315
+ t.tgenabled != 'D' as is_enabled,
316
+ obj_description(t.oid, 'pg_trigger') as comment
314
317
  FROM pg_trigger t
315
318
  JOIN pg_class c ON t.tgrelid = c.oid
316
319
  JOIN pg_namespace n ON c.relnamespace = n.oid
@@ -333,6 +336,7 @@ export async function introspectDatabase(connection, onProgress, options) {
333
336
  functionName: t.function_name,
334
337
  definition: t.definition || '',
335
338
  isEnabled: t.is_enabled,
339
+ comment: t.comment || undefined,
336
340
  }));
337
341
  }
338
342
  const policiesResult = await pool.query(`
@@ -630,6 +630,7 @@ export const smallserial = (columnName) => createColumnWithName('SMALLSERIAL', c
630
630
  export const serial2 = smallserial;
631
631
  export const bigserial = (columnName) => createColumnWithName('BIGSERIAL', columnName);
632
632
  export const serial8 = bigserial;
633
+ export const epoch = (columnName) => createColumnWithName('BIGINT', columnName);
633
634
  export const decimal = (columnNameOrOpts, scale) => {
634
635
  if (typeof columnNameOrOpts === 'string' && !columnNameOrOpts.includes('.')) {
635
636
  return createColumnWithName('DECIMAL', columnNameOrOpts);
@@ -18,6 +18,8 @@ export const DEFAULT = {
18
18
  clockTimestamp: () => createDefault('clock_timestamp()'),
19
19
  timeofday: () => createDefault('timeofday()'),
20
20
  interval: (value) => createDefault(`INTERVAL '${value}'`),
21
+ epochNow: () => createDefault('(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint'),
22
+ epochSeconds: () => createDefault('EXTRACT(EPOCH FROM NOW())::bigint'),
21
23
  currentUser: () => createDefault('CURRENT_USER'),
22
24
  sessionUser: () => createDefault('SESSION_USER'),
23
25
  user: () => createDefault('USER'),
@@ -7,7 +7,12 @@ export function generateFunctionSQL(config) {
7
7
  if (arg.mode && arg.mode !== 'IN') {
8
8
  argStr += arg.mode + ' ';
9
9
  }
10
- argStr += arg.name + ' ' + arg.type;
10
+ if (arg.name) {
11
+ argStr += arg.name + ' ' + arg.type;
12
+ }
13
+ else {
14
+ argStr += arg.type;
15
+ }
11
16
  if (arg.default !== undefined) {
12
17
  argStr += ' DEFAULT ' + arg.default;
13
18
  }
@@ -23,6 +23,10 @@ export declare const DEFAULT: {
23
23
  readonly clockTimestamp: () => DefaultValue;
24
24
  readonly timeofday: () => DefaultValue;
25
25
  readonly interval: (value: string) => DefaultValue;
26
+ /** Current time as epoch milliseconds (BIGINT) - use with epoch() column */
27
+ readonly epochNow: () => DefaultValue;
28
+ /** Current time as epoch seconds (BIGINT) */
29
+ readonly epochSeconds: () => DefaultValue;
26
30
  readonly currentUser: () => DefaultValue;
27
31
  readonly sessionUser: () => DefaultValue;
28
32
  readonly user: () => DefaultValue;
@@ -978,6 +982,17 @@ export declare const smallserial: (columnName?: string) => ColumnBuilder<number,
978
982
  export declare const serial2: (columnName?: string) => ColumnBuilder<number, ColumnConfig<number>>;
979
983
  export declare const bigserial: (columnName?: string) => ColumnBuilder<bigint, ColumnConfig<bigint>>;
980
984
  export declare const serial8: (columnName?: string) => ColumnBuilder<bigint, ColumnConfig<bigint>>;
985
+ /**
986
+ * Epoch timestamp column (BIGINT storing milliseconds since Unix epoch)
987
+ * Use with DEFAULT.epochNow() for auto-generated timestamps
988
+ *
989
+ * @example
990
+ * ```typescript
991
+ * createdAt: epoch().default(DEFAULT.epochNow()),
992
+ * updatedAt: epoch().default(DEFAULT.epochNow()),
993
+ * ```
994
+ */
995
+ export declare const epoch: (columnName?: string) => ColumnBuilder<number, ColumnConfig<number>>;
981
996
  export declare const decimal: (columnNameOrOpts?: string | number | {
982
997
  precision?: number;
983
998
  scale?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relq",
3
- "version": "1.0.58",
3
+ "version": "1.0.60",
4
4
  "description": "The Fully-Typed PostgreSQL ORM for TypeScript",
5
5
  "author": "Olajide Mathew O. <olajide.mathew@yuniq.solutions>",
6
6
  "license": "MIT",