@treeseed/sdk 0.4.12 → 0.5.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/control-plane-client.d.ts +60 -1
- package/dist/control-plane-client.js +59 -0
- package/dist/control-plane.d.ts +1 -1
- package/dist/control-plane.js +11 -4
- package/dist/d1-store.d.ts +58 -0
- package/dist/d1-store.js +64 -0
- package/dist/dispatch.js +6 -0
- package/dist/graph/schema.js +4 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +32 -0
- package/dist/knowledge-coop.d.ts +223 -0
- package/dist/knowledge-coop.js +82 -0
- package/dist/model-registry.js +79 -0
- package/dist/operations/providers/default.js +128 -7
- package/dist/operations/services/config-runtime.d.ts +102 -24
- package/dist/operations/services/config-runtime.js +896 -160
- package/dist/operations/services/deploy.d.ts +223 -15
- package/dist/operations/services/deploy.js +626 -55
- package/dist/operations/services/git-workflow.d.ts +47 -3
- package/dist/operations/services/git-workflow.js +125 -19
- package/dist/operations/services/github-automation.d.ts +85 -0
- package/dist/operations/services/github-automation.js +220 -1
- package/dist/operations/services/key-agent.d.ts +118 -0
- package/dist/operations/services/key-agent.js +476 -0
- package/dist/operations/services/knowledge-coop-launch.d.ts +90 -0
- package/dist/operations/services/knowledge-coop-launch.js +753 -0
- package/dist/operations/services/knowledge-coop-packaging.d.ts +59 -0
- package/dist/operations/services/knowledge-coop-packaging.js +234 -0
- package/dist/operations/services/local-dev.d.ts +0 -1
- package/dist/operations/services/local-dev.js +1 -14
- package/dist/operations/services/project-platform.d.ts +42 -182
- package/dist/operations/services/project-platform.js +162 -59
- package/dist/operations/services/railway-deploy.d.ts +1 -0
- package/dist/operations/services/railway-deploy.js +31 -13
- package/dist/operations/services/runtime-tools.d.ts +52 -5
- package/dist/operations/services/runtime-tools.js +186 -26
- package/dist/operations/services/watch-dev.js +2 -4
- package/dist/operations/services/workspace-preflight.d.ts +4 -4
- package/dist/operations/services/workspace-preflight.js +22 -20
- package/dist/operations/services/workspace-save.d.ts +10 -1
- package/dist/operations/services/workspace-save.js +54 -3
- package/dist/operations/services/workspace-tools.d.ts +1 -0
- package/dist/operations/services/workspace-tools.js +20 -5
- package/dist/operations-registry.js +15 -8
- package/dist/operations-types.d.ts +2 -2
- package/dist/platform/contracts.d.ts +39 -3
- package/dist/platform/deploy-config.d.ts +12 -1
- package/dist/platform/deploy-config.js +214 -15
- package/dist/platform/deploy-runtime.d.ts +1 -0
- package/dist/platform/deploy-runtime.js +10 -2
- package/dist/platform/env.yaml +93 -61
- package/dist/platform/environment.d.ts +13 -2
- package/dist/platform/environment.js +90 -20
- package/dist/platform/plugins/constants.d.ts +1 -0
- package/dist/platform/plugins/constants.js +7 -6
- package/dist/platform/tenant/runtime-config.js +8 -1
- package/dist/platform/tenant-config.js +4 -0
- package/dist/platform/utils/site-config-schema.js +18 -0
- package/dist/plugin-default.js +2 -2
- package/dist/scripts/key-agent.js +165 -0
- package/dist/scripts/tenant-build.js +4 -1
- package/dist/scripts/tenant-check.js +4 -1
- package/dist/scripts/tenant-deploy.js +43 -4
- package/dist/scripts/tenant-dev.js +0 -1
- package/dist/scripts/workspace-start-warning.js +2 -2
- package/dist/sdk-types.d.ts +2 -2
- package/dist/sdk-types.js +2 -0
- package/dist/sdk.d.ts +13 -0
- package/dist/sdk.js +40 -0
- package/dist/stores/knowledge-coop-store.d.ts +56 -0
- package/dist/stores/knowledge-coop-store.js +482 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +6 -2
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/api/server.js +4 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/config.yaml +25 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/decisions/adopt-initial-proposal-loop.mdx +22 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/people/starter-steward.mdx +11 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/proposals/establish-initial-proposal-loop.mdx +17 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/manifest.yaml +17 -10
- package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +69 -7
- package/dist/treeseed/template-catalog/templates/starter-basic/template.config.json +1 -0
- package/dist/workflow/operations.d.ts +592 -243
- package/dist/workflow/operations.js +1908 -219
- package/dist/workflow/runs.d.ts +90 -0
- package/dist/workflow/runs.js +242 -0
- package/dist/workflow/session.d.ts +31 -0
- package/dist/workflow/session.js +97 -0
- package/dist/workflow-state.d.ts +88 -2
- package/dist/workflow-state.js +288 -26
- package/dist/workflow-support.d.ts +1 -1
- package/dist/workflow-support.js +32 -2
- package/dist/workflow.d.ts +93 -3
- package/dist/workflow.js +12 -0
- package/package.json +1 -1
- package/templates/github/deploy.workflow.yml +11 -1
- package/dist/scripts/sync-dev-vars.js +0 -6
- package/dist/scripts/workspace-close.js +0 -24
- package/dist/scripts/workspace-release.js +0 -42
- package/dist/scripts/workspace-start.js +0 -71
|
@@ -3,22 +3,30 @@ function operation(spec) {
|
|
|
3
3
|
}
|
|
4
4
|
const TRESEED_OPERATION_SPECS = [
|
|
5
5
|
operation({ id: "workspace.status", name: "status", aliases: [], group: "Workflow", summary: "Show Treeseed project health and the current task state.", description: "Report branch/task state, runtime readiness, preview/deploy state, auth readiness, and recommended next operations.", provider: "default", related: ["tasks", "switch", "config"] }),
|
|
6
|
-
operation({ id: "branch.tasks", name: "tasks", aliases: [], group: "Workflow", summary: "List task branches
|
|
7
|
-
operation({ id: "branch.switch", name: "switch", aliases: [], group: "Workflow", summary: "Create or resume a task branch.", description: "Create
|
|
8
|
-
operation({ id: "branch.save", name: "save", aliases: [], group: "Workflow", summary: "
|
|
9
|
-
operation({ id: "branch.close", name: "close", aliases: [], group: "Workflow", summary: "
|
|
10
|
-
operation({ id: "branch.stage", name: "stage", aliases: [], group: "Workflow", summary: "
|
|
6
|
+
operation({ id: "branch.tasks", name: "tasks", aliases: [], group: "Workflow", summary: "List task branches plus package branch alignment.", description: "List task branches from market and checked-out package repos, including preview metadata and branch/pointer alignment state.", provider: "default", related: ["status", "switch", "close"] }),
|
|
7
|
+
operation({ id: "branch.switch", name: "switch", aliases: [], group: "Workflow", summary: "Create or resume a recursive task branch.", description: "Create or resume the task branch in market and any checked-out package repos, with optional preview provisioning.", provider: "default", related: ["tasks", "dev", "save"] }),
|
|
8
|
+
operation({ id: "branch.save", name: "save", aliases: [], group: "Workflow", summary: "Recursively verify, commit, and push the current task checkpoint.", description: "Save dirty package repos in dependency order, then verify, commit, push, and optionally refresh preview for market.", provider: "default", related: ["switch", "stage", "status"] }),
|
|
9
|
+
operation({ id: "branch.close", name: "close", aliases: [], group: "Workflow", summary: "Recursively archive and delete a task branch.", description: "Auto-save if needed, clean preview resources, create deprecated tags, and remove the task branch across market and checked-out package repos.", provider: "default", related: ["tasks", "switch", "stage"] }),
|
|
10
|
+
operation({ id: "branch.stage", name: "stage", aliases: [], group: "Workflow", summary: "Squash a task branch into staging across market and packages.", description: "Auto-save if needed, squash-merge package task branches into staging first, update market submodule pointers, then squash-merge market into staging and clean up the task branch.", provider: "default", related: ["save", "release", "close"] }),
|
|
11
|
+
operation({ id: "workspace.resume", name: "resume", aliases: [], group: "Workflow", summary: "Resume an interrupted workflow run.", description: "Continue a failed journaled workflow run from its next incomplete step after validating current workspace preconditions.", provider: "default", related: ["recover", "status"] }),
|
|
12
|
+
operation({ id: "workspace.recover", name: "recover", aliases: [], group: "Workflow", summary: "Inspect active workflow locks and interrupted runs.", description: "List active workflow locks, resumable interrupted runs, and the exact commands needed to continue or recover the workspace state.", provider: "default", related: ["resume", "status"] }),
|
|
11
13
|
operation({ id: "deploy.rollback", name: "rollback", aliases: [], group: "Workflow", summary: "Roll back staging or production to a recorded deployment.", description: "Redeploy a previously recorded staging or production commit using a temporary checkout of that revision.", provider: "default", related: ["status", "release"] }),
|
|
12
14
|
operation({ id: "workspace.doctor", name: "doctor", aliases: [], group: "Validation", summary: "Diagnose Treeseed tooling, auth, and workflow readiness.", description: "Collect doctor-style diagnostics for workspace readiness and optional safe repairs.", provider: "default", related: ["status", "config"] }),
|
|
13
15
|
operation({ id: "auth.login", name: "auth:login", aliases: [], group: "Validation", summary: "Authenticate against the configured Treeseed API.", description: "Start the device login flow against the active Treeseed API host and persist the returned session locally.", provider: "default", related: ["auth:check", "auth:whoami", "auth:logout"] }),
|
|
14
16
|
operation({ id: "auth.logout", name: "auth:logout", aliases: [], group: "Validation", summary: "Clear locally stored Treeseed API credentials.", description: "Remove the persisted local device-flow session for the active Treeseed API host.", provider: "default", related: ["auth:login", "auth:whoami"] }),
|
|
15
17
|
operation({ id: "auth.whoami", name: "auth:whoami", aliases: [], group: "Validation", summary: "Inspect the active Treeseed API identity.", description: "Use the persisted local remote session to query the active Treeseed API principal.", provider: "default", related: ["auth:login", "status"] }),
|
|
18
|
+
operation({ id: "secrets.status", name: "secrets:status", aliases: [], group: "Validation", summary: "Inspect the local wrapped machine-key session.", description: "Report whether the local key agent is running, whether the wrapped machine key exists, and whether the secret session is unlocked.", provider: "default", related: ["secrets:unlock", "secrets:lock"] }),
|
|
19
|
+
operation({ id: "secrets.unlock", name: "secrets:unlock", aliases: [], group: "Validation", summary: "Unlock the local Treeseed secret session.", description: "Unlock the host-local Treeseed key agent from an interactive passphrase prompt or an explicit startup passphrase env var.", provider: "default", related: ["secrets:status", "secrets:lock", "secrets:migrate-key"] }),
|
|
20
|
+
operation({ id: "secrets.lock", name: "secrets:lock", aliases: [], group: "Validation", summary: "Lock the local Treeseed secret session.", description: "Clear the in-memory machine key from the host-local Treeseed key agent.", provider: "default", related: ["secrets:status", "secrets:unlock"] }),
|
|
21
|
+
operation({ id: "secrets.migrateKey", name: "secrets:migrate-key", aliases: [], group: "Validation", summary: "Wrap a legacy plaintext machine key.", description: "Replace the legacy plaintext machine-key file with the wrapped passphrase-protected format used by the Treeseed key agent.", provider: "default", related: ["secrets:unlock", "secrets:rotate-passphrase"] }),
|
|
22
|
+
operation({ id: "secrets.rotatePassphrase", name: "secrets:rotate-passphrase", aliases: [], group: "Validation", summary: "Rotate the wrapped machine-key passphrase.", description: "Re-wrap the existing machine key with a newly entered passphrase without changing the underlying machine key.", provider: "default", related: ["secrets:unlock", "secrets:rotate-machine-key"] }),
|
|
23
|
+
operation({ id: "secrets.rotateMachineKey", name: "secrets:rotate-machine-key", aliases: [], group: "Validation", summary: "Rotate the encrypted machine key itself.", description: "Generate a new machine key, re-encrypt stored local secrets and remote auth sessions, and re-wrap the result with the configured passphrase.", provider: "default", related: ["config", "secrets:rotate-passphrase"] }),
|
|
16
24
|
operation({ id: "template.list", name: "template", aliases: [], group: "Utilities", summary: "List, inspect, and validate templates from the Treeseed catalog.", description: "Use remote template metadata to list templates, show one template, or validate local template artifacts.", provider: "default", related: ["init", "sync"] }),
|
|
17
25
|
operation({ id: "template.sync", name: "sync", aliases: [], group: "Validation", summary: "Validate or reconcile the managed template surface for the current site.", description: "Use remote template metadata plus the local scaffold artifact to check or apply updates to the managed scaffold surface.", provider: "default", related: ["template", "init", "status"] }),
|
|
18
26
|
operation({ id: "project.init", name: "init", aliases: [], group: "Workflow", summary: "Scaffold a new Treeseed tenant project.", description: "Create a new Treeseed tenant directory from a remote-catalog template backed by the packaged scaffold artifact.", provider: "default", related: ["config", "switch", "dev"] }),
|
|
19
|
-
operation({ id: "project.config", name: "config", aliases: [], group: "Workflow", summary: "Configure and test the runtime foundation.", description: "Apply safe repairs, collect environment values, write local machine config,
|
|
27
|
+
operation({ id: "project.config", name: "config", aliases: [], group: "Workflow", summary: "Configure and test the runtime foundation.", description: "Apply safe repairs, collect environment values, write local machine config, initialize environments, sync providers, and run doctor-style checks.", provider: "default", related: ["status", "switch", "dev"] }),
|
|
20
28
|
operation({ id: "project.export", name: "export", aliases: [], group: "Utilities", summary: "Export a Markdown snapshot of the current codebase.", description: "Generate a Markdown codebase snapshot for the selected directory using the SDK-owned repomix integration and store it under .treeseed/exports.", provider: "default", related: ["status", "config"] }),
|
|
21
|
-
operation({ id: "deploy.release", name: "release", aliases: [], group: "Workflow", summary: "
|
|
29
|
+
operation({ id: "deploy.release", name: "release", aliases: [], group: "Workflow", summary: "Release changed packages and market from staging to production.", description: "Select changed packages plus dependents, validate publish workflows, release packages first, then promote market from staging to main with aligned package pointers.", provider: "default", related: ["stage", "status", "rollback"] }),
|
|
22
30
|
operation({ id: "deploy.destroy", name: "destroy", aliases: [], group: "Workflow", summary: "Destroy a persistent environment and its local state.", description: "Delete the selected persistent environment resources and remove the local deploy state after confirmation.", provider: "default", related: ["config", "status"] }),
|
|
23
31
|
operation({ id: "local.dev", name: "dev", aliases: [], group: "Local Development", summary: "Start the unified local Treeseed development environment.", description: "Start the unified local Treeseed development environment.", provider: "default" }),
|
|
24
32
|
operation({ id: "local.devWatch", name: "dev:watch", aliases: [], group: "Local Development", summary: "Start local development with rebuild and watch mode.", description: "Start local development with rebuild and watch mode.", provider: "default" }),
|
|
@@ -38,7 +46,6 @@ const TRESEED_OPERATION_SPECS = [
|
|
|
38
46
|
operation({ id: "release.verify", name: "test:release:full", aliases: ["release:verify"], group: "Release Utilities", summary: "Run the full release verification path.", description: "Run the full release verification path.", provider: "default" }),
|
|
39
47
|
operation({ id: "release.publishChanged", name: "release:publish:changed", aliases: [], group: "Release Utilities", summary: "Publish changed Treeseed workspace packages.", description: "Publish changed Treeseed workspace packages.", provider: "default" }),
|
|
40
48
|
operation({ id: "tools.astro", name: "astro", aliases: [], group: "Passthrough", summary: "Pass through to the packaged Astro CLI wrapper.", description: "Pass through to the packaged Astro CLI wrapper.", provider: "default" }),
|
|
41
|
-
operation({ id: "tools.syncDevvars", name: "sync:devvars", aliases: [], group: "Utilities", summary: "Regenerate .dev.vars from local configuration.", description: "Regenerate .dev.vars from local configuration.", provider: "default" }),
|
|
42
49
|
operation({ id: "services.mailpitUp", name: "mailpit:up", aliases: [], group: "Utilities", summary: "Start the package-managed Mailpit service.", description: "Start the package-managed Mailpit service.", provider: "default" }),
|
|
43
50
|
operation({ id: "services.mailpitDown", name: "mailpit:down", aliases: [], group: "Utilities", summary: "Stop the package-managed Mailpit service.", description: "Stop the package-managed Mailpit service.", provider: "default" }),
|
|
44
51
|
operation({ id: "services.mailpitLogs", name: "mailpit:logs", aliases: [], group: "Utilities", summary: "Show Mailpit logs.", description: "Show Mailpit logs.", provider: "default" }),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type TreeseedOperationGroup = 'Workflow' | 'Local Development' | 'Validation' | 'Release Utilities' | 'Utilities' | 'Passthrough';
|
|
2
|
-
export type TreeseedOperationId = 'workspace.status' | 'workspace.doctor' | 'branch.tasks' | 'branch.switch' | 'branch.save' | 'branch.close' | 'branch.stage' | 'deploy.release' | 'deploy.rollback' | 'deploy.destroy' | 'template.list' | 'template.show' | 'template.validate' | 'template.sync' | 'project.init' | 'project.config' | 'local.dev' | 'local.devWatch' | 'local.build' | 'local.check' | 'local.preview' | 'local.lint' | 'local.test' | 'validation.testUnit' | 'validation.preflight' | 'validation.authCheck' | 'auth.login' | 'auth.logout' | 'auth.whoami' | 'release.testE2e' | 'release.testE2eLocal' | 'release.testE2eStaging' | 'release.testE2eFull' | 'release.testFast' | 'release.verify' | 'release.publishChanged' | 'services.mailpitUp' | 'services.mailpitDown' | 'services.mailpitLogs' | 'data.d1MigrateLocal' | 'content.cleanupMarkdown' | 'content.cleanupMarkdownCheck' | 'project.export' | 'tools.astro' | 'tools.syncDevvars' | 'tools.starlightPatch' | 'agents.run';
|
|
2
|
+
export type TreeseedOperationId = 'workspace.status' | 'workspace.doctor' | 'branch.tasks' | 'branch.switch' | 'branch.save' | 'branch.close' | 'branch.stage' | 'deploy.release' | 'deploy.rollback' | 'deploy.destroy' | 'workspace.resume' | 'workspace.recover' | 'template.list' | 'template.show' | 'template.validate' | 'template.sync' | 'project.init' | 'project.config' | 'local.dev' | 'local.devWatch' | 'local.build' | 'local.check' | 'local.preview' | 'local.lint' | 'local.test' | 'validation.testUnit' | 'validation.preflight' | 'validation.authCheck' | 'auth.login' | 'auth.logout' | 'auth.whoami' | 'release.testE2e' | 'release.testE2eLocal' | 'release.testE2eStaging' | 'release.testE2eFull' | 'release.testFast' | 'release.verify' | 'release.publishChanged' | 'services.mailpitUp' | 'services.mailpitDown' | 'services.mailpitLogs' | 'data.d1MigrateLocal' | 'content.cleanupMarkdown' | 'content.cleanupMarkdownCheck' | 'project.export' | 'tools.astro' | 'tools.syncDevvars' | 'tools.starlightPatch' | 'agents.run';
|
|
3
3
|
export type TreeseedOperationProviderId = 'default';
|
|
4
4
|
export type TreeseedOperationMetadata = {
|
|
5
5
|
id: TreeseedOperationId;
|
|
@@ -49,7 +49,7 @@ export type TreeseedOperationContext = {
|
|
|
49
49
|
confirm?: TreeseedOperationConfirm;
|
|
50
50
|
transport?: 'sdk' | 'cli' | 'api';
|
|
51
51
|
};
|
|
52
|
-
export type TreeseedOperationFailureCode = 'validation_failed' | 'merge_conflict' | 'missing_runtime_auth' | 'deployment_timeout' | 'confirmation_required' | 'unsupported_transport' | 'unsupported_state' | 'provider_resolution_failed';
|
|
52
|
+
export type TreeseedOperationFailureCode = 'validation_failed' | 'merge_conflict' | 'missing_runtime_auth' | 'deployment_timeout' | 'confirmation_required' | 'unsupported_transport' | 'unsupported_state' | 'workflow_locked' | 'resume_unavailable' | 'workflow_contract_missing' | 'provider_resolution_failed';
|
|
53
53
|
export declare class TreeseedOperationError extends Error {
|
|
54
54
|
code: TreeseedOperationFailureCode;
|
|
55
55
|
operation: string;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
export type TreeseedFeatureName = 'docs' | 'books' | 'notes' | 'questions' | 'objectives' | 'agents' | 'forms';
|
|
2
|
-
export type TreeseedContentCollection = 'pages' | 'notes' | 'questions' | 'objectives' | 'people' | 'agents' | 'books' | 'docs' | 'templates' | 'knowledge_packs' | 'workdays';
|
|
1
|
+
export type TreeseedFeatureName = 'docs' | 'books' | 'notes' | 'questions' | 'objectives' | 'proposals' | 'decisions' | 'agents' | 'forms';
|
|
2
|
+
export type TreeseedContentCollection = 'pages' | 'notes' | 'questions' | 'objectives' | 'proposals' | 'decisions' | 'people' | 'agents' | 'books' | 'docs' | 'templates' | 'knowledge_packs' | 'workdays';
|
|
3
3
|
export interface TreeseedFeatureModules {
|
|
4
4
|
docs?: boolean;
|
|
5
5
|
books?: boolean;
|
|
6
6
|
notes?: boolean;
|
|
7
7
|
questions?: boolean;
|
|
8
8
|
objectives?: boolean;
|
|
9
|
+
proposals?: boolean;
|
|
10
|
+
decisions?: boolean;
|
|
9
11
|
agents?: boolean;
|
|
10
12
|
forms?: boolean;
|
|
11
13
|
[key: string]: boolean | undefined;
|
|
@@ -15,6 +17,8 @@ export interface TreeseedContentMap {
|
|
|
15
17
|
notes: string;
|
|
16
18
|
questions: string;
|
|
17
19
|
objectives: string;
|
|
20
|
+
proposals: string;
|
|
21
|
+
decisions: string;
|
|
18
22
|
people: string;
|
|
19
23
|
agents: string;
|
|
20
24
|
books: string;
|
|
@@ -118,7 +122,23 @@ export interface TreeseedPlatformSurfaceConfig {
|
|
|
118
122
|
rootDir?: string;
|
|
119
123
|
publicBaseUrl?: string;
|
|
120
124
|
localBaseUrl?: string;
|
|
125
|
+
cache?: TreeseedWebSurfaceCacheConfig;
|
|
121
126
|
}
|
|
127
|
+
export interface TreeseedWebCachePolicyConfig {
|
|
128
|
+
browserTtlSeconds?: number;
|
|
129
|
+
edgeTtlSeconds?: number;
|
|
130
|
+
staleWhileRevalidateSeconds?: number;
|
|
131
|
+
staleIfErrorSeconds?: number;
|
|
132
|
+
}
|
|
133
|
+
export interface TreeseedWebSourcePageCacheConfig extends TreeseedWebCachePolicyConfig {
|
|
134
|
+
paths?: string[];
|
|
135
|
+
}
|
|
136
|
+
export interface TreeseedWebSurfaceCacheConfig {
|
|
137
|
+
sourcePages?: TreeseedWebSourcePageCacheConfig;
|
|
138
|
+
contentPages?: TreeseedWebCachePolicyConfig;
|
|
139
|
+
r2PublishedObjects?: TreeseedWebCachePolicyConfig;
|
|
140
|
+
}
|
|
141
|
+
export type TreeseedContentServingMode = 'local_collections' | 'published_runtime';
|
|
122
142
|
export interface TreeseedCloudflareR2Config {
|
|
123
143
|
binding?: string;
|
|
124
144
|
bucketName?: string;
|
|
@@ -136,6 +156,9 @@ export interface TreeseedCloudflarePagesConfig {
|
|
|
136
156
|
}
|
|
137
157
|
export type TreeseedHostingKind = 'market_control_plane' | 'hosted_project' | 'self_hosted_project';
|
|
138
158
|
export type TreeseedHostingRegistration = 'optional' | 'none';
|
|
159
|
+
export type TreeseedHubMode = 'treeseed_hosted' | 'customer_hosted';
|
|
160
|
+
export type TreeseedRuntimeMode = 'none' | 'byo_attached' | 'treeseed_managed';
|
|
161
|
+
export type TreeseedRuntimeRegistration = 'optional' | 'required' | 'none';
|
|
139
162
|
export interface TreeseedHostingConfig {
|
|
140
163
|
kind: TreeseedHostingKind;
|
|
141
164
|
registration?: TreeseedHostingRegistration;
|
|
@@ -143,6 +166,16 @@ export interface TreeseedHostingConfig {
|
|
|
143
166
|
teamId?: string;
|
|
144
167
|
projectId?: string;
|
|
145
168
|
}
|
|
169
|
+
export interface TreeseedHubConfig {
|
|
170
|
+
mode: TreeseedHubMode;
|
|
171
|
+
}
|
|
172
|
+
export interface TreeseedRuntimeConfig {
|
|
173
|
+
mode: TreeseedRuntimeMode;
|
|
174
|
+
registration?: TreeseedRuntimeRegistration;
|
|
175
|
+
marketBaseUrl?: string;
|
|
176
|
+
teamId?: string;
|
|
177
|
+
projectId?: string;
|
|
178
|
+
}
|
|
146
179
|
export interface TreeseedManagedServiceEnvironmentConfig {
|
|
147
180
|
baseUrl?: string;
|
|
148
181
|
domain?: string;
|
|
@@ -172,7 +205,6 @@ export interface TreeseedManagedServiceConfig {
|
|
|
172
205
|
}
|
|
173
206
|
export interface TreeseedManagedServicesConfig {
|
|
174
207
|
api?: TreeseedManagedServiceConfig;
|
|
175
|
-
agents?: TreeseedManagedServiceConfig;
|
|
176
208
|
[key: string]: TreeseedManagedServiceConfig | undefined;
|
|
177
209
|
}
|
|
178
210
|
export interface TreeseedPlatformSurfacesConfig {
|
|
@@ -196,6 +228,7 @@ export interface TreeseedProviderSelections {
|
|
|
196
228
|
runtime: string;
|
|
197
229
|
publish: string;
|
|
198
230
|
docs?: string;
|
|
231
|
+
serving?: TreeseedContentServingMode;
|
|
199
232
|
};
|
|
200
233
|
site?: string;
|
|
201
234
|
}
|
|
@@ -209,8 +242,11 @@ export interface TreeseedDeployConfig {
|
|
|
209
242
|
siteUrl: string;
|
|
210
243
|
contactEmail: string;
|
|
211
244
|
hosting?: TreeseedHostingConfig;
|
|
245
|
+
hub: TreeseedHubConfig;
|
|
246
|
+
runtime: TreeseedRuntimeConfig;
|
|
212
247
|
cloudflare: {
|
|
213
248
|
accountId: string;
|
|
249
|
+
zoneId?: string;
|
|
214
250
|
workerName?: string;
|
|
215
251
|
queueName?: string;
|
|
216
252
|
dlqName?: string;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import type { TreeseedDeployConfig } from './contracts.ts';
|
|
1
|
+
import type { TreeseedDeployConfig, TreeseedWebCachePolicyConfig } from './contracts.ts';
|
|
2
2
|
export declare function resolveTreeseedDeployConfigPath(configPath?: string): string;
|
|
3
3
|
export declare function resolveTreeseedDeployConfigPathFromRoot(tenantRoot: string, configPath?: string): string;
|
|
4
4
|
export declare function deriveCloudflareWorkerName(config: TreeseedDeployConfig): string;
|
|
5
|
+
export declare function resolveTreeseedWebCachePolicy(config: TreeseedDeployConfig): {
|
|
6
|
+
sourcePages: {
|
|
7
|
+
paths: string[];
|
|
8
|
+
browserTtlSeconds: number;
|
|
9
|
+
edgeTtlSeconds: number;
|
|
10
|
+
staleWhileRevalidateSeconds: number;
|
|
11
|
+
staleIfErrorSeconds: number;
|
|
12
|
+
};
|
|
13
|
+
contentPages: Required<TreeseedWebCachePolicyConfig>;
|
|
14
|
+
r2PublishedObjects: Required<TreeseedWebCachePolicyConfig>;
|
|
15
|
+
};
|
|
5
16
|
export declare function loadTreeseedDeployConfig(configPath?: string): TreeseedDeployConfig;
|
|
6
17
|
export declare function loadTreeseedDeployConfigFromPath(resolvedConfigPath: string): TreeseedDeployConfig;
|
|
@@ -18,8 +18,19 @@ const hostingFieldAliases = {
|
|
|
18
18
|
teamId: { key: "teamId", aliases: ["team_id"] },
|
|
19
19
|
projectId: { key: "projectId", aliases: ["project_id"] }
|
|
20
20
|
};
|
|
21
|
+
const hubFieldAliases = {
|
|
22
|
+
mode: { key: "mode", aliases: ["mode"] }
|
|
23
|
+
};
|
|
24
|
+
const runtimeFieldAliases = {
|
|
25
|
+
mode: { key: "mode", aliases: ["mode"] },
|
|
26
|
+
registration: { key: "registration", aliases: ["registration"] },
|
|
27
|
+
marketBaseUrl: { key: "marketBaseUrl", aliases: ["market_base_url"] },
|
|
28
|
+
teamId: { key: "teamId", aliases: ["team_id"] },
|
|
29
|
+
projectId: { key: "projectId", aliases: ["project_id"] }
|
|
30
|
+
};
|
|
21
31
|
const cloudflareFieldAliases = {
|
|
22
32
|
accountId: { key: "accountId", aliases: ["account_id"] },
|
|
33
|
+
zoneId: { key: "zoneId", aliases: ["zone_id"] },
|
|
23
34
|
workerName: { key: "workerName", aliases: ["worker_name"] },
|
|
24
35
|
queueName: { key: "queueName", aliases: ["queue_name"] },
|
|
25
36
|
dlqName: { key: "dlqName", aliases: ["dlq_name"] },
|
|
@@ -41,7 +52,26 @@ const cloudflareR2FieldAliases = {
|
|
|
41
52
|
previewRootTemplate: { key: "previewRootTemplate", aliases: ["preview_root_template", "preview_root"] },
|
|
42
53
|
previewTtlHours: { key: "previewTtlHours", aliases: ["preview_ttl_hours"] }
|
|
43
54
|
};
|
|
55
|
+
const webSurfaceCacheFieldAliases = {
|
|
56
|
+
sourcePages: { key: "sourcePages", aliases: ["source_pages"] },
|
|
57
|
+
contentPages: { key: "contentPages", aliases: ["content_pages"] },
|
|
58
|
+
r2PublishedObjects: { key: "r2PublishedObjects", aliases: ["r2_published_objects"] }
|
|
59
|
+
};
|
|
60
|
+
const webCachePolicyFieldAliases = {
|
|
61
|
+
browserTtlSeconds: { key: "browserTtlSeconds", aliases: ["browser_ttl_seconds"] },
|
|
62
|
+
edgeTtlSeconds: { key: "edgeTtlSeconds", aliases: ["edge_ttl_seconds"] },
|
|
63
|
+
staleWhileRevalidateSeconds: { key: "staleWhileRevalidateSeconds", aliases: ["stale_while_revalidate_seconds"] },
|
|
64
|
+
staleIfErrorSeconds: { key: "staleIfErrorSeconds", aliases: ["stale_if_error_seconds"] },
|
|
65
|
+
paths: { key: "paths", aliases: ["paths"] }
|
|
66
|
+
};
|
|
44
67
|
const CLOUDFLARE_ACCOUNT_ID_PLACEHOLDER = "replace-with-cloudflare-account-id";
|
|
68
|
+
const TREESEED_DEFAULT_SOURCE_PAGE_PURGE_PATHS = ["/", "/contact", "/404"];
|
|
69
|
+
const TREESEED_DEFAULT_LONG_LIVED_CACHE_POLICY = {
|
|
70
|
+
browserTtlSeconds: 0,
|
|
71
|
+
edgeTtlSeconds: 31536e3,
|
|
72
|
+
staleWhileRevalidateSeconds: 86400,
|
|
73
|
+
staleIfErrorSeconds: 86400
|
|
74
|
+
};
|
|
45
75
|
function expectString(value, label) {
|
|
46
76
|
if (typeof value !== "string" || !value.trim()) {
|
|
47
77
|
throw new Error(`Invalid deploy config: expected ${label} to be a non-empty string.`);
|
|
@@ -67,6 +97,15 @@ function optionalPositiveNumber(value, label) {
|
|
|
67
97
|
}
|
|
68
98
|
return value;
|
|
69
99
|
}
|
|
100
|
+
function optionalNonNegativeNumber(value, label) {
|
|
101
|
+
if (value === void 0) {
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
105
|
+
throw new Error(`Invalid deploy config: expected ${label} to be a non-negative number when provided.`);
|
|
106
|
+
}
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
70
109
|
function optionalEnum(value, label, allowed) {
|
|
71
110
|
if (value === void 0) {
|
|
72
111
|
return void 0;
|
|
@@ -138,9 +177,85 @@ function parseHostingConfig(value) {
|
|
|
138
177
|
"self_hosted_project"
|
|
139
178
|
]) ?? "self_hosted_project",
|
|
140
179
|
registration: optionalEnum(record.registration, "hosting.registration", ["optional", "none"]) ?? "none",
|
|
141
|
-
marketBaseUrl: optionalString(record.marketBaseUrl),
|
|
142
|
-
teamId: optionalString(record.teamId),
|
|
143
|
-
projectId: optionalString(record.projectId)
|
|
180
|
+
marketBaseUrl: optionalString(process.env.TREESEED_MARKET_API_BASE_URL) ?? optionalString(record.marketBaseUrl),
|
|
181
|
+
teamId: optionalString(process.env.TREESEED_HOSTING_TEAM_ID) ?? optionalString(record.teamId),
|
|
182
|
+
projectId: optionalString(process.env.TREESEED_PROJECT_ID) ?? optionalString(record.projectId)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function normalizePlanesFromLegacyHosting(hosting) {
|
|
186
|
+
if (!hosting) {
|
|
187
|
+
return {
|
|
188
|
+
hub: { mode: "treeseed_hosted" },
|
|
189
|
+
runtime: { mode: "none", registration: "none" }
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (hosting.kind === "market_control_plane" || hosting.kind === "hosted_project") {
|
|
193
|
+
return {
|
|
194
|
+
hub: { mode: "treeseed_hosted" },
|
|
195
|
+
runtime: {
|
|
196
|
+
mode: "treeseed_managed",
|
|
197
|
+
registration: hosting.kind === "market_control_plane" ? "none" : hosting.registration ?? "none",
|
|
198
|
+
marketBaseUrl: hosting.marketBaseUrl,
|
|
199
|
+
teamId: hosting.teamId,
|
|
200
|
+
projectId: hosting.projectId
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
hub: { mode: "customer_hosted" },
|
|
206
|
+
runtime: {
|
|
207
|
+
mode: "byo_attached",
|
|
208
|
+
registration: hosting.registration ?? "none",
|
|
209
|
+
marketBaseUrl: hosting.marketBaseUrl,
|
|
210
|
+
teamId: hosting.teamId,
|
|
211
|
+
projectId: hosting.projectId
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function normalizeLegacyHostingFromPlanes(hub, runtime) {
|
|
216
|
+
if (runtime.mode === "treeseed_managed" && hub.mode === "treeseed_hosted") {
|
|
217
|
+
return {
|
|
218
|
+
kind: "hosted_project",
|
|
219
|
+
registration: runtime.registration === "required" ? "optional" : runtime.registration ?? "none",
|
|
220
|
+
marketBaseUrl: runtime.marketBaseUrl,
|
|
221
|
+
teamId: runtime.teamId,
|
|
222
|
+
projectId: runtime.projectId
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
kind: "self_hosted_project",
|
|
227
|
+
registration: runtime.registration === "required" ? "optional" : runtime.registration ?? "none",
|
|
228
|
+
marketBaseUrl: runtime.marketBaseUrl,
|
|
229
|
+
teamId: runtime.teamId,
|
|
230
|
+
projectId: runtime.projectId
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function parseHubConfig(value, fallback) {
|
|
234
|
+
const record = normalizeAliasedRecord(
|
|
235
|
+
hubFieldAliases,
|
|
236
|
+
optionalRecord(value, "hub") ?? {}
|
|
237
|
+
);
|
|
238
|
+
if (!value || Object.keys(record).length === 0) {
|
|
239
|
+
return fallback;
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
mode: optionalEnum(record.mode, "hub.mode", ["treeseed_hosted", "customer_hosted"]) ?? fallback.mode
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function parseRuntimeConfig(value, fallback) {
|
|
246
|
+
const record = normalizeAliasedRecord(
|
|
247
|
+
runtimeFieldAliases,
|
|
248
|
+
optionalRecord(value, "runtime") ?? {}
|
|
249
|
+
);
|
|
250
|
+
if (!value || Object.keys(record).length === 0) {
|
|
251
|
+
return fallback;
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
mode: optionalEnum(record.mode, "runtime.mode", ["none", "byo_attached", "treeseed_managed"]) ?? fallback.mode,
|
|
255
|
+
registration: optionalEnum(record.registration, "runtime.registration", ["optional", "required", "none"]) ?? fallback.registration ?? "none",
|
|
256
|
+
marketBaseUrl: optionalString(process.env.TREESEED_MARKET_API_BASE_URL) ?? fallback.marketBaseUrl,
|
|
257
|
+
teamId: optionalString(process.env.TREESEED_HOSTING_TEAM_ID) ?? fallback.teamId,
|
|
258
|
+
projectId: optionalString(process.env.TREESEED_PROJECT_ID) ?? fallback.projectId
|
|
144
259
|
};
|
|
145
260
|
}
|
|
146
261
|
function parseProviderSelections(value) {
|
|
@@ -192,7 +307,12 @@ function parseProviderSelections(value) {
|
|
|
192
307
|
docs: expectString(
|
|
193
308
|
contentProviders.docs ?? contentProviders.runtime ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.docs ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.runtime,
|
|
194
309
|
"providers.content.docs"
|
|
195
|
-
)
|
|
310
|
+
),
|
|
311
|
+
serving: optionalEnum(
|
|
312
|
+
contentProviders.serving,
|
|
313
|
+
"providers.content.serving",
|
|
314
|
+
["local_collections", "published_runtime"]
|
|
315
|
+
) ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.serving
|
|
196
316
|
},
|
|
197
317
|
site: expectString(record.site ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.site, "providers.site")
|
|
198
318
|
};
|
|
@@ -246,6 +366,11 @@ function parseManagedServicesConfig(value) {
|
|
|
246
366
|
])
|
|
247
367
|
);
|
|
248
368
|
}
|
|
369
|
+
function inferManagedRuntimeFromServices(services) {
|
|
370
|
+
return Object.values(services ?? {}).some(
|
|
371
|
+
(service) => service && service.enabled !== false && (service.provider ?? "railway") === "railway"
|
|
372
|
+
);
|
|
373
|
+
}
|
|
249
374
|
function parsePlatformSurfaceConfig(value, label) {
|
|
250
375
|
const record = optionalRecord(value, label);
|
|
251
376
|
if (!record) {
|
|
@@ -256,8 +381,47 @@ function parsePlatformSurfaceConfig(value, label) {
|
|
|
256
381
|
provider: optionalString(record.provider),
|
|
257
382
|
rootDir: optionalString(record.rootDir),
|
|
258
383
|
publicBaseUrl: optionalString(record.publicBaseUrl),
|
|
259
|
-
localBaseUrl: optionalString(record.localBaseUrl)
|
|
384
|
+
localBaseUrl: optionalString(record.localBaseUrl),
|
|
385
|
+
cache: parseWebSurfaceCacheConfig(record.cache, `${label}.cache`)
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function parseWebSurfaceCacheConfig(value, label) {
|
|
389
|
+
const record = normalizeAliasedRecord(
|
|
390
|
+
webSurfaceCacheFieldAliases,
|
|
391
|
+
optionalRecord(value, label) ?? {}
|
|
392
|
+
);
|
|
393
|
+
if (!value || Object.keys(record).length === 0) {
|
|
394
|
+
return void 0;
|
|
395
|
+
}
|
|
396
|
+
return {
|
|
397
|
+
sourcePages: parseWebCachePolicyRecord(record.sourcePages, `${label}.sourcePages`, {
|
|
398
|
+
paths: TREESEED_DEFAULT_SOURCE_PAGE_PURGE_PATHS
|
|
399
|
+
}),
|
|
400
|
+
contentPages: parseWebCachePolicyRecord(record.contentPages, `${label}.contentPages`),
|
|
401
|
+
r2PublishedObjects: parseWebCachePolicyRecord(record.r2PublishedObjects, `${label}.r2PublishedObjects`)
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function parseWebCachePolicyRecord(value, label, options = {}) {
|
|
405
|
+
const record = normalizeAliasedRecord(
|
|
406
|
+
webCachePolicyFieldAliases,
|
|
407
|
+
optionalRecord(value, label) ?? {}
|
|
408
|
+
);
|
|
409
|
+
if (!value || Object.keys(record).length === 0) {
|
|
410
|
+
return options.paths ? { paths: [...options.paths] } : void 0;
|
|
411
|
+
}
|
|
412
|
+
const parsed = {
|
|
413
|
+
browserTtlSeconds: optionalNonNegativeNumber(record.browserTtlSeconds, `${label}.browserTtlSeconds`),
|
|
414
|
+
edgeTtlSeconds: optionalNonNegativeNumber(record.edgeTtlSeconds, `${label}.edgeTtlSeconds`),
|
|
415
|
+
staleWhileRevalidateSeconds: optionalNonNegativeNumber(
|
|
416
|
+
record.staleWhileRevalidateSeconds,
|
|
417
|
+
`${label}.staleWhileRevalidateSeconds`
|
|
418
|
+
),
|
|
419
|
+
staleIfErrorSeconds: optionalNonNegativeNumber(record.staleIfErrorSeconds, `${label}.staleIfErrorSeconds`)
|
|
260
420
|
};
|
|
421
|
+
if (options.paths) {
|
|
422
|
+
parsed.paths = [...new Set(optionalStringArray(record.paths, `${label}.paths`) ?? options.paths)];
|
|
423
|
+
}
|
|
424
|
+
return parsed;
|
|
261
425
|
}
|
|
262
426
|
function parsePlatformSurfacesConfig(value) {
|
|
263
427
|
const record = optionalRecord(value, "surfaces");
|
|
@@ -298,33 +462,47 @@ function parseDeployConfig(raw) {
|
|
|
298
462
|
cloudflareR2FieldAliases,
|
|
299
463
|
optionalRecord(cloudflare.r2, "cloudflare.r2") ?? {}
|
|
300
464
|
);
|
|
465
|
+
const hosting = parseHostingConfig(parsed.hosting);
|
|
466
|
+
const services = parseManagedServicesConfig(parsed.services);
|
|
467
|
+
const normalizedPlanes = normalizePlanesFromLegacyHosting(hosting);
|
|
468
|
+
const inferredPlanes = !hosting && !parsed.hub && !parsed.runtime && inferManagedRuntimeFromServices(services) ? {
|
|
469
|
+
hub: { mode: "customer_hosted" },
|
|
470
|
+
runtime: { mode: "treeseed_managed", registration: "none" }
|
|
471
|
+
} : normalizedPlanes;
|
|
472
|
+
const hub = parseHubConfig(parsed.hub, inferredPlanes.hub);
|
|
473
|
+
const runtime = parseRuntimeConfig(parsed.runtime, inferredPlanes.runtime);
|
|
301
474
|
const smtp = optionalRecord(parsed.smtp, "smtp") ?? {};
|
|
302
475
|
const turnstile = optionalRecord(parsed.turnstile, "turnstile") ?? {};
|
|
303
476
|
optionalBoolean(turnstile.enabled, "turnstile.enabled");
|
|
477
|
+
const normalizedHosting = normalizeLegacyHostingFromPlanes(hub, runtime);
|
|
478
|
+
const compatibilityHosting = hosting && !parsed.hub && !parsed.runtime ? hosting : normalizedHosting;
|
|
304
479
|
return {
|
|
305
480
|
name: expectString(parsed.name, "name"),
|
|
306
481
|
slug: expectString(parsed.slug, "slug"),
|
|
307
482
|
siteUrl: expectString(parsed.siteUrl, "siteUrl"),
|
|
308
483
|
contactEmail: expectString(parsed.contactEmail, "contactEmail"),
|
|
309
|
-
hosting:
|
|
484
|
+
hosting: compatibilityHosting,
|
|
485
|
+
hub,
|
|
486
|
+
runtime,
|
|
310
487
|
cloudflare: {
|
|
311
|
-
accountId: optionalCloudflareAccountId(
|
|
488
|
+
accountId: optionalCloudflareAccountId(process.env.CLOUDFLARE_ACCOUNT_ID) ?? CLOUDFLARE_ACCOUNT_ID_PLACEHOLDER,
|
|
489
|
+
zoneId: optionalString(cloudflare.zoneId),
|
|
312
490
|
workerName: optionalString(cloudflare.workerName),
|
|
313
491
|
queueName: optionalString(cloudflare.queueName),
|
|
314
492
|
dlqName: optionalString(cloudflare.dlqName),
|
|
315
493
|
d1Binding: optionalString(cloudflare.d1Binding),
|
|
316
494
|
queueBinding: optionalString(cloudflare.queueBinding),
|
|
317
495
|
pages: cloudflare.pages === void 0 ? void 0 : {
|
|
318
|
-
projectName: optionalString(
|
|
319
|
-
previewProjectName: optionalString(
|
|
496
|
+
projectName: optionalString(process.env.TREESEED_CLOUDFLARE_PAGES_PROJECT_NAME) ?? optionalString(cloudflarePages.projectName),
|
|
497
|
+
previewProjectName: optionalString(process.env.TREESEED_CLOUDFLARE_PAGES_PREVIEW_PROJECT_NAME) ?? optionalString(cloudflarePages.previewProjectName),
|
|
320
498
|
productionBranch: optionalString(cloudflarePages.productionBranch) ?? "main",
|
|
321
499
|
stagingBranch: optionalString(cloudflarePages.stagingBranch) ?? "staging",
|
|
322
500
|
buildOutputDir: optionalString(cloudflarePages.buildOutputDir)
|
|
323
501
|
},
|
|
324
502
|
r2: cloudflare.r2 === void 0 ? void 0 : {
|
|
325
|
-
binding: optionalString(
|
|
326
|
-
bucketName: optionalString(
|
|
327
|
-
publicBaseUrl: optionalString(
|
|
503
|
+
binding: optionalString(process.env.TREESEED_CONTENT_BUCKET_BINDING),
|
|
504
|
+
bucketName: optionalString(process.env.TREESEED_CONTENT_BUCKET_NAME),
|
|
505
|
+
publicBaseUrl: optionalString(process.env.TREESEED_CONTENT_PUBLIC_BASE_URL),
|
|
328
506
|
manifestKeyTemplate: optionalString(cloudflareR2.manifestKeyTemplate) ?? "teams/{teamId}/published/common.json",
|
|
329
507
|
previewRootTemplate: optionalString(cloudflareR2.previewRootTemplate) ?? "teams/{teamId}/previews",
|
|
330
508
|
previewTtlHours: optionalPositiveNumber(cloudflareR2.previewTtlHours, "cloudflare.r2.previewTtlHours") ?? 168
|
|
@@ -333,12 +511,12 @@ function parseDeployConfig(raw) {
|
|
|
333
511
|
plugins: parsePluginReferences(parsed.plugins),
|
|
334
512
|
providers: parseProviderSelections(parsed.providers),
|
|
335
513
|
surfaces: parsePlatformSurfacesConfig(parsed.surfaces),
|
|
336
|
-
services
|
|
514
|
+
services,
|
|
337
515
|
smtp: {
|
|
338
516
|
enabled: optionalBoolean(smtp.enabled, "smtp.enabled")
|
|
339
517
|
},
|
|
340
518
|
turnstile: {
|
|
341
|
-
enabled:
|
|
519
|
+
enabled: optionalBoolean(turnstile.enabled, "turnstile.enabled") ?? false
|
|
342
520
|
},
|
|
343
521
|
export: parseExportConfig(parsed.export)
|
|
344
522
|
};
|
|
@@ -357,6 +535,26 @@ function resolveTreeseedDeployConfigPathFromRoot(tenantRoot, configPath = "trees
|
|
|
357
535
|
function deriveCloudflareWorkerName(config) {
|
|
358
536
|
return config.cloudflare.workerName?.trim() || config.slug;
|
|
359
537
|
}
|
|
538
|
+
function resolveLongLivedCachePolicy(configured) {
|
|
539
|
+
return {
|
|
540
|
+
browserTtlSeconds: configured?.browserTtlSeconds ?? TREESEED_DEFAULT_LONG_LIVED_CACHE_POLICY.browserTtlSeconds,
|
|
541
|
+
edgeTtlSeconds: configured?.edgeTtlSeconds ?? TREESEED_DEFAULT_LONG_LIVED_CACHE_POLICY.edgeTtlSeconds,
|
|
542
|
+
staleWhileRevalidateSeconds: configured?.staleWhileRevalidateSeconds ?? TREESEED_DEFAULT_LONG_LIVED_CACHE_POLICY.staleWhileRevalidateSeconds,
|
|
543
|
+
staleIfErrorSeconds: configured?.staleIfErrorSeconds ?? TREESEED_DEFAULT_LONG_LIVED_CACHE_POLICY.staleIfErrorSeconds
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
function resolveTreeseedWebCachePolicy(config) {
|
|
547
|
+
const cache = config.surfaces?.web?.cache ?? {};
|
|
548
|
+
const sourcePages = cache.sourcePages;
|
|
549
|
+
return {
|
|
550
|
+
sourcePages: {
|
|
551
|
+
...resolveLongLivedCachePolicy(sourcePages),
|
|
552
|
+
paths: [...new Set(sourcePages?.paths ?? TREESEED_DEFAULT_SOURCE_PAGE_PURGE_PATHS)]
|
|
553
|
+
},
|
|
554
|
+
contentPages: resolveLongLivedCachePolicy(cache.contentPages),
|
|
555
|
+
r2PublishedObjects: resolveLongLivedCachePolicy(cache.r2PublishedObjects)
|
|
556
|
+
};
|
|
557
|
+
}
|
|
360
558
|
function loadTreeseedDeployConfig(configPath = "treeseed.site.yaml") {
|
|
361
559
|
const resolvedConfigPath = resolveTreeseedDeployConfigPath(configPath);
|
|
362
560
|
return loadTreeseedDeployConfigFromPath(resolvedConfigPath);
|
|
@@ -379,5 +577,6 @@ export {
|
|
|
379
577
|
loadTreeseedDeployConfig,
|
|
380
578
|
loadTreeseedDeployConfigFromPath,
|
|
381
579
|
resolveTreeseedDeployConfigPath,
|
|
382
|
-
resolveTreeseedDeployConfigPathFromRoot
|
|
580
|
+
resolveTreeseedDeployConfigPathFromRoot,
|
|
581
|
+
resolveTreeseedWebCachePolicy
|
|
383
582
|
};
|
|
@@ -14,6 +14,7 @@ export declare function getTreeseedAgentProviderSelections(): {
|
|
|
14
14
|
export declare function getTreeseedDeployProvider(): string;
|
|
15
15
|
export declare function getTreeseedContentRuntimeProvider(): string;
|
|
16
16
|
export declare function getTreeseedContentPublishProvider(): string;
|
|
17
|
+
export declare function getTreeseedContentServingMode(): string;
|
|
17
18
|
export declare function getTreeseedDocsProvider(): string;
|
|
18
19
|
export declare function getTreeseedSiteProvider(): string;
|
|
19
20
|
export declare function isTreeseedSmtpEnabled(): boolean;
|
|
@@ -17,7 +17,7 @@ function defaultDeployConfig() {
|
|
|
17
17
|
enabled: false
|
|
18
18
|
},
|
|
19
19
|
turnstile: {
|
|
20
|
-
enabled:
|
|
20
|
+
enabled: false
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -58,6 +58,13 @@ function getTreeseedContentRuntimeProvider() {
|
|
|
58
58
|
function getTreeseedContentPublishProvider() {
|
|
59
59
|
return getTreeseedDeployConfig().providers?.content?.publish ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.publish;
|
|
60
60
|
}
|
|
61
|
+
function getTreeseedContentServingMode() {
|
|
62
|
+
const override = process.env.TREESEED_CONTENT_SERVING_MODE?.trim();
|
|
63
|
+
if (override === "local_collections" || override === "published_runtime") {
|
|
64
|
+
return override;
|
|
65
|
+
}
|
|
66
|
+
return getTreeseedDeployConfig().providers?.content?.serving ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.serving;
|
|
67
|
+
}
|
|
61
68
|
function getTreeseedDocsProvider() {
|
|
62
69
|
return getTreeseedDeployConfig().providers?.content?.docs ?? getTreeseedDeployConfig().providers?.content?.runtime ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.docs ?? TREESEED_DEFAULT_PROVIDER_SELECTIONS.content.runtime;
|
|
63
70
|
}
|
|
@@ -68,12 +75,13 @@ function isTreeseedSmtpEnabled() {
|
|
|
68
75
|
return getTreeseedDeployConfig().smtp?.enabled ?? false;
|
|
69
76
|
}
|
|
70
77
|
function isTreeseedTurnstileEnabled() {
|
|
71
|
-
return getTreeseedDeployConfig().turnstile?.enabled ??
|
|
78
|
+
return getTreeseedDeployConfig().turnstile?.enabled ?? false;
|
|
72
79
|
}
|
|
73
80
|
export {
|
|
74
81
|
getTreeseedAgentProviderSelections,
|
|
75
82
|
getTreeseedContentPublishProvider,
|
|
76
83
|
getTreeseedContentRuntimeProvider,
|
|
84
|
+
getTreeseedContentServingMode,
|
|
77
85
|
getTreeseedDeployConfig,
|
|
78
86
|
getTreeseedDeployProvider,
|
|
79
87
|
getTreeseedDocsProvider,
|