@krantho/persistence-postgres 0.0.0-stage → 1.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.
Files changed (127) hide show
  1. package/LICENSE +21 -0
  2. package/dist/auth-adapter.d.ts +23 -0
  3. package/dist/auth-adapter.d.ts.map +1 -0
  4. package/dist/auth-adapter.js +159 -0
  5. package/dist/auth-adapter.js.map +1 -0
  6. package/dist/content-migration.d.ts +14 -0
  7. package/dist/content-migration.d.ts.map +1 -0
  8. package/dist/content-migration.js +64 -0
  9. package/dist/content-migration.js.map +1 -0
  10. package/dist/content-query.d.ts +23 -0
  11. package/dist/content-query.d.ts.map +1 -0
  12. package/dist/content-query.js +170 -0
  13. package/dist/content-query.js.map +1 -0
  14. package/dist/index.d.ts +17 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +15 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/migration-runner.d.ts +29 -0
  19. package/dist/migration-runner.d.ts.map +1 -0
  20. package/dist/migration-runner.js +123 -0
  21. package/dist/migration-runner.js.map +1 -0
  22. package/dist/migrations/index.d.ts +4 -0
  23. package/dist/migrations/index.d.ts.map +1 -0
  24. package/dist/migrations/index.js +32 -0
  25. package/dist/migrations/index.js.map +1 -0
  26. package/dist/migrations/v001-initial-schema.d.ts +10 -0
  27. package/dist/migrations/v001-initial-schema.d.ts.map +1 -0
  28. package/dist/migrations/v001-initial-schema.js +94 -0
  29. package/dist/migrations/v001-initial-schema.js.map +1 -0
  30. package/dist/migrations/v002-auth-tables.d.ts +8 -0
  31. package/dist/migrations/v002-auth-tables.d.ts.map +1 -0
  32. package/dist/migrations/v002-auth-tables.js +37 -0
  33. package/dist/migrations/v002-auth-tables.js.map +1 -0
  34. package/dist/migrations/v003-user-permissions.d.ts +6 -0
  35. package/dist/migrations/v003-user-permissions.d.ts.map +1 -0
  36. package/dist/migrations/v003-user-permissions.js +18 -0
  37. package/dist/migrations/v003-user-permissions.js.map +1 -0
  38. package/dist/migrations/v004-media-hotspot.d.ts +14 -0
  39. package/dist/migrations/v004-media-hotspot.d.ts.map +1 -0
  40. package/dist/migrations/v004-media-hotspot.js +25 -0
  41. package/dist/migrations/v004-media-hotspot.js.map +1 -0
  42. package/dist/migrations/v005-content-locks.d.ts +6 -0
  43. package/dist/migrations/v005-content-locks.d.ts.map +1 -0
  44. package/dist/migrations/v005-content-locks.js +21 -0
  45. package/dist/migrations/v005-content-locks.js.map +1 -0
  46. package/dist/migrations/v006-webhook-deliveries.d.ts +6 -0
  47. package/dist/migrations/v006-webhook-deliveries.d.ts.map +1 -0
  48. package/dist/migrations/v006-webhook-deliveries.js +24 -0
  49. package/dist/migrations/v006-webhook-deliveries.js.map +1 -0
  50. package/dist/migrations/v007-media-folders.d.ts +6 -0
  51. package/dist/migrations/v007-media-folders.d.ts.map +1 -0
  52. package/dist/migrations/v007-media-folders.js +19 -0
  53. package/dist/migrations/v007-media-folders.js.map +1 -0
  54. package/dist/migrations/v008-site-settings.d.ts +6 -0
  55. package/dist/migrations/v008-site-settings.d.ts.map +1 -0
  56. package/dist/migrations/v008-site-settings.js +17 -0
  57. package/dist/migrations/v008-site-settings.js.map +1 -0
  58. package/dist/migrations/v009-seo-config.d.ts +12 -0
  59. package/dist/migrations/v009-seo-config.d.ts.map +1 -0
  60. package/dist/migrations/v009-seo-config.js +27 -0
  61. package/dist/migrations/v009-seo-config.js.map +1 -0
  62. package/dist/migrations/v010-content-live-version.d.ts +15 -0
  63. package/dist/migrations/v010-content-live-version.d.ts.map +1 -0
  64. package/dist/migrations/v010-content-live-version.js +40 -0
  65. package/dist/migrations/v010-content-live-version.js.map +1 -0
  66. package/dist/migrations/v011-media.d.ts +12 -0
  67. package/dist/migrations/v011-media.d.ts.map +1 -0
  68. package/dist/migrations/v011-media.js +43 -0
  69. package/dist/migrations/v011-media.js.map +1 -0
  70. package/dist/migrations/v012-page-cache.d.ts +12 -0
  71. package/dist/migrations/v012-page-cache.d.ts.map +1 -0
  72. package/dist/migrations/v012-page-cache.js +31 -0
  73. package/dist/migrations/v012-page-cache.js.map +1 -0
  74. package/dist/migrations/v013-content-contracts.d.ts +17 -0
  75. package/dist/migrations/v013-content-contracts.d.ts.map +1 -0
  76. package/dist/migrations/v013-content-contracts.js +41 -0
  77. package/dist/migrations/v013-content-contracts.js.map +1 -0
  78. package/dist/migrations/v014-content-manifest-commit.d.ts +7 -0
  79. package/dist/migrations/v014-content-manifest-commit.d.ts.map +1 -0
  80. package/dist/migrations/v014-content-manifest-commit.js +12 -0
  81. package/dist/migrations/v014-content-manifest-commit.js.map +1 -0
  82. package/dist/postgres-adapter.d.ts +71 -0
  83. package/dist/postgres-adapter.d.ts.map +1 -0
  84. package/dist/postgres-adapter.js +327 -0
  85. package/dist/postgres-adapter.js.map +1 -0
  86. package/dist/postgres-checkpoints.d.ts +20 -0
  87. package/dist/postgres-checkpoints.d.ts.map +1 -0
  88. package/dist/postgres-checkpoints.js +109 -0
  89. package/dist/postgres-checkpoints.js.map +1 -0
  90. package/dist/postgres-lock-adapter.d.ts +12 -0
  91. package/dist/postgres-lock-adapter.d.ts.map +1 -0
  92. package/dist/postgres-lock-adapter.js +62 -0
  93. package/dist/postgres-lock-adapter.js.map +1 -0
  94. package/dist/postgres-media-adapter.d.ts +28 -0
  95. package/dist/postgres-media-adapter.d.ts.map +1 -0
  96. package/dist/postgres-media-adapter.js +167 -0
  97. package/dist/postgres-media-adapter.js.map +1 -0
  98. package/dist/postgres-media-folder-adapter.d.ts +12 -0
  99. package/dist/postgres-media-folder-adapter.d.ts.map +1 -0
  100. package/dist/postgres-media-folder-adapter.js +60 -0
  101. package/dist/postgres-media-folder-adapter.js.map +1 -0
  102. package/dist/postgres-page-cache-store.d.ts +23 -0
  103. package/dist/postgres-page-cache-store.d.ts.map +1 -0
  104. package/dist/postgres-page-cache-store.js +80 -0
  105. package/dist/postgres-page-cache-store.js.map +1 -0
  106. package/dist/postgres-retention-adapter.d.ts +14 -0
  107. package/dist/postgres-retention-adapter.d.ts.map +1 -0
  108. package/dist/postgres-retention-adapter.js +61 -0
  109. package/dist/postgres-retention-adapter.js.map +1 -0
  110. package/dist/postgres-seo-config-adapter.d.ts +14 -0
  111. package/dist/postgres-seo-config-adapter.d.ts.map +1 -0
  112. package/dist/postgres-seo-config-adapter.js +59 -0
  113. package/dist/postgres-seo-config-adapter.js.map +1 -0
  114. package/dist/postgres-site-settings-adapter.d.ts +11 -0
  115. package/dist/postgres-site-settings-adapter.d.ts.map +1 -0
  116. package/dist/postgres-site-settings-adapter.js +30 -0
  117. package/dist/postgres-site-settings-adapter.js.map +1 -0
  118. package/dist/postgres-webhook-delivery-adapter.d.ts +27 -0
  119. package/dist/postgres-webhook-delivery-adapter.d.ts.map +1 -0
  120. package/dist/postgres-webhook-delivery-adapter.js +99 -0
  121. package/dist/postgres-webhook-delivery-adapter.js.map +1 -0
  122. package/dist/row-mapping.d.ts +40 -0
  123. package/dist/row-mapping.d.ts.map +1 -0
  124. package/dist/row-mapping.js +49 -0
  125. package/dist/row-mapping.js.map +1 -0
  126. package/package.json +39 -3
  127. package/README.md +0 -3
