@columnus/shared 0.1.47
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/LICENSE +21 -0
- package/dist/apiProfile.d.ts +1072 -0
- package/dist/apiProfile.js +4210 -0
- package/dist/apiProfile.js.map +1 -0
- package/dist/apiProfileSlug.d.ts +11 -0
- package/dist/apiProfileSlug.js +39 -0
- package/dist/apiProfileSlug.js.map +1 -0
- package/dist/apiToken.d.ts +6 -0
- package/dist/apiToken.js +35 -0
- package/dist/apiToken.js.map +1 -0
- package/dist/betterAuthSession.d.ts +8 -0
- package/dist/betterAuthSession.js +57 -0
- package/dist/betterAuthSession.js.map +1 -0
- package/dist/bffHost.d.ts +36 -0
- package/dist/bffHost.js +74 -0
- package/dist/bffHost.js.map +1 -0
- package/dist/bffProtocol.d.ts +1357 -0
- package/dist/bffProtocol.js +4362 -0
- package/dist/bffProtocol.js.map +1 -0
- package/dist/bffRedact.d.ts +30 -0
- package/dist/bffRedact.js +55 -0
- package/dist/bffRedact.js.map +1 -0
- package/dist/ciPreviewEnv.d.ts +49 -0
- package/dist/ciPreviewEnv.js +143 -0
- package/dist/ciPreviewEnv.js.map +1 -0
- package/dist/clipboardTransfer.d.ts +25 -0
- package/dist/clipboardTransfer.js +4862 -0
- package/dist/clipboardTransfer.js.map +1 -0
- package/dist/convexSiteUrl.d.ts +73 -0
- package/dist/convexSiteUrl.js +137 -0
- package/dist/convexSiteUrl.js.map +1 -0
- package/dist/csv.d.ts +54 -0
- package/dist/csv.js +5499 -0
- package/dist/csv.js.map +1 -0
- package/dist/dataTransfer.d.ts +21 -0
- package/dist/dataTransfer.js +74 -0
- package/dist/dataTransfer.js.map +1 -0
- package/dist/dateValues.d.ts +18 -0
- package/dist/dateValues.js +73 -0
- package/dist/dateValues.js.map +1 -0
- package/dist/deployOutput.d.ts +3 -0
- package/dist/deployOutput.js +23 -0
- package/dist/deployOutput.js.map +1 -0
- package/dist/displayLabel.d.ts +13 -0
- package/dist/displayLabel.js +4342 -0
- package/dist/displayLabel.js.map +1 -0
- package/dist/displayTemplateGenerator.d.ts +11 -0
- package/dist/displayTemplateGenerator.js +98 -0
- package/dist/displayTemplateGenerator.js.map +1 -0
- package/dist/displayTypes.d.ts +10 -0
- package/dist/displayTypes.js +3 -0
- package/dist/displayTypes.js.map +1 -0
- package/dist/dotenv.d.ts +8 -0
- package/dist/dotenv.js +61 -0
- package/dist/dotenv.js.map +1 -0
- package/dist/erdLayout.d.ts +27 -0
- package/dist/erdLayout.js +78 -0
- package/dist/erdLayout.js.map +1 -0
- package/dist/fieldTypeFormat.d.ts +5 -0
- package/dist/fieldTypeFormat.js +63 -0
- package/dist/fieldTypeFormat.js.map +1 -0
- package/dist/fieldTypeMeta.d.ts +50 -0
- package/dist/fieldTypeMeta.js +84 -0
- package/dist/fieldTypeMeta.js.map +1 -0
- package/dist/fieldValueEqual.d.ts +4 -0
- package/dist/fieldValueEqual.js +58 -0
- package/dist/fieldValueEqual.js.map +1 -0
- package/dist/importMatch.d.ts +80 -0
- package/dist/importMatch.js +5643 -0
- package/dist/importMatch.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +10647 -0
- package/dist/index.js.map +1 -0
- package/dist/inferIdentifier.d.ts +18 -0
- package/dist/inferIdentifier.js +49 -0
- package/dist/inferIdentifier.js.map +1 -0
- package/dist/keyboard.d.ts +16 -0
- package/dist/keyboard.js +71 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/manifestDeploy.d.ts +27 -0
- package/dist/manifestDeploy.js +16 -0
- package/dist/manifestDeploy.js.map +1 -0
- package/dist/manifestHash.d.ts +11 -0
- package/dist/manifestHash.js +35 -0
- package/dist/manifestHash.js.map +1 -0
- package/dist/previewDeployName.d.ts +26 -0
- package/dist/previewDeployName.js +77 -0
- package/dist/previewDeployName.js.map +1 -0
- package/dist/proposePolicy.d.ts +17 -0
- package/dist/proposePolicy.js +33 -0
- package/dist/proposePolicy.js.map +1 -0
- package/dist/queryBetween.d.ts +20 -0
- package/dist/queryBetween.js +28 -0
- package/dist/queryBetween.js.map +1 -0
- package/dist/queryExecution.d.ts +5 -0
- package/dist/queryExecution.js +58 -0
- package/dist/queryExecution.js.map +1 -0
- package/dist/queryFieldOps.d.ts +66 -0
- package/dist/queryFieldOps.js +138 -0
- package/dist/queryFieldOps.js.map +1 -0
- package/dist/queryMerge.d.ts +29 -0
- package/dist/queryMerge.js +4277 -0
- package/dist/queryMerge.js.map +1 -0
- package/dist/queryPlan.d.ts +97 -0
- package/dist/queryPlan.js +4564 -0
- package/dist/queryPlan.js.map +1 -0
- package/dist/queryStudio.d.ts +25 -0
- package/dist/queryStudio.js +4658 -0
- package/dist/queryStudio.js.map +1 -0
- package/dist/queryTypes.d.ts +402 -0
- package/dist/queryTypes.js +4239 -0
- package/dist/queryTypes.js.map +1 -0
- package/dist/queryValidators.d.ts +99 -0
- package/dist/queryValidators.js +76 -0
- package/dist/queryValidators.js.map +1 -0
- package/dist/readApiQuery.d.ts +10 -0
- package/dist/readApiQuery.js +24 -0
- package/dist/readApiQuery.js.map +1 -0
- package/dist/recordTableColumns.d.ts +21 -0
- package/dist/recordTableColumns.js +4469 -0
- package/dist/recordTableColumns.js.map +1 -0
- package/dist/refDisplayRequests.d.ts +17 -0
- package/dist/refDisplayRequests.js +4877 -0
- package/dist/refDisplayRequests.js.map +1 -0
- package/dist/refGraph.d.ts +23 -0
- package/dist/refGraph.js +102 -0
- package/dist/refGraph.js.map +1 -0
- package/dist/refsRecompute.d.ts +8 -0
- package/dist/refsRecompute.js +12 -0
- package/dist/refsRecompute.js.map +1 -0
- package/dist/richDoc.d.ts +67 -0
- package/dist/richDoc.js +4408 -0
- package/dist/richDoc.js.map +1 -0
- package/dist/schemaGenerator.d.ts +31 -0
- package/dist/schemaGenerator.js +198 -0
- package/dist/schemaGenerator.js.map +1 -0
- package/dist/schemaShrink.d.ts +74 -0
- package/dist/schemaShrink.js +132 -0
- package/dist/schemaShrink.js.map +1 -0
- package/dist/schemaShrinkValidators.d.ts +72 -0
- package/dist/schemaShrinkValidators.js +31 -0
- package/dist/schemaShrinkValidators.js.map +1 -0
- package/dist/schemaTypes.d.ts +454 -0
- package/dist/schemaTypes.js +4557 -0
- package/dist/schemaTypes.js.map +1 -0
- package/dist/share.d.ts +8 -0
- package/dist/share.js +4755 -0
- package/dist/share.js.map +1 -0
- package/dist/shareApiBridge.d.ts +18 -0
- package/dist/shareApiBridge.js +4283 -0
- package/dist/shareApiBridge.js.map +1 -0
- package/dist/shareGuestPolicy.d.ts +14 -0
- package/dist/shareGuestPolicy.js +90 -0
- package/dist/shareGuestPolicy.js.map +1 -0
- package/dist/shareProposal.d.ts +113 -0
- package/dist/shareProposal.js +4810 -0
- package/dist/shareProposal.js.map +1 -0
- package/dist/shareProposalDiff.d.ts +13 -0
- package/dist/shareProposalDiff.js +91 -0
- package/dist/shareProposalDiff.js.map +1 -0
- package/dist/shareScopes.d.ts +14 -0
- package/dist/shareScopes.js +223 -0
- package/dist/shareScopes.js.map +1 -0
- package/dist/shareTokenCrypto.d.ts +9 -0
- package/dist/shareTokenCrypto.js +87 -0
- package/dist/shareTokenCrypto.js.map +1 -0
- package/dist/shareTokens.d.ts +6 -0
- package/dist/shareTokens.js +26 -0
- package/dist/shareTokens.js.map +1 -0
- package/dist/shareTypes.d.ts +107 -0
- package/dist/shareTypes.js +3 -0
- package/dist/shareTypes.js.map +1 -0
- package/dist/shareValidators.d.ts +168 -0
- package/dist/shareValidators.js +124 -0
- package/dist/shareValidators.js.map +1 -0
- package/dist/shareWizard.d.ts +14 -0
- package/dist/shareWizard.js +200 -0
- package/dist/shareWizard.js.map +1 -0
- package/dist/spaceBundle.d.ts +67 -0
- package/dist/spaceBundle.js +4664 -0
- package/dist/spaceBundle.js.map +1 -0
- package/dist/storageFieldValues.d.ts +10 -0
- package/dist/storageFieldValues.js +4421 -0
- package/dist/storageFieldValues.js.map +1 -0
- package/dist/studioBoot.d.ts +49 -0
- package/dist/studioBoot.js +167 -0
- package/dist/studioBoot.js.map +1 -0
- package/dist/syncClampMembership.d.ts +22 -0
- package/dist/syncClampMembership.js +74 -0
- package/dist/syncClampMembership.js.map +1 -0
- package/dist/tenantHosts.d.ts +30 -0
- package/dist/tenantHosts.js +60 -0
- package/dist/tenantHosts.js.map +1 -0
- package/dist/tenantSecretsCrypto.d.ts +31 -0
- package/dist/tenantSecretsCrypto.js +145 -0
- package/dist/tenantSecretsCrypto.js.map +1 -0
- package/dist/useDebouncedCommit.d.ts +11 -0
- package/dist/useDebouncedCommit.js +34 -0
- package/dist/useDebouncedCommit.js.map +1 -0
- package/dist/useDebouncedValue.d.ts +1 -0
- package/dist/useDebouncedValue.js +15 -0
- package/dist/useDebouncedValue.js.map +1 -0
- package/dist/useModifierHeld.d.ts +2 -0
- package/dist/useModifierHeld.js +28 -0
- package/dist/useModifierHeld.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redaction and secret-compare helpers for BFF / Management / deploy boundaries (D39).
|
|
3
|
+
* Prepared bodies and deploy keys must never appear in logs or error telemetry.
|
|
4
|
+
*/
|
|
5
|
+
export declare const REDACTED: "[REDACTED]";
|
|
6
|
+
/**
|
|
7
|
+
* Deep-clone a value for logs, replacing classified fields (including nested
|
|
8
|
+
* `payload` / `convexDeployKey`) with {@link REDACTED}.
|
|
9
|
+
*/
|
|
10
|
+
export declare function redactForLogs(value: unknown): unknown;
|
|
11
|
+
/** Redact known secret substrings from a free-form message. */
|
|
12
|
+
export declare function redactString(message: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Constant-time string equality for shared secrets.
|
|
15
|
+
* Works in Node and browsers (no `node:crypto` dependency).
|
|
16
|
+
*/
|
|
17
|
+
export declare function secretsEqual(provided: string | undefined, expected: string | undefined): boolean;
|
|
18
|
+
/** True when a key name is classified and must not be logged. */
|
|
19
|
+
export declare function isClassifiedKey(key: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Safe summary of a prepared-body envelope for structured logs:
|
|
22
|
+
* operation, tenant slug, protocol version — never the inner payload.
|
|
23
|
+
*/
|
|
24
|
+
export declare function summarizePreparedEnvelope(envelope: unknown): {
|
|
25
|
+
protocolVersion?: unknown;
|
|
26
|
+
operation?: unknown;
|
|
27
|
+
tenantSlug?: unknown;
|
|
28
|
+
correlationId?: unknown;
|
|
29
|
+
payload: typeof REDACTED;
|
|
30
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// packages/@columnus/shared/src/bffRedact.ts
|
|
2
|
+
var CLASSIFIED_KEY_RE = /^(convexDeployKey|deployKey|payload|authorization|token|password|secret)$/i;
|
|
3
|
+
var CLASSIFIED_SUBSTRING_RE = /(deploy[_-]?key|authorization|bearer\s+[A-Za-z0-9._~+/=-]+|prod:[A-Za-z0-9|._~+/-]+)/gi;
|
|
4
|
+
var REDACTED = "[REDACTED]";
|
|
5
|
+
function isRecord(value) {
|
|
6
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
function redactForLogs(value) {
|
|
9
|
+
if (value == null) return value;
|
|
10
|
+
if (typeof value === "string") return redactString(value);
|
|
11
|
+
if (typeof value !== "object") return value;
|
|
12
|
+
if (Array.isArray(value)) return value.map(redactForLogs);
|
|
13
|
+
const out = {};
|
|
14
|
+
for (const [key, child] of Object.entries(value)) {
|
|
15
|
+
if (CLASSIFIED_KEY_RE.test(key)) {
|
|
16
|
+
out[key] = REDACTED;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
out[key] = redactForLogs(child);
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
function redactString(message) {
|
|
24
|
+
return message.replace(CLASSIFIED_SUBSTRING_RE, REDACTED);
|
|
25
|
+
}
|
|
26
|
+
function secretsEqual(provided, expected) {
|
|
27
|
+
if (provided == null || expected == null) return false;
|
|
28
|
+
const a = encoder.encode(provided);
|
|
29
|
+
const b = encoder.encode(expected);
|
|
30
|
+
if (a.length !== b.length) return false;
|
|
31
|
+
let diff = 0;
|
|
32
|
+
for (let i = 0; i < a.length; i += 1) diff |= a[i] ^ b[i];
|
|
33
|
+
return diff === 0;
|
|
34
|
+
}
|
|
35
|
+
var encoder = new TextEncoder();
|
|
36
|
+
function isClassifiedKey(key) {
|
|
37
|
+
return CLASSIFIED_KEY_RE.test(key);
|
|
38
|
+
}
|
|
39
|
+
function summarizePreparedEnvelope(envelope) {
|
|
40
|
+
if (!isRecord(envelope)) {
|
|
41
|
+
return { payload: REDACTED };
|
|
42
|
+
}
|
|
43
|
+
const tenant = isRecord(envelope.tenant) ? envelope.tenant : void 0;
|
|
44
|
+
return {
|
|
45
|
+
protocolVersion: envelope.protocolVersion,
|
|
46
|
+
operation: envelope.operation,
|
|
47
|
+
tenantSlug: tenant?.slug,
|
|
48
|
+
correlationId: envelope.correlationId,
|
|
49
|
+
payload: REDACTED
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { REDACTED, isClassifiedKey, redactForLogs, redactString, secretsEqual, summarizePreparedEnvelope };
|
|
54
|
+
//# sourceMappingURL=bffRedact.js.map
|
|
55
|
+
//# sourceMappingURL=bffRedact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bffRedact.ts"],"names":[],"mappings":";AAKA,IAAM,iBAAA,GACJ,4EAAA;AAEF,IAAM,uBAAA,GACJ,wFAAA;AAEK,IAAM,QAAA,GAAW;AAExB,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAMO,SAAS,cAAc,KAAA,EAAyB;AACrD,EAAA,IAAI,KAAA,IAAS,MAAM,OAAO,KAAA;AAC1B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,aAAa,KAAK,CAAA;AACxD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,aAAa,CAAA;AACxD,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AAC3E,IAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,GAAG,CAAA,EAAG;AAC/B,MAAA,GAAA,CAAI,GAAG,CAAA,GAAI,QAAA;AACX,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI,aAAA,CAAc,KAAK,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,aAAa,OAAA,EAAyB;AACpD,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,uBAAA,EAAyB,QAAQ,CAAA;AAC1D;AAMO,SAAS,YAAA,CAAa,UAA8B,QAAA,EAAuC;AAChG,EAAA,IAAI,QAAA,IAAY,IAAA,IAAQ,QAAA,IAAY,IAAA,EAAM,OAAO,KAAA;AACjD,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AACjC,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AACjC,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAClC,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,IAAK,CAAA,EAAG,IAAA,IAAQ,CAAA,CAAE,CAAC,CAAA,GAAK,CAAA,CAAE,CAAC,CAAA;AACzD,EAAA,OAAO,IAAA,KAAS,CAAA;AAClB;AAEA,IAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAGzB,SAAS,gBAAgB,GAAA,EAAsB;AACpD,EAAA,OAAO,iBAAA,CAAkB,KAAK,GAAG,CAAA;AACnC;AAMO,SAAS,0BAA0B,QAAA,EAMxC;AACA,EAAA,IAAI,CAAC,QAAA,CAAS,QAAQ,CAAA,EAAG;AACvB,IAAA,OAAO,EAAE,SAAS,QAAA,EAAS;AAAA,EAC7B;AACA,EAAA,MAAM,SAAS,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,GAAI,SAAS,MAAA,GAAS,MAAA;AAC7D,EAAA,OAAO;AAAA,IACL,iBAAiB,QAAA,CAAS,eAAA;AAAA,IAC1B,WAAW,QAAA,CAAS,SAAA;AAAA,IACpB,YAAY,MAAA,EAAQ,IAAA;AAAA,IACpB,eAAe,QAAA,CAAS,aAAA;AAAA,IACxB,OAAA,EAAS;AAAA,GACX;AACF","file":"bffRedact.js","sourcesContent":["/**\n * Redaction and secret-compare helpers for BFF / Management / deploy boundaries (D39).\n * Prepared bodies and deploy keys must never appear in logs or error telemetry.\n */\n\nconst CLASSIFIED_KEY_RE =\n /^(convexDeployKey|deployKey|payload|authorization|token|password|secret)$/i;\n\nconst CLASSIFIED_SUBSTRING_RE =\n /(deploy[_-]?key|authorization|bearer\\s+[A-Za-z0-9._~+/=-]+|prod:[A-Za-z0-9|._~+/-]+)/gi;\n\nexport const REDACTED = \"[REDACTED]\" as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Deep-clone a value for logs, replacing classified fields (including nested\n * `payload` / `convexDeployKey`) with {@link REDACTED}.\n */\nexport function redactForLogs(value: unknown): unknown {\n if (value == null) return value;\n if (typeof value === \"string\") return redactString(value);\n if (typeof value !== \"object\") return value;\n if (Array.isArray(value)) return value.map(redactForLogs);\n const out: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (CLASSIFIED_KEY_RE.test(key)) {\n out[key] = REDACTED;\n continue;\n }\n out[key] = redactForLogs(child);\n }\n return out;\n}\n\n/** Redact known secret substrings from a free-form message. */\nexport function redactString(message: string): string {\n return message.replace(CLASSIFIED_SUBSTRING_RE, REDACTED);\n}\n\n/**\n * Constant-time string equality for shared secrets.\n * Works in Node and browsers (no `node:crypto` dependency).\n */\nexport function secretsEqual(provided: string | undefined, expected: string | undefined): boolean {\n if (provided == null || expected == null) return false;\n const a = encoder.encode(provided);\n const b = encoder.encode(expected);\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i += 1) diff |= a[i]! ^ b[i]!;\n return diff === 0;\n}\n\nconst encoder = new TextEncoder();\n\n/** True when a key name is classified and must not be logged. */\nexport function isClassifiedKey(key: string): boolean {\n return CLASSIFIED_KEY_RE.test(key);\n}\n\n/**\n * Safe summary of a prepared-body envelope for structured logs:\n * operation, tenant slug, protocol version — never the inner payload.\n */\nexport function summarizePreparedEnvelope(envelope: unknown): {\n protocolVersion?: unknown;\n operation?: unknown;\n tenantSlug?: unknown;\n correlationId?: unknown;\n payload: typeof REDACTED;\n} {\n if (!isRecord(envelope)) {\n return { payload: REDACTED };\n }\n const tenant = isRecord(envelope.tenant) ? envelope.tenant : undefined;\n return {\n protocolVersion: envelope.protocolVersion,\n operation: envelope.operation,\n tenantSlug: tenant?.slug,\n correlationId: envelope.correlationId,\n payload: REDACTED,\n };\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Parse and validate a git commit SHA (7–40 hex chars). */
|
|
2
|
+
export declare function parseGitSha(raw: string | undefined, label?: string): string;
|
|
3
|
+
export declare function defaultProdDeployUrl(domain?: string): string;
|
|
4
|
+
/** True for local defaults that should not beat Coolify preview deploy URLs. */
|
|
5
|
+
export declare function isLoopbackDeployServiceUrl(url: string): boolean;
|
|
6
|
+
/** Production shared deploy host (`deploy.columnus.app`), any path. */
|
|
7
|
+
export declare function isProdDeployServiceUrl(url: string, domain?: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* When on a PR preview host, return the per-PR deploy-service URL unless env already
|
|
10
|
+
* points at a non-production executor (deploy-preview or Coolify internal).
|
|
11
|
+
*
|
|
12
|
+
* Coolify often copies production `STUDIO_DEPLOY_URL=https://deploy.columnus.app/deploy`
|
|
13
|
+
* onto preview apps — that must not win over `deploy-preview-<pr>`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function derivePreviewStudioDeployUrl(env?: NodeJS.ProcessEnv, domain?: string): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Runtime deploy-service URL for Web BFF / container entrypoint.
|
|
18
|
+
*
|
|
19
|
+
* Prefer preview-derived `deploy-preview-<pr>`, else non-loopback `COLUMNUS_DEPLOY_SERVICE_URL`,
|
|
20
|
+
* else `STUDIO_DEPLOY_URL`, else loopback COLUMNUS, else local default.
|
|
21
|
+
*
|
|
22
|
+
* Callers that need an origin (no path) should normalize with deploy-service helpers.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveRuntimeDeployServiceUrl(env?: NodeJS.ProcessEnv, domain?: string): string;
|
|
25
|
+
/** Coolify internal URL for columnus-deploy preview container (build-time manifest sync). */
|
|
26
|
+
export declare function derivePreviewDeployBuildUrl(env?: NodeJS.ProcessEnv): string | null;
|
|
27
|
+
export type ResolveSyncDeployUrlResult = {
|
|
28
|
+
ok: true;
|
|
29
|
+
url: string;
|
|
30
|
+
derivedMessage?: string;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
/** URL for `sync-manifest-deploy` during Docker/CI builds. */
|
|
36
|
+
export declare function resolveSyncDeployUrl(env: NodeJS.ProcessEnv, studioDeployUrl: string, isPreviewBuild: boolean): ResolveSyncDeployUrlResult;
|
|
37
|
+
export type PreviewSourceCommitResult = {
|
|
38
|
+
ok: true;
|
|
39
|
+
commit: string;
|
|
40
|
+
required: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
ok: false;
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
/** Validates SOURCE_COMMIT for Coolify preview builds (skipped when CI_PREVIEW=true). */
|
|
46
|
+
export declare function validatePreviewSourceCommit(env?: NodeJS.ProcessEnv): PreviewSourceCommitResult;
|
|
47
|
+
export declare function normalizeConvexUrl(url: string): string;
|
|
48
|
+
/** DOCS_SEED_SYNC_EMAIL with PLAYWRIGHT_TEST_EMAIL fallback (Coolify / entrypoint). */
|
|
49
|
+
export declare function docsSeedSyncEmailFromEnv(env?: NodeJS.ProcessEnv): string | undefined;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// packages/@columnus/shared/src/previewDeployName.ts
|
|
2
|
+
function coolifyHostnameFromEnv(env = process.env) {
|
|
3
|
+
const raw = env.COOLIFY_FQDN ?? env.COOLIFY_URL;
|
|
4
|
+
if (!raw) return null;
|
|
5
|
+
const host = raw.replace(/^https?:\/\//, "").split("/")[0] ?? "";
|
|
6
|
+
return host || null;
|
|
7
|
+
}
|
|
8
|
+
var PULL_HEAD_BRANCH_RE = /^pull\/(\d+)\/head$/i;
|
|
9
|
+
var PREVIEW_HOST_PR_RE = /^(?:manage-|deploy-)?preview-(\d+)\./;
|
|
10
|
+
function resolvePreviewPrId(env = process.env) {
|
|
11
|
+
const host = coolifyHostnameFromEnv(env);
|
|
12
|
+
if (host) {
|
|
13
|
+
const fromHost = PREVIEW_HOST_PR_RE.exec(host)?.[1];
|
|
14
|
+
if (fromHost) return fromHost;
|
|
15
|
+
}
|
|
16
|
+
const branch = env.COOLIFY_BRANCH ?? env.GIT_BRANCH;
|
|
17
|
+
if (branch) {
|
|
18
|
+
const fromBranch = PULL_HEAD_BRANCH_RE.exec(stripQualifiedBranch(branch))?.[1];
|
|
19
|
+
if (fromBranch) return fromBranch;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function stripQualifiedBranch(branch) {
|
|
24
|
+
const colon = branch.indexOf(":");
|
|
25
|
+
return colon > 0 ? branch.slice(0, colon) : branch;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// packages/@columnus/shared/src/ciPreviewEnv.ts
|
|
29
|
+
var GIT_SHA_RE = /^[0-9a-fA-F]{7,40}$/;
|
|
30
|
+
function parseGitSha(raw, label = "commit") {
|
|
31
|
+
const commit = (raw ?? "").trim();
|
|
32
|
+
if (!commit || commit === "unknown" || !GIT_SHA_RE.test(commit)) {
|
|
33
|
+
throw new Error(`${label} must be a git SHA (7\u201340 hex chars); got '${raw ?? ""}'`);
|
|
34
|
+
}
|
|
35
|
+
return commit;
|
|
36
|
+
}
|
|
37
|
+
function defaultProdDeployUrl(domain = "columnus.app") {
|
|
38
|
+
return `https://deploy.${domain}/ops/v1/deploy-initial`;
|
|
39
|
+
}
|
|
40
|
+
function hostnameOf(url) {
|
|
41
|
+
try {
|
|
42
|
+
const withScheme = /:\/\//.test(url) ? url : `http://${url}`;
|
|
43
|
+
return new URL(withScheme).hostname;
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function isLoopbackDeployServiceUrl(url) {
|
|
49
|
+
const host = hostnameOf(url);
|
|
50
|
+
return host === "127.0.0.1" || host === "localhost" || host === "::1";
|
|
51
|
+
}
|
|
52
|
+
function isProdDeployServiceUrl(url, domain = "columnus.app") {
|
|
53
|
+
return hostnameOf(url) === `deploy.${domain}`;
|
|
54
|
+
}
|
|
55
|
+
function derivePreviewStudioDeployUrl(env = process.env, domain = "columnus.app") {
|
|
56
|
+
const prId = resolvePreviewPrId(env);
|
|
57
|
+
if (!prId) return null;
|
|
58
|
+
for (const key of ["COLUMNUS_DEPLOY_SERVICE_URL", "STUDIO_DEPLOY_URL"]) {
|
|
59
|
+
const current = env[key]?.trim();
|
|
60
|
+
if (!current) continue;
|
|
61
|
+
if (isLoopbackDeployServiceUrl(current) || isProdDeployServiceUrl(current, domain)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return `https://deploy-preview-${prId}.${domain}/ops/v1/deploy-initial`;
|
|
67
|
+
}
|
|
68
|
+
var LOCAL_DEPLOY_SERVICE_DEFAULT = "http://127.0.0.1:8787";
|
|
69
|
+
function resolveRuntimeDeployServiceUrl(env = process.env, domain = "columnus.app") {
|
|
70
|
+
const derived = derivePreviewStudioDeployUrl(env, domain);
|
|
71
|
+
if (derived) return derived;
|
|
72
|
+
const columnus = env.COLUMNUS_DEPLOY_SERVICE_URL?.trim();
|
|
73
|
+
const studio = env.STUDIO_DEPLOY_URL?.trim();
|
|
74
|
+
if (columnus && !isLoopbackDeployServiceUrl(columnus)) return columnus;
|
|
75
|
+
if (studio) return studio;
|
|
76
|
+
if (columnus) return columnus;
|
|
77
|
+
return LOCAL_DEPLOY_SERVICE_DEFAULT;
|
|
78
|
+
}
|
|
79
|
+
function derivePreviewDeployBuildUrl(env = process.env) {
|
|
80
|
+
const prId = resolvePreviewPrId(env);
|
|
81
|
+
if (!prId) return null;
|
|
82
|
+
let uuid = env.COLUMNUS_DEPLOY_RESOURCE_UUID?.trim() ?? "";
|
|
83
|
+
uuid = uuid.replace(/^https?:\/\//, "");
|
|
84
|
+
uuid = uuid.split("/")[0] ?? "";
|
|
85
|
+
uuid = uuid.split("-pr-")[0] ?? uuid;
|
|
86
|
+
uuid = uuid.split(":")[0] ?? uuid;
|
|
87
|
+
if (!uuid) return null;
|
|
88
|
+
const port = env.COLUMNUS_DEPLOY_PREVIEW_PORT?.trim() || "3000";
|
|
89
|
+
return `http://${uuid}-pr-${prId}:${port}/ops/v1/deploy-initial`;
|
|
90
|
+
}
|
|
91
|
+
function resolveSyncDeployUrl(env, studioDeployUrl, isPreviewBuild) {
|
|
92
|
+
const explicit = env.STUDIO_DEPLOY_BUILD_URL?.trim();
|
|
93
|
+
if (explicit) {
|
|
94
|
+
return { ok: true, url: explicit };
|
|
95
|
+
}
|
|
96
|
+
if (env.CI_PREVIEW === "true") {
|
|
97
|
+
return { ok: true, url: "http://127.0.0.1:8787/ops/v1/deploy-initial" };
|
|
98
|
+
}
|
|
99
|
+
if (isPreviewBuild) {
|
|
100
|
+
const derived = derivePreviewDeployBuildUrl(env);
|
|
101
|
+
if (derived) {
|
|
102
|
+
return {
|
|
103
|
+
ok: true,
|
|
104
|
+
url: derived,
|
|
105
|
+
derivedMessage: `derived STUDIO_DEPLOY_BUILD_URL=${derived} (from COLUMNUS_DEPLOY_RESOURCE_UUID + PR id)`
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
ok: false,
|
|
110
|
+
message: "Set COLUMNUS_DEPLOY_RESOURCE_UUID on columnus-web preview (columnus-deploy Coolify resource UUID) or STUDIO_DEPLOY_BUILD_URL explicitly. See plans/done/021-preview-deploy-service.md"
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { ok: true, url: studioDeployUrl };
|
|
114
|
+
}
|
|
115
|
+
function validatePreviewSourceCommit(env = process.env) {
|
|
116
|
+
if (env.CI_PREVIEW === "true") {
|
|
117
|
+
return { ok: true, commit: env.SOURCE_COMMIT?.trim() ?? "", required: false };
|
|
118
|
+
}
|
|
119
|
+
const raw = env.SOURCE_COMMIT ?? "";
|
|
120
|
+
try {
|
|
121
|
+
const commit = parseGitSha(raw, "SOURCE_COMMIT");
|
|
122
|
+
return { ok: true, commit, required: true };
|
|
123
|
+
} catch (error) {
|
|
124
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
125
|
+
if (!raw.trim() || raw.trim() === "unknown") {
|
|
126
|
+
return {
|
|
127
|
+
ok: false,
|
|
128
|
+
message: `SOURCE_COMMIT is required for Coolify preview builds (got '${raw}'). Enable Advanced \u2192 Include Source Commit in Build on both columnus-web and columnus-deploy.`
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return { ok: false, message };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function normalizeConvexUrl(url) {
|
|
135
|
+
return url.trim().replace(/\/+$/, "");
|
|
136
|
+
}
|
|
137
|
+
function docsSeedSyncEmailFromEnv(env = process.env) {
|
|
138
|
+
return env.DOCS_SEED_SYNC_EMAIL?.trim() || env.PLAYWRIGHT_TEST_EMAIL?.trim() || void 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { defaultProdDeployUrl, derivePreviewDeployBuildUrl, derivePreviewStudioDeployUrl, docsSeedSyncEmailFromEnv, isLoopbackDeployServiceUrl, isProdDeployServiceUrl, normalizeConvexUrl, parseGitSha, resolveRuntimeDeployServiceUrl, resolveSyncDeployUrl, validatePreviewSourceCommit };
|
|
142
|
+
//# sourceMappingURL=ciPreviewEnv.js.map
|
|
143
|
+
//# sourceMappingURL=ciPreviewEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/previewDeployName.ts","../src/ciPreviewEnv.ts"],"names":[],"mappings":"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","file":"ciPreviewEnv.js","sourcesContent":["/**\n * Sanitized Convex preview deployment name for CI / Coolify preview builds.\n * \"/\" breaks preview/<name> lookups in Convex deployment references.\n *\n * Coolify preview env vars: COOLIFY_BRANCH, COOLIFY_IS_PREVIEW, COOLIFY_FQDN,\n * COOLIFY_URL (BuildKit build secrets).\n */\nexport function coolifyHostnameFromEnv(env: NodeJS.ProcessEnv = process.env): string | null {\n const raw = env.COOLIFY_FQDN ?? env.COOLIFY_URL;\n if (!raw) return null;\n const host = raw.replace(/^https?:\\/\\//, \"\").split(\"/\")[0] ?? \"\";\n return host || null;\n}\n\n/** True when Coolify (or CI_PREVIEW) indicates a PR preview Docker build. */\nexport function isCiPreviewBuild(env: NodeJS.ProcessEnv = process.env): boolean {\n if (env.CI_PREVIEW === \"true\" || env.COOLIFY_IS_PREVIEW === \"true\") {\n return true;\n }\n const host = coolifyHostnameFromEnv(env);\n // preview-<pr>, manage-preview-<pr>, deploy-preview-<pr>\n return Boolean(host && /^(?:manage-|deploy-)?preview-\\d+\\./.test(host));\n}\n\nconst PULL_HEAD_BRANCH_RE = /^pull\\/(\\d+)\\/head$/i;\nconst PREVIEW_HOST_PR_RE = /^(?:manage-|deploy-)?preview-(\\d+)\\./;\n\n/** PR id from `preview-<n>.<domain>` / `manage-preview-<n>` hostname or `pull/<n>/head` branch. */\nexport function resolvePreviewPrId(env: NodeJS.ProcessEnv = process.env): string | null {\n const host = coolifyHostnameFromEnv(env);\n if (host) {\n const fromHost = PREVIEW_HOST_PR_RE.exec(host)?.[1];\n if (fromHost) return fromHost;\n }\n\n const branch = env.COOLIFY_BRANCH ?? env.GIT_BRANCH;\n if (branch) {\n const fromBranch = PULL_HEAD_BRANCH_RE.exec(stripQualifiedBranch(branch))?.[1];\n if (fromBranch) return fromBranch;\n }\n\n return null;\n}\n\n/**\n * Resolve the git branch used for Convex `--preview-name`.\n * Coolify often sets COOLIFY_BRANCH to `pull/<n>/head` at runtime (see coollabsio/coolify#9572).\n */\nexport function resolvePreviewBranch(env: NodeJS.ProcessEnv = process.env): string | null {\n if (env.GITHUB_HEAD_REF) return stripQualifiedBranch(env.GITHUB_HEAD_REF);\n\n const branch = env.COOLIFY_BRANCH ?? env.GIT_BRANCH;\n const prId = resolvePreviewPrId(env);\n if (!branch) {\n return prId ? `preview-${prId}` : null;\n }\n\n const stripped = stripQualifiedBranch(branch);\n if (PULL_HEAD_BRANCH_RE.test(stripped)) {\n if (prId) return `preview-${prId}`;\n }\n // Coolify PR apps often leave COOLIFY_BRANCH=main while FQDN is *-preview-<n>.\n if ((stripped === \"main\" || stripped === \"master\") && prId) {\n return `preview-${prId}`;\n }\n return stripped;\n}\n\n/** Strip Coolify/Convex qualified suffixes (e.g. `pull-48-head:pr-48-coolify`). */\nfunction stripQualifiedBranch(branch: string): string {\n const colon = branch.indexOf(\":\");\n return colon > 0 ? branch.slice(0, colon) : branch;\n}\n\nexport function sanitizePreviewDeployName(branch: string): string {\n return stripQualifiedBranch(branch).replace(/\\//g, \"-\");\n}\n\n/** Normalize a preview name from Convex env before `convex deploy --preview-name`. */\nexport function normalizePreviewDeployName(name: string): string {\n return sanitizePreviewDeployName(name.trim());\n}\n\nexport function ciPreviewDeployName(env: NodeJS.ProcessEnv = process.env): string | null {\n if (!isCiPreviewBuild(env)) return null;\n\n const branch = resolvePreviewBranch(env);\n if (!branch) return null;\n return sanitizePreviewDeployName(branch);\n}\n\n/** Stale failures from broken preview deploy before the bridge was live. */\nexport const STALE_ENDPOINT_DEPLOY_ERROR =\n /^deploy endpoint returned (?:200(?: OK)?|500(?: Internal Server Error)?)$/;\n\nexport function isStaleEndpointDeployError(error: string | undefined): boolean {\n return error != null && STALE_ENDPOINT_DEPLOY_ERROR.test(error);\n}\n\n/** Infra failures from a prior broken deploy that a fresh save can retry. */\nexport function isRecoverableDeployError(error: string | undefined): boolean {\n if (error == null) return false;\n if (isStaleEndpointDeployError(error)) return true;\n if (error.includes(\"502 Bad Gateway\")) return true;\n if (error.includes(\"deploy endpoint unreachable\")) return true;\n if (error.includes(\"deploy endpoint timed out\")) return true;\n return (\n error.includes(\"convex/bin/main.js\") ||\n error.includes(\"convex CLI (bin/main.js\") ||\n error.includes(\"convex CLI not available\")\n );\n}\n","import { resolvePreviewPrId } from \"./previewDeployName.ts\";\n\nconst GIT_SHA_RE = /^[0-9a-fA-F]{7,40}$/;\n\n/** Parse and validate a git commit SHA (7–40 hex chars). */\nexport function parseGitSha(raw: string | undefined, label = \"commit\"): string {\n const commit = (raw ?? \"\").trim();\n if (!commit || commit === \"unknown\" || !GIT_SHA_RE.test(commit)) {\n throw new Error(`${label} must be a git SHA (7–40 hex chars); got '${raw ?? \"\"}'`);\n }\n return commit;\n}\n\nexport function defaultProdDeployUrl(domain = \"columnus.app\"): string {\n return `https://deploy.${domain}/ops/v1/deploy-initial`;\n}\n\nfunction hostnameOf(url: string): string | null {\n try {\n const withScheme = /:\\/\\//.test(url) ? url : `http://${url}`;\n return new URL(withScheme).hostname;\n } catch {\n return null;\n }\n}\n\n/** True for local defaults that should not beat Coolify preview deploy URLs. */\nexport function isLoopbackDeployServiceUrl(url: string): boolean {\n const host = hostnameOf(url);\n return host === \"127.0.0.1\" || host === \"localhost\" || host === \"::1\";\n}\n\n/** Production shared deploy host (`deploy.columnus.app`), any path. */\nexport function isProdDeployServiceUrl(url: string, domain = \"columnus.app\"): boolean {\n return hostnameOf(url) === `deploy.${domain}`;\n}\n\n/**\n * When on a PR preview host, return the per-PR deploy-service URL unless env already\n * points at a non-production executor (deploy-preview or Coolify internal).\n *\n * Coolify often copies production `STUDIO_DEPLOY_URL=https://deploy.columnus.app/deploy`\n * onto preview apps — that must not win over `deploy-preview-<pr>`.\n */\nexport function derivePreviewStudioDeployUrl(\n env: NodeJS.ProcessEnv = process.env,\n domain = \"columnus.app\",\n): string | null {\n const prId = resolvePreviewPrId(env);\n if (!prId) return null;\n\n for (const key of [\"COLUMNUS_DEPLOY_SERVICE_URL\", \"STUDIO_DEPLOY_URL\"] as const) {\n const current = env[key]?.trim();\n if (!current) continue;\n if (isLoopbackDeployServiceUrl(current) || isProdDeployServiceUrl(current, domain)) {\n continue;\n }\n // Explicit non-prod URL (deploy-preview / Coolify internal) — leave alone.\n return null;\n }\n\n return `https://deploy-preview-${prId}.${domain}/ops/v1/deploy-initial`;\n}\n\nconst LOCAL_DEPLOY_SERVICE_DEFAULT = \"http://127.0.0.1:8787\";\n\n/**\n * Runtime deploy-service URL for Web BFF / container entrypoint.\n *\n * Prefer preview-derived `deploy-preview-<pr>`, else non-loopback `COLUMNUS_DEPLOY_SERVICE_URL`,\n * else `STUDIO_DEPLOY_URL`, else loopback COLUMNUS, else local default.\n *\n * Callers that need an origin (no path) should normalize with deploy-service helpers.\n */\nexport function resolveRuntimeDeployServiceUrl(\n env: NodeJS.ProcessEnv = process.env,\n domain = \"columnus.app\",\n): string {\n const derived = derivePreviewStudioDeployUrl(env, domain);\n if (derived) return derived;\n\n const columnus = env.COLUMNUS_DEPLOY_SERVICE_URL?.trim();\n const studio = env.STUDIO_DEPLOY_URL?.trim();\n if (columnus && !isLoopbackDeployServiceUrl(columnus)) return columnus;\n if (studio) return studio;\n if (columnus) return columnus;\n return LOCAL_DEPLOY_SERVICE_DEFAULT;\n}\n\n/** Coolify internal URL for columnus-deploy preview container (build-time manifest sync). */\nexport function derivePreviewDeployBuildUrl(env: NodeJS.ProcessEnv = process.env): string | null {\n const prId = resolvePreviewPrId(env);\n if (!prId) return null;\n\n let uuid = env.COLUMNUS_DEPLOY_RESOURCE_UUID?.trim() ?? \"\";\n uuid = uuid.replace(/^https?:\\/\\//, \"\");\n uuid = uuid.split(\"/\")[0] ?? \"\";\n uuid = uuid.split(\"-pr-\")[0] ?? uuid;\n uuid = uuid.split(\":\")[0] ?? uuid;\n if (!uuid) return null;\n\n const port = env.COLUMNUS_DEPLOY_PREVIEW_PORT?.trim() || \"3000\";\n return `http://${uuid}-pr-${prId}:${port}/ops/v1/deploy-initial`;\n}\n\nexport type ResolveSyncDeployUrlResult =\n | { ok: true; url: string; derivedMessage?: string }\n | { ok: false; message: string };\n\n/** URL for `sync-manifest-deploy` during Docker/CI builds. */\nexport function resolveSyncDeployUrl(\n env: NodeJS.ProcessEnv,\n studioDeployUrl: string,\n isPreviewBuild: boolean,\n): ResolveSyncDeployUrlResult {\n const explicit = env.STUDIO_DEPLOY_BUILD_URL?.trim();\n if (explicit) {\n return { ok: true, url: explicit };\n }\n\n if (env.CI_PREVIEW === \"true\") {\n return { ok: true, url: \"http://127.0.0.1:8787/ops/v1/deploy-initial\" };\n }\n\n if (isPreviewBuild) {\n const derived = derivePreviewDeployBuildUrl(env);\n if (derived) {\n return {\n ok: true,\n url: derived,\n derivedMessage: `derived STUDIO_DEPLOY_BUILD_URL=${derived} (from COLUMNUS_DEPLOY_RESOURCE_UUID + PR id)`,\n };\n }\n return {\n ok: false,\n message:\n \"Set COLUMNUS_DEPLOY_RESOURCE_UUID on columnus-web preview (columnus-deploy Coolify resource UUID) or STUDIO_DEPLOY_BUILD_URL explicitly. See plans/done/021-preview-deploy-service.md\",\n };\n }\n\n return { ok: true, url: studioDeployUrl };\n}\n\nexport type PreviewSourceCommitResult =\n | { ok: true; commit: string; required: boolean }\n | { ok: false; message: string };\n\n/** Validates SOURCE_COMMIT for Coolify preview builds (skipped when CI_PREVIEW=true). */\nexport function validatePreviewSourceCommit(\n env: NodeJS.ProcessEnv = process.env,\n): PreviewSourceCommitResult {\n if (env.CI_PREVIEW === \"true\") {\n return { ok: true, commit: env.SOURCE_COMMIT?.trim() ?? \"\", required: false };\n }\n\n const raw = env.SOURCE_COMMIT ?? \"\";\n try {\n const commit = parseGitSha(raw, \"SOURCE_COMMIT\");\n return { ok: true, commit, required: true };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (!raw.trim() || raw.trim() === \"unknown\") {\n return {\n ok: false,\n message: `SOURCE_COMMIT is required for Coolify preview builds (got '${raw}'). Enable Advanced → Include Source Commit in Build on both columnus-web and columnus-deploy.`,\n };\n }\n return { ok: false, message };\n }\n}\n\nexport function normalizeConvexUrl(url: string): string {\n return url.trim().replace(/\\/+$/, \"\");\n}\n\n/** DOCS_SEED_SYNC_EMAIL with PLAYWRIGHT_TEST_EMAIL fallback (Coolify / entrypoint). */\nexport function docsSeedSyncEmailFromEnv(env: NodeJS.ProcessEnv = process.env): string | undefined {\n return env.DOCS_SEED_SYNC_EMAIL?.trim() || env.PLAYWRIGHT_TEST_EMAIL?.trim() || undefined;\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Table as TableT } from "./schemaTypes.ts";
|
|
2
|
+
import { type CsvExport } from "./csv.ts";
|
|
3
|
+
export declare const COLUMNUS_CLIPBOARD_MARKER = "#columnus-clipboard";
|
|
4
|
+
export declare const COLUMNUS_CLIPBOARD_VERSION = 1;
|
|
5
|
+
export type ColumnusClipboardMeta = {
|
|
6
|
+
version: number;
|
|
7
|
+
table: string;
|
|
8
|
+
columns: string[];
|
|
9
|
+
};
|
|
10
|
+
export type ParsedColumnusClipboard = {
|
|
11
|
+
meta: ColumnusClipboardMeta;
|
|
12
|
+
csvBody: string;
|
|
13
|
+
};
|
|
14
|
+
export type SerializeColumnusClipboardInput = {
|
|
15
|
+
table: string;
|
|
16
|
+
csv: CsvExport;
|
|
17
|
+
};
|
|
18
|
+
export declare function serializeColumnusClipboard(input: SerializeColumnusClipboardInput): string;
|
|
19
|
+
export declare function parseColumnusClipboard(text: string): ParsedColumnusClipboard | null;
|
|
20
|
+
export declare function validateClipboardColumns(columns: readonly string[], table: TableT): {
|
|
21
|
+
ok: true;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
unknownColumns: string[];
|
|
25
|
+
};
|