@@ -0,0 +1,99 @@
1
+ import { MAX_WEBHOOK_ATTEMPTS } from '@krantho/persistence';
2
+ /** A delivery is failed when it was never delivered and has used every attempt */
3
+ const FAILED = `delivered_at IS NULL AND attempts >= ${MAX_WEBHOOK_ATTEMPTS}`;
4
+ /** The columns of a delivery; the payload is JSONB, read back as the JSON text */
5
+ const COLUMNS = 'id, webhook_url, event, payload::text AS payload, status, attempts, next_retry_at, created_at, delivered_at';
6
+ function iso(value) {
7
+ return value === null ? null : value.toISOString();
8
+ }
9
+ function toRecord(row) {
10
+ return {
11
+ id: row.id,
12
+ url: row.webhook_url,
13
+ event: row.event,
14
+ status: row.status,
15
+ attempts: row.attempts,
16
+ nextRetryAt: iso(row.next_retry_at),
17
+ createdAt: row.created_at.toISOString(),
18
+ deliveredAt: iso(row.delivered_at),
19
+ };
20
+ }
21
+ /** Postgres implementation of webhook delivery log */
22
+ export class PostgresWebhookDeliveryAdapter {
23
+ sql;
24
+ constructor(sql) {
25
+ this.sql = sql;
26
+ }
27
+ async listDeliveries(options) {
28
+ let where = '1=1';
29
+ if (options.status === 'pending') {
30
+ where = `delivered_at IS NULL AND attempts < ${MAX_WEBHOOK_ATTEMPTS}`;
31
+ }
32
+ else if (options.status === 'delivered') {
33
+ where = 'delivered_at IS NOT NULL';
34
+ }
35
+ else if (options.status === 'failed') {
36
+ where = `delivered_at IS NULL AND attempts >= ${MAX_WEBHOOK_ATTEMPTS}`;
37
+ }
38
+ const countRows = (await this.sql.unsafe(`SELECT COUNT(*) as count FROM webhook_deliveries WHERE ${where}`));
39
+ const total = parseInt(countRows[0]?.count ?? '0', 10);
40
+ const rows = (await this.sql.unsafe(`SELECT ${COLUMNS} FROM webhook_deliveries WHERE ${where} ORDER BY created_at DESC LIMIT $1 OFFSET $2`, [options.limit, options.offset]));
41
+ return { deliveries: rows.map(toRecord), total };
42
+ }
43
+ async getDelivery(id) {
44
+ const rows = (await this.sql.unsafe(`SELECT ${COLUMNS} FROM webhook_deliveries WHERE id = $1`, [
45
+ id,
46
+ ]));
47
+ const row = rows[0];
48
+ return row ? { ...toRecord(row), payload: row.payload } : null;
49
+ }
50
+ async requeueDelivery(id, dueAt) {
51
+ const rows = (await this.sql.unsafe(`UPDATE webhook_deliveries SET attempts = $1, next_retry_at = $2::timestamptz
52
+ WHERE id = $3 AND ${FAILED} RETURNING ${COLUMNS}`, [MAX_WEBHOOK_ATTEMPTS - 1, dueAt.toISOString(), id]));
53
+ const row = rows[0];
54
+ return row ? toRecord(row) : null;
55
+ }
56
+ async logDelivery(delivery) {
57
+ // The payload binds as text and is cast, so the driver does not encode it a second time
58
+ const rows = await this.sql `
59
+ INSERT INTO webhook_deliveries (webhook_url, event, payload, attempts, next_retry_at)
60
+ VALUES (${delivery.url}, ${delivery.event}, ${delivery.payload}::text::jsonb, 1,
61
+ ${delivery.retryAt.toISOString()}::timestamptz)
62
+ RETURNING id`;
63
+ const row = rows[0];
64
+ if (!row)
65
+ throw new Error('Logging a webhook delivery returned no id');
66
+ return row.id;
67
+ }
68
+ async markDelivered(id, status) {
69
+ await this.sql `
70
+ UPDATE webhook_deliveries SET status = ${status}, delivered_at = NOW() WHERE id = ${id}`;
71
+ }
72
+ async markFailed(id, status, nextRetryAt) {
73
+ await this.sql `
74
+ UPDATE webhook_deliveries
75
+ SET status = ${status}, attempts = attempts + 1,
76
+ next_retry_at = ${nextRetryAt.toISOString()}::timestamptz
77
+ WHERE id = ${id}`;
78
+ }
79
+ async claimDueDeliveries(options) {
80
+ if (options.urls.length === 0)
81
+ return [];
82
+ // SKIP LOCKED: rows another instance is claiming at this moment are left to it
83
+ const rows = await this.sql `
84
+ UPDATE webhook_deliveries SET next_retry_at = ${options.leaseUntil.toISOString()}::timestamptz
85
+ WHERE id IN (
86
+ SELECT id FROM webhook_deliveries
87
+ WHERE delivered_at IS NULL AND attempts < ${MAX_WEBHOOK_ATTEMPTS}
88
+ AND (next_retry_at IS NULL OR next_retry_at <= ${options.now.toISOString()}::timestamptz)
89
+ AND webhook_url IN ${this.sql(options.urls)}
90
+ ORDER BY created_at, id LIMIT ${options.limit}
91
+ FOR UPDATE SKIP LOCKED
92
+ )
93
+ RETURNING ${this.sql.unsafe(COLUMNS)}`;
94
+ return [...rows]
95
+ .sort((a, b) => a.created_at.getTime() - b.created_at.getTime() || a.id - b.id)
96
+ .map((row) => ({ ...toRecord(row), payload: row.payload }));
97
+ }
98
+ }
99
+ //# sourceMappingURL=postgres-webhook-delivery-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-webhook-delivery-adapter.js","sourceRoot":"","sources":["../src/postgres-webhook-delivery-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { AuthoredMetadata, ContentDocument, ContentSummary, DocumentMeta } from '@krantho/persistence';
2
+ /** Row shape from the append-only content table */
3
+ export interface ContentRow {
4
+ id: string;
5
+ collection: string;
6
+ slug: string;
7
+ locale: string;
8
+ version: number;
9
+ is_current: boolean;
10
+ status: string;
11
+ authored: AuthoredMetadata;
12
+ fields: Record<string, unknown>;
13
+ body: string;
14
+ html: string;
15
+ sections: Record<string, string>;
16
+ source: string;
17
+ file_path: string | null;
18
+ changed_by: string | null;
19
+ deleted_at: Date | null;
20
+ created_at: Date;
21
+ /** The document's live version as of this row; NULL when nothing is live */
22
+ live_version: number | null;
23
+ }
24
+ /** A content row read without its body, rendered HTML and sections */
25
+ export type SummaryRow = Omit<ContentRow, 'body' | 'html' | 'sections' | 'authored'> & {
26
+ /** `authored.metadata` alone: the contract and provenance stay in the row */
27
+ metadata: AuthoredMetadata['metadata'] | null;
28
+ };
29
+ /** A content row read with neither its fields nor its body, rendered HTML and sections */
30
+ export type MetaRow = Omit<SummaryRow, 'fields' | 'metadata'>;
31
+ /** The columns of a content row that make up a document's meta */
32
+ export declare const META_COLUMNS = "id, collection, slug, locale, version, is_current, status, source, file_path, changed_by, deleted_at, created_at, live_version";
33
+ /** The columns of a content row that name a document: everything but its body, HTML and sections */
34
+ export declare const SUMMARY_COLUMNS = "id, collection, slug, locale, version, is_current, status, fields, authored->'metadata' AS metadata, source, file_path, changed_by, deleted_at, created_at, live_version";
35
+ /** Valid scalar types accepted by `sql.unsafe()` positional parameters. */
36
+ export type SqlParam = string | number | boolean | null;
37
+ export declare function rowToContentDocument(row: ContentRow): ContentDocument;
38
+ export declare function rowToSummary(row: SummaryRow): ContentSummary;
39
+ export declare function rowToDocumentMeta(row: MetaRow): DocumentMeta;
40
+ //# sourceMappingURL=row-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-mapping.d.ts","sourceRoot":"","sources":["../src/row-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,YAAY,EAIb,MAAM,sBAAsB,CAAA;AAO7B,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,OAAO,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAA;IACvB,UAAU,EAAE,IAAI,CAAA;IAChB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC,GAAG;IACrF,6EAA6E;IAC7E,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,GAAG,IAAI,CAAA;CAC9C,CAAA;AAED,0FAA0F;AAC1F,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAA;AAE7D,kEAAkE;AAClE,eAAO,MAAM,YAAY,mIACyG,CAAA;AAElI,oGAAoG;AACpG,eAAO,MAAM,eAAe,6KACgJ,CAAA;AAE5K,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AAwCvD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,GAAG,eAAe,CAErE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,cAAc,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAE5D"}
@@ -0,0 +1,49 @@
1
+ import { contentDocumentFromRow, contentSummaryFromRow, documentMetaFromRow, } from '@krantho/persistence';
2
+ /** The columns of a content row that make up a document's meta */
3
+ export const META_COLUMNS = 'id, collection, slug, locale, version, is_current, status, source, file_path, changed_by, deleted_at, created_at, live_version';
4
+ /** The columns of a content row that name a document: everything but its body, HTML and sections */
5
+ export const SUMMARY_COLUMNS = "id, collection, slug, locale, version, is_current, status, fields, authored->'metadata' AS metadata, source, file_path, changed_by, deleted_at, created_at, live_version";
6
+ /**
7
+ * Normalize a raw Postgres row into the canonical shape shared by every adapter.
8
+ *
9
+ * This is the only place in the Postgres adapter that coerces `Date` to ISO
10
+ * strings or falls back null `html` / `sections` columns. All downstream
11
+ * conversions go through the shared helpers in `@krantho/persistence`.
12
+ */
13
+ function normalizeMetaRow(row) {
14
+ return {
15
+ collection: row.collection,
16
+ slug: row.slug,
17
+ locale: row.locale,
18
+ version: row.version,
19
+ liveVersion: row.live_version,
20
+ status: row.status,
21
+ source: row.source,
22
+ changedBy: row.changed_by,
23
+ createdAt: row.created_at instanceof Date ? row.created_at.toISOString() : String(row.created_at),
24
+ };
25
+ }
26
+ function normalizeSummaryRow(row) {
27
+ return { ...normalizeMetaRow(row), fields: row.fields, metadata: row.metadata ?? {} };
28
+ }
29
+ function normalizeRow(row) {
30
+ return {
31
+ ...normalizeMetaRow(row),
32
+ fields: row.fields,
33
+ metadata: row.authored.metadata,
34
+ authored: row.authored,
35
+ body: row.body,
36
+ html: row.html ?? '',
37
+ sections: row.sections ?? {},
38
+ };
39
+ }
40
+ export function rowToContentDocument(row) {
41
+ return contentDocumentFromRow(normalizeRow(row));
42
+ }
43
+ export function rowToSummary(row) {
44
+ return contentSummaryFromRow(normalizeSummaryRow(row));
45
+ }
46
+ export function rowToDocumentMeta(row) {
47
+ return documentMetaFromRow(normalizeMetaRow(row));
48
+ }
49
+ //# sourceMappingURL=row-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-mapping.js","sourceRoot":"","sources":["../src/row-mapping.ts"],"names":[],"mappings":"AASA,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,sBAAsB,CAAA;AAkC7B,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GACvB,gIAAgI,CAAA;AAElI,oGAAoG;AACpG,MAAM,CAAC,MAAM,eAAe,GAC1B,0KAA0K,CAAA;AAK5K;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,GAAY;IACpC,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,SAAS,EACP,GAAG,CAAC,UAAU,YAAY,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;KACzF,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAe;IAC1C,OAAO,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAA;AACvF,CAAC;AAED,SAAS,YAAY,CAAC,GAAe;IACnC,OAAO;QACL,GAAG,gBAAgB,CAAC,GAAG,CAAC;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ;QAC/B,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE;QACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;KAC7B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAe;IAClD,OAAO,sBAAsB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAe;IAC1C,OAAO,qBAAqB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC5C,OAAO,mBAAmB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAA;AACnD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@krantho/persistence-postgres",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.1",
4
+ "description": "The krantho persistence adapter for Postgres, the production store for serverless hosts and several instances.",
5
+ "license": "MIT",
6
+ "homepage": "https://krantho.com",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/descoped/krantho.git",
10
+ "directory": "packages/persistence-postgres"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/descoped/krantho/issues"
14
+ },
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "dependencies": {
26
+ "postgres": "^3.4.9",
27
+ "@krantho/core": "1.0.1",
28
+ "@krantho/seo-shared": "1.0.1",
29
+ "@krantho/persistence": "1.0.1"
30
+ },
31
+ "devDependencies": {
32
+ "@testcontainers/postgresql": "^12.2.1",
33
+ "@types/node": "^25.9.9",
34
+ "typescript": "^6.0.3",
35
+ "@krantho/persistence-sqlite": "1.0.1"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "typecheck": "tsc --noEmit",
40
+ "clean": "rm -rf dist"
41
+ }
6
42
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.