@supatype/cli 0.2.0 → 0.3.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +190 -153
- package/.turbo/turbo-typecheck.log +1 -1
- package/dist/api-config-cache.d.ts +34 -0
- package/dist/api-config-cache.d.ts.map +1 -0
- package/dist/api-config-cache.js +123 -0
- package/dist/api-config-cache.js.map +1 -0
- package/dist/cache-identity-scope.d.ts +38 -0
- package/dist/cache-identity-scope.d.ts.map +1 -0
- package/dist/cache-identity-scope.js +70 -0
- package/dist/cache-identity-scope.js.map +1 -0
- package/dist/cache-provider.d.ts +30 -0
- package/dist/cache-provider.d.ts.map +1 -0
- package/dist/cache-provider.js +60 -0
- package/dist/cache-provider.js.map +1 -0
- package/dist/cli-version-embedded.js +1 -1
- package/dist/commands/add.js +1 -1
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/cache.d.ts +1 -1
- package/dist/commands/cache.js +3 -3
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +2 -1
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +2 -1
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +61 -8
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +2 -1
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +6 -2
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +13 -9
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +14 -0
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +37 -0
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +2 -1
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +52 -1
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/self-host.d.ts.map +1 -1
- package/dist/commands/self-host.js +9 -0
- package/dist/commands/self-host.js.map +1 -1
- package/dist/compose-services.d.ts.map +1 -1
- package/dist/compose-services.js +2 -1
- package/dist/compose-services.js.map +1 -1
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +18 -7
- package/dist/dev-compose.js.map +1 -1
- package/dist/engine-floor.d.ts +11 -1
- package/dist/engine-floor.d.ts.map +1 -1
- package/dist/engine-floor.js +49 -16
- package/dist/engine-floor.js.map +1 -1
- package/dist/functions-deno-types.d.ts +9 -0
- package/dist/functions-deno-types.d.ts.map +1 -1
- package/dist/functions-deno-types.js +45 -1
- package/dist/functions-deno-types.js.map +1 -1
- package/dist/functions-router-gen.d.ts.map +1 -1
- package/dist/functions-router-gen.js +113 -81
- package/dist/functions-router-gen.js.map +1 -1
- package/dist/kong-config.d.ts +1 -1
- package/dist/model-cache.d.ts +17 -0
- package/dist/model-cache.d.ts.map +1 -0
- package/dist/model-cache.js +45 -0
- package/dist/model-cache.js.map +1 -0
- package/dist/model-hooks.d.ts +5 -0
- package/dist/model-hooks.d.ts.map +1 -1
- package/dist/model-hooks.js +29 -1
- package/dist/model-hooks.js.map +1 -1
- package/dist/model-versioning.d.ts +80 -0
- package/dist/model-versioning.d.ts.map +1 -0
- package/dist/model-versioning.js +140 -0
- package/dist/model-versioning.js.map +1 -0
- package/dist/postgres-ctl.d.ts +55 -0
- package/dist/postgres-ctl.d.ts.map +1 -1
- package/dist/postgres-ctl.js +84 -8
- package/dist/postgres-ctl.js.map +1 -1
- package/dist/preview-config-check.d.ts +21 -0
- package/dist/preview-config-check.d.ts.map +1 -0
- package/dist/preview-config-check.js +47 -0
- package/dist/preview-config-check.js.map +1 -0
- package/dist/project-config.d.ts +182 -5
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +125 -8
- package/dist/project-config.js.map +1 -1
- package/dist/resolve-target.d.ts +9 -0
- package/dist/resolve-target.d.ts.map +1 -1
- package/dist/resolve-target.js.map +1 -1
- package/dist/rest-cache-admin.d.ts.map +1 -1
- package/dist/rest-cache-admin.js +6 -2
- package/dist/rest-cache-admin.js.map +1 -1
- package/dist/schema-ast-v2.d.ts +32 -1
- package/dist/schema-ast-v2.d.ts.map +1 -1
- package/dist/schema-ast-v2.js +14 -1
- package/dist/schema-ast-v2.js.map +1 -1
- package/dist/self-host-compose.d.ts +20 -1
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +181 -27
- package/dist/self-host-compose.js.map +1 -1
- package/dist/studio-admin-roles.d.ts +8 -1
- package/dist/studio-admin-roles.d.ts.map +1 -1
- package/dist/studio-admin-roles.js +16 -2
- package/dist/studio-admin-roles.js.map +1 -1
- package/dist/type-extractor.d.ts +7 -0
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +234 -3
- package/dist/type-extractor.js.map +1 -1
- package/package.json +2 -2
- package/src/api-config-cache.ts +142 -0
- package/src/cache-identity-scope.ts +92 -0
- package/src/cache-provider.ts +61 -0
- package/src/cli-version-embedded.ts +1 -1
- package/src/commands/add.ts +1 -1
- package/src/commands/cache.ts +3 -3
- package/src/commands/cloud.ts +2 -1
- package/src/commands/deploy.ts +2 -1
- package/src/commands/dev.ts +68 -7
- package/src/commands/diff.ts +2 -1
- package/src/commands/functions.ts +6 -2
- package/src/commands/init.ts +13 -9
- package/src/commands/keys.ts +40 -0
- package/src/commands/migrate.ts +2 -1
- package/src/commands/push.ts +57 -1
- package/src/commands/self-host.ts +9 -0
- package/src/compose-services.ts +2 -1
- package/src/dev-compose.ts +18 -7
- package/src/engine-floor.ts +73 -16
- package/src/functions-deno-types.ts +48 -1
- package/src/functions-router-gen.ts +113 -81
- package/src/kong-config.ts +1 -1
- package/src/model-cache.ts +74 -0
- package/src/model-hooks.ts +26 -2
- package/src/model-versioning.ts +167 -0
- package/src/postgres-ctl.ts +103 -9
- package/src/preview-config-check.ts +52 -0
- package/src/project-config.ts +273 -11
- package/src/resolve-target.ts +11 -1
- package/src/rest-cache-admin.ts +8 -2
- package/src/schema-ast-v2.ts +47 -0
- package/src/self-host-compose.ts +204 -27
- package/src/studio-admin-roles.ts +16 -2
- package/src/type-extractor.ts +281 -2
- package/tests/api-config-cache-seed.test.ts +180 -0
- package/tests/cache-identity-scope.test.ts +61 -0
- package/tests/cache-provider-config.test.ts +132 -0
- package/tests/engine-floor.test.ts +43 -0
- package/tests/external-database-compose.test.ts +74 -3
- package/tests/field-masking-tier.test.ts +3 -3
- package/tests/fixtures/identity-scope-corpus.json +42 -0
- package/tests/functions-concurrency.test.ts +71 -0
- package/tests/init.test.ts +36 -2
- package/tests/model-cache-declaration.test.ts +229 -0
- package/tests/model-cache-manifest.test.ts +99 -0
- package/tests/model-hooks.test.ts +55 -0
- package/tests/model-versions.test.ts +229 -0
- package/tests/native-keyspace.test.ts +130 -0
- package/tests/preview-config-check.test.ts +104 -0
- package/tests/rest-cache-admin.test.ts +36 -0
- package/tests/runtime-contract.test.ts +176 -22
- package/tests/self-host-keys.test.ts +92 -0
- package/tests/studio-admin-roles.test.ts +32 -0
- package/tests/type-extractor.test.ts +113 -0
- package/tsconfig.tsbuildinfo +1 -1
package/dist/schema-ast-v2.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ export interface DbFieldAnnotations {
|
|
|
42
42
|
export interface PlatformFieldAnnotations {
|
|
43
43
|
editor?: string;
|
|
44
44
|
readOnly?: boolean;
|
|
45
|
+
/** Studio searches this column in the list view. Set by `Searchable<T>`. */
|
|
46
|
+
searchable?: boolean;
|
|
45
47
|
}
|
|
46
48
|
export interface FieldAnnotations {
|
|
47
49
|
db?: DbFieldAnnotations;
|
|
@@ -87,6 +89,17 @@ export interface KernelFieldFacts {
|
|
|
87
89
|
tsType?: string;
|
|
88
90
|
index?: boolean;
|
|
89
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* The `cache` declaration as it reaches the AST. See `ModelMeta.cache` in `@supatype/types` for
|
|
94
|
+
* what each setting means; this is the wire shape, kept narrow so a typo in the extractor is a
|
|
95
|
+
* type error rather than an extra key nobody reads.
|
|
96
|
+
*/
|
|
97
|
+
export interface ModelCacheAst {
|
|
98
|
+
enabled?: boolean;
|
|
99
|
+
maxTtl?: number;
|
|
100
|
+
public?: boolean;
|
|
101
|
+
rows?: boolean;
|
|
102
|
+
}
|
|
90
103
|
/** Internal parse result: not serialized. */
|
|
91
104
|
export interface ParsedField {
|
|
92
105
|
kind: FieldKind;
|
|
@@ -118,6 +131,9 @@ export interface ModelAstV2 {
|
|
|
118
131
|
access: Record<string, unknown>;
|
|
119
132
|
hooks?: Record<string, unknown>;
|
|
120
133
|
validate?: Record<string, unknown>;
|
|
134
|
+
/** Columns Studio's list view searches. See {@link emitModel}. */
|
|
135
|
+
searchFields?: string[];
|
|
136
|
+
cache?: ModelCacheAst;
|
|
121
137
|
};
|
|
122
138
|
};
|
|
123
139
|
}
|
|
@@ -136,6 +152,21 @@ export interface ExtractedSchemaAstV2 {
|
|
|
136
152
|
storageBuckets?: ExtractedStorageBucketAst[];
|
|
137
153
|
locales?: string[];
|
|
138
154
|
defaultLocale?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Draft visibility and preview-link bounds, from `supatype.config.ts`.
|
|
157
|
+
*
|
|
158
|
+
* Not extracted from the schema like everything else here: it is a project setting that the
|
|
159
|
+
* engine needs at the moment it compiles the draft policies, so it rides the same payload rather
|
|
160
|
+
* than growing a delivery path of its own. Attached by `withPublishing`, and absent for a project
|
|
161
|
+
* with no versioned model.
|
|
162
|
+
*/
|
|
163
|
+
publishing?: {
|
|
164
|
+
draftVisibility: string[];
|
|
165
|
+
previewDefaultTtl: number;
|
|
166
|
+
previewMaxRecordTtl: number;
|
|
167
|
+
previewMaxProjectTtl: number;
|
|
168
|
+
previewAllowProjectScope: boolean;
|
|
169
|
+
};
|
|
139
170
|
}
|
|
140
171
|
/**
|
|
141
172
|
* Start a parsed field with kind defaults for db/platform namespaces.
|
|
@@ -153,7 +184,7 @@ export declare function scalar(kind: FieldKind, extra?: {
|
|
|
153
184
|
platform?: Partial<PlatformFieldAnnotations>;
|
|
154
185
|
}): ParsedField;
|
|
155
186
|
export declare function emitField(parsed: ParsedField): FieldAstV2;
|
|
156
|
-
export declare function emitModel(name: string, fields: Record<string, FieldAstV2>, options: Record<string, unknown>, tableName: string, access: Record<string, unknown>, indexes?: unknown[], hooks?: Record<string, unknown>, constraints?: unknown[], validators?: Record<string, unknown
|
|
187
|
+
export declare function emitModel(name: string, fields: Record<string, FieldAstV2>, options: Record<string, unknown>, tableName: string, access: Record<string, unknown>, indexes?: unknown[], hooks?: Record<string, unknown>, constraints?: unknown[], validators?: Record<string, unknown>, searchFields?: string[], cache?: ModelCacheAst | undefined): ModelAstV2;
|
|
157
188
|
export declare function emitSchema(models: ModelAstV2[], extras?: {
|
|
158
189
|
storageBuckets?: ExtractedSchemaAstV2["storageBuckets"];
|
|
159
190
|
locales?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-ast-v2.d.ts","sourceRoot":"","sources":["../src/schema-ast-v2.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAItD,YAAY,EAAE,eAAe,EAAE,CAAA;AAE/B,eAAO,MAAM,WAAW,EAAG,CAAU,CAAA;AAErC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,qaAiDd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpD,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAExC,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"schema-ast-v2.d.ts","sourceRoot":"","sources":["../src/schema-ast-v2.ts"],"names":[],"mappings":"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"}
|
package/dist/schema-ast-v2.js
CHANGED
|
@@ -277,7 +277,7 @@ export function emitField(parsed) {
|
|
|
277
277
|
wire.annotations = annotations;
|
|
278
278
|
return wire;
|
|
279
279
|
}
|
|
280
|
-
export function emitModel(name, fields, options, tableName, access, indexes = [], hooks = {}, constraints = [], validators = {}) {
|
|
280
|
+
export function emitModel(name, fields, options, tableName, access, indexes = [], hooks = {}, constraints = [], validators = {}, searchFields = [], cache) {
|
|
281
281
|
return {
|
|
282
282
|
name,
|
|
283
283
|
fields,
|
|
@@ -290,10 +290,23 @@ export function emitModel(name, fields, options, tableName, access, indexes = []
|
|
|
290
290
|
// supatype-server reads them, Postgres never sees them.
|
|
291
291
|
// Validators sit in `platform` beside `hooks`: both are enforced by the API layer on the
|
|
292
292
|
// write path, and neither is something Postgres knows about.
|
|
293
|
+
// `searchFields` sits in `platform` because it is an admin-UI concern: Studio's list view
|
|
294
|
+
// renders its search box when a model has them and filters on the first. Postgres knows
|
|
295
|
+
// nothing about it, which is why it is not in `db` beside `indexes` — searching a column and
|
|
296
|
+
// indexing one are different asks, and `Indexed` already covers the latter.
|
|
293
297
|
platform: {
|
|
294
298
|
access,
|
|
295
299
|
...(Object.keys(hooks).length > 0 && { hooks }),
|
|
296
300
|
...(Object.keys(validators).length > 0 && { validate: validators }),
|
|
301
|
+
...(searchFields.length > 0 && { searchFields }),
|
|
302
|
+
// Cache sits in `platform` beside `hooks` for the same reason, and travels the same way:
|
|
303
|
+
// the route manifest, not this AST. The schema engine re-serialises its own parsed struct
|
|
304
|
+
// when it writes `ast_snapshot`, and its `PlatformModelAnnotations` knows only `access`
|
|
305
|
+
// and `searchFields` — so this key, like `hooks` above it, does not survive that round
|
|
306
|
+
// trip and the manifest is what the server actually reads. Kept here because the AST is
|
|
307
|
+
// the schema's own description of itself, and a reader looking for the declaration should
|
|
308
|
+
// find it next to the other API-layer concerns.
|
|
309
|
+
...(cache !== undefined && { cache }),
|
|
297
310
|
},
|
|
298
311
|
},
|
|
299
312
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-ast-v2.js","sourceRoot":"","sources":["../src/schema-ast-v2.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAU,CAAA;AAErC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc;IACd,MAAM;IACN,OAAO;IACP,KAAK;IACL,MAAM;IACN,OAAO;IACP,KAAK;IACL,IAAI;IACJ,MAAM;IACN,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;IACV,OAAO;IACP,UAAU;IACV,SAAS;IACT,UAAU;IACV,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,WAAW;IACX,SAAS;IACT,OAAO;IACP,WAAW;IACX,UAAU;IACV,WAAW;IACX,MAAM;IACN,UAAU;IACV,oCAAoC;IACpC,OAAO;IACP,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,MAAM;IACN,sBAAsB;IACtB,SAAS;IACT,MAAM;IACN,2BAA2B;IAC3B,OAAO;IACP,MAAM;IACN,KAAK;IACL,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,mEAAmE;IACnE,YAAY;IACZ,aAAa;IACb,YAAY;CACJ,CAAA;
|
|
1
|
+
{"version":3,"file":"schema-ast-v2.js","sourceRoot":"","sources":["../src/schema-ast-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { type FieldMaskingTier } from "./field-masking-tier.js";
|
|
|
4
4
|
/** Env keys written when `versions` pins exist in supatype.config.ts. */
|
|
5
5
|
export declare const COMPOSE_PINNED_IMAGE_ENV_KEYS: readonly ["SUPATYPE_ENGINE_IMAGE", "SUPATYPE_SERVER_IMAGE", "SUPATYPE_POSTGRES_IMAGE"];
|
|
6
6
|
/** Compose image env vars that may be overridden manually in `.env`. */
|
|
7
|
-
export declare const COMPOSE_IMAGE_ENV_KEYS: readonly ["SUPATYPE_ENGINE_IMAGE", "SUPATYPE_SERVER_IMAGE", "SUPATYPE_POSTGRES_IMAGE", "SUPATYPE_CONTROL_PLANE_IMAGE", "SUPATYPE_AUTH_IMAGE", "SUPATYPE_STUDIO_IMAGE", "SUPATYPE_STORAGE_IMAGE", "SUPATYPE_FUNCTIONS_WORKER_IMAGE"];
|
|
7
|
+
export declare const COMPOSE_IMAGE_ENV_KEYS: readonly ["SUPATYPE_ENGINE_IMAGE", "SUPATYPE_SERVER_IMAGE", "SUPATYPE_POSTGRES_IMAGE", "SUPATYPE_CONTROL_PLANE_IMAGE", "SUPATYPE_AUTH_IMAGE", "SUPATYPE_STUDIO_IMAGE", "SUPATYPE_STORAGE_IMAGE", "SUPATYPE_FUNCTIONS_WORKER_IMAGE", "SUPATYPE_SEAWEEDFS_IMAGE"];
|
|
8
8
|
type DockerPinComponent = "engine" | "server" | "postgres";
|
|
9
9
|
/** Map a config version pin to a Docker Hub image reference. */
|
|
10
10
|
export declare function dockerImageRef(component: DockerPinComponent, version: string, config?: SupatypeProjectConfig): string;
|
|
@@ -27,11 +27,22 @@ export declare function composePullNeedsIgnoreFailures(config: SupatypeProjectCo
|
|
|
27
27
|
* Does not touch `.env`, server/postgres still use compose `:latest` defaults.
|
|
28
28
|
*/
|
|
29
29
|
export declare function schemaEngineImageForPush(config: SupatypeProjectConfig): Promise<string | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* SeaweedFS reads its identities from a file, so the stack's credentials are a generated artifact
|
|
32
|
+
* beside the compose file rather than two env vars inside it.
|
|
33
|
+
*
|
|
34
|
+
* There is deliberately no `anonymous` identity. Declaring one with `Read` would make every bucket
|
|
35
|
+
* world-readable and the per-bucket policy decorative, which is the opposite of what
|
|
36
|
+
* `applyPublicPolicy` is for: a bucket is public because its policy says so.
|
|
37
|
+
*/
|
|
38
|
+
export declare function renderSeaweedIdentities(): string;
|
|
30
39
|
export interface SelfHostComposePaths {
|
|
31
40
|
dir: string;
|
|
32
41
|
composePath: string;
|
|
33
42
|
kongPath: string;
|
|
34
43
|
nginxPath: string;
|
|
44
|
+
/** SeaweedFS identities, rendered beside the compose file the server reads them through. */
|
|
45
|
+
s3ConfigPath: string;
|
|
35
46
|
}
|
|
36
47
|
export declare function selfHostComposePaths(cwd: string): SelfHostComposePaths;
|
|
37
48
|
export declare function appUpstreamForCompose(config: SupatypeProjectConfig): string | undefined;
|
|
@@ -49,6 +60,14 @@ export interface SelfHostComposeOptions {
|
|
|
49
60
|
* rules and for every project on `supatype/postgres`.
|
|
50
61
|
*/
|
|
51
62
|
fieldMaskingTier?: FieldMaskingTier;
|
|
63
|
+
/**
|
|
64
|
+
* Whether any model declares `versions`, which puts the generated `draft` schema on the exposed
|
|
65
|
+
* list.
|
|
66
|
+
*
|
|
67
|
+
* Same reasoning as the tier above: only a caller that has loaded the schema can say, and left
|
|
68
|
+
* unset the list is today's, which is correct for every project with no versioned model.
|
|
69
|
+
*/
|
|
70
|
+
drafts?: boolean;
|
|
52
71
|
}
|
|
53
72
|
export declare function renderSelfHostCompose(config: SupatypeProjectConfig, cwd?: string, options?: SelfHostComposeOptions): string;
|
|
54
73
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"self-host-compose.d.ts","sourceRoot":"","sources":["../src/self-host-compose.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAElF,OAAO,EASL,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"self-host-compose.d.ts","sourceRoot":"","sources":["../src/self-host-compose.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,10 @@ import { fatalError } from "./ui/fatal.js";
|
|
|
6
6
|
import { apiSchemaList, externalDatabaseUrl, hooksPathFromProject, preferredFunctionsPathFromProject, realtimeEnabled, serviceRoleRoutes, selfHostTlsEnabled, usesExternalDatabase, } from "./project-config.js";
|
|
7
7
|
import { hasEngineOverride, hasStudioOverride, pinnedVersion, fetchLatestVersion, VERSION_PIN_LOCAL } from "./binary-cache.js";
|
|
8
8
|
import { buildKongDeclarative } from "./kong-config.js";
|
|
9
|
+
import { keyspaceInPostgres } from "./cache-provider.js";
|
|
9
10
|
import { readEnvFile } from "./env-file.js";
|
|
10
11
|
import { fieldMaskingTierFromProject } from "./field-masking-tier.js";
|
|
12
|
+
import { projectHasVersionedModels } from "./model-versioning.js";
|
|
11
13
|
/** Env keys written when `versions` pins exist in supatype.config.ts. */
|
|
12
14
|
export const COMPOSE_PINNED_IMAGE_ENV_KEYS = [
|
|
13
15
|
"SUPATYPE_ENGINE_IMAGE",
|
|
@@ -22,7 +24,25 @@ export const COMPOSE_IMAGE_ENV_KEYS = [
|
|
|
22
24
|
"SUPATYPE_STUDIO_IMAGE",
|
|
23
25
|
"SUPATYPE_STORAGE_IMAGE",
|
|
24
26
|
"SUPATYPE_FUNCTIONS_WORKER_IMAGE",
|
|
27
|
+
"SUPATYPE_SEAWEEDFS_IMAGE",
|
|
25
28
|
];
|
|
29
|
+
/** Pinned by digest, because the registry this replaced proved a tag can be taken away. */
|
|
30
|
+
const SEAWEEDFS_IMAGE = "chrislusf/seaweedfs:4.46@sha256:08d516132314207d10c8e37cbffc1f32b147d870169688734cc61c6231625b62";
|
|
31
|
+
/** Credentials the object store is configured with and the storage service is handed. */
|
|
32
|
+
/**
|
|
33
|
+
* The prefix Kong's ACME plugin stores its certificates under.
|
|
34
|
+
*
|
|
35
|
+
* Not a guess and not configurable: the plugin prefixes every key it writes
|
|
36
|
+
* with this and enforces it in its own `reserved_words.lua`, so it is the one
|
|
37
|
+
* durable thing in a keyspace that is otherwise a cache. Verified on a live
|
|
38
|
+
* instance — both ACME keys survived `kill -9` with only this prefix named
|
|
39
|
+
* durable, and a response-cache key beside them did not.
|
|
40
|
+
*/
|
|
41
|
+
const ACME_KEY_PREFIX = "kong_acme:";
|
|
42
|
+
const OBJECT_STORE_ACCESS_KEY = "supatype";
|
|
43
|
+
const OBJECT_STORE_SECRET_KEY = "supatype-secret";
|
|
44
|
+
/** Where the rendered SeaweedFS identity file sits, resolved from the project root like kong.yml. */
|
|
45
|
+
const SEAWEED_CONFIG_MOUNT = ".supatype/self-host/s3.json";
|
|
26
46
|
/** Map a config version pin to a Docker Hub image reference. */
|
|
27
47
|
export function dockerImageRef(component, version, config) {
|
|
28
48
|
const trimmed = version.trim();
|
|
@@ -121,6 +141,28 @@ export async function schemaEngineImageForPush(config) {
|
|
|
121
141
|
const version = await fetchLatestVersion("engine");
|
|
122
142
|
return dockerImageRef("engine", version);
|
|
123
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* SeaweedFS reads its identities from a file, so the stack's credentials are a generated artifact
|
|
146
|
+
* beside the compose file rather than two env vars inside it.
|
|
147
|
+
*
|
|
148
|
+
* There is deliberately no `anonymous` identity. Declaring one with `Read` would make every bucket
|
|
149
|
+
* world-readable and the per-bucket policy decorative, which is the opposite of what
|
|
150
|
+
* `applyPublicPolicy` is for: a bucket is public because its policy says so.
|
|
151
|
+
*/
|
|
152
|
+
export function renderSeaweedIdentities() {
|
|
153
|
+
const identities = {
|
|
154
|
+
identities: [
|
|
155
|
+
{
|
|
156
|
+
name: "supatype",
|
|
157
|
+
credentials: [
|
|
158
|
+
{ accessKey: OBJECT_STORE_ACCESS_KEY, secretKey: OBJECT_STORE_SECRET_KEY },
|
|
159
|
+
],
|
|
160
|
+
actions: ["Admin", "Read", "List", "Tagging", "Write"],
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
return `${JSON.stringify(identities, null, 2)}\n`;
|
|
165
|
+
}
|
|
124
166
|
export function selfHostComposePaths(cwd) {
|
|
125
167
|
const dir = resolve(cwd, ".supatype", "self-host");
|
|
126
168
|
return {
|
|
@@ -128,6 +170,7 @@ export function selfHostComposePaths(cwd) {
|
|
|
128
170
|
composePath: join(dir, "docker-compose.yml"),
|
|
129
171
|
kongPath: join(dir, "kong.yml"),
|
|
130
172
|
nginxPath: join(dir, "nginx.conf"),
|
|
173
|
+
s3ConfigPath: join(dir, "s3.json"),
|
|
131
174
|
};
|
|
132
175
|
}
|
|
133
176
|
export function appUpstreamForCompose(config) {
|
|
@@ -239,6 +282,12 @@ export function renderSelfHostCompose(config, cwd = process.cwd(), options) {
|
|
|
239
282
|
const projectMount = projectMountPath(cwd);
|
|
240
283
|
const kongMount = kongMountPath(cwd);
|
|
241
284
|
const external = usesExternalDatabase(config);
|
|
285
|
+
// Both halves come from the caller because both need the schema loaded, which this renderer does
|
|
286
|
+
// not do. See `SelfHostComposeOptions`.
|
|
287
|
+
const restSchemas = apiSchemaList(config, {
|
|
288
|
+
...(options?.fieldMaskingTier !== undefined && { tier: options.fieldMaskingTier }),
|
|
289
|
+
drafts: options?.drafts === true,
|
|
290
|
+
});
|
|
242
291
|
const ownerUrl = ownerDatabaseUrl(config);
|
|
243
292
|
// the auth driver wants the `postgres://` spelling; an external URL is used as given.
|
|
244
293
|
const authUrl = external ? ownerUrl : ownerDatabaseUrl(config, "postgres");
|
|
@@ -288,12 +337,23 @@ ${studioService}
|
|
|
288
337
|
: ` ports:
|
|
289
338
|
- "9999:9999"
|
|
290
339
|
`;
|
|
291
|
-
const
|
|
340
|
+
const seaweedPorts = devLocal
|
|
292
341
|
? ""
|
|
293
342
|
: ` ports:
|
|
294
|
-
- "
|
|
295
|
-
- "9001:9001"
|
|
343
|
+
- "8333:8333"
|
|
296
344
|
`;
|
|
345
|
+
// One source for the credentials: the server is configured with them and the storage service is
|
|
346
|
+
// handed them, and a mismatch does not fail at start, it fails at the first upload.
|
|
347
|
+
const objectStoreBlock = ` seaweedfs:
|
|
348
|
+
# Identities come from a config file rather than env vars, and the anonymous identity is
|
|
349
|
+
# deliberately absent: a bucket is public because of its policy, never because the server is
|
|
350
|
+
# open. Written beside this file by the same generator, so the two cannot drift.
|
|
351
|
+
image: \${SUPATYPE_SEAWEEDFS_IMAGE:-${SEAWEEDFS_IMAGE}}
|
|
352
|
+
command: server -dir=/data -s3 -s3.port=8333 -s3.config=/etc/seaweedfs/s3.json
|
|
353
|
+
volumes:
|
|
354
|
+
- storage-data:/data
|
|
355
|
+
- ${SEAWEED_CONFIG_MOUNT}:/etc/seaweedfs/s3.json:ro
|
|
356
|
+
${seaweedPorts}`;
|
|
297
357
|
const kongTlsEnv = tlsEnabled
|
|
298
358
|
? ` KONG_PROXY_LISTEN: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
|
|
299
359
|
KONG_LUA_SSL_TRUSTED_CERTIFICATE: system
|
|
@@ -304,7 +364,16 @@ ${studioService}
|
|
|
304
364
|
? ` - "80:8000"
|
|
305
365
|
- "443:8443"`
|
|
306
366
|
: ` - "\${SUPATYPE_KONG_PORT:-18473}:8000"`;
|
|
307
|
-
|
|
367
|
+
// The RESP server the response cache and Kong's ACME certificates use.
|
|
368
|
+
// Either a Valkey sidecar, or pg_keyspace inside the Postgres container --
|
|
369
|
+
// one stateful service instead of two.
|
|
370
|
+
const keyspaceInPg = keyspaceInPostgres(config);
|
|
371
|
+
const respHost = keyspaceInPg ? "db" : "valkey";
|
|
372
|
+
const valkeyBlock = keyspaceInPg
|
|
373
|
+
? ` # No \`valkey\` service: cache.provider is "pg_keyspace", so the RESP keyspace is
|
|
374
|
+
# served by the \`db\` container on :6379. See extensions/pg_keyspace in supatype/postgres.
|
|
375
|
+
`
|
|
376
|
+
: `
|
|
308
377
|
valkey:
|
|
309
378
|
image: \${SUPATYPE_VALKEY_IMAGE:-valkey/valkey:8-alpine}
|
|
310
379
|
command: ["valkey-server", "--appendonly", "yes"]
|
|
@@ -313,7 +382,9 @@ ${studioService}
|
|
|
313
382
|
volumes:
|
|
314
383
|
- valkey-data:/data
|
|
315
384
|
`;
|
|
316
|
-
|
|
385
|
+
// With the keyspace inside Postgres, waiting on `db` is already what every
|
|
386
|
+
// other service does, so Kong needs no extra dependency of its own.
|
|
387
|
+
const kongValkeyDepends = keyspaceInPg ? "" : "\n - valkey";
|
|
317
388
|
const tlsHintComment = tlsEnabled
|
|
318
389
|
? ""
|
|
319
390
|
: ` # HTTPS is off. To enable automatic TLS (Let's Encrypt) for production, set in supatype.config.ts:
|
|
@@ -322,9 +393,8 @@ ${studioService}
|
|
|
322
393
|
`;
|
|
323
394
|
// An external database is not ours to declare a volume for.
|
|
324
395
|
const volumesBlock = `volumes:
|
|
325
|
-
${external ? "" : " db-data:\n"}
|
|
326
|
-
valkey-data
|
|
327
|
-
`;
|
|
396
|
+
${external ? "" : " db-data:\n"} storage-data:
|
|
397
|
+
${keyspaceInPg ? "" : " valkey-data:\n"}`;
|
|
328
398
|
// `depends_on` for the services that talk to Postgres. With an external database there is no
|
|
329
399
|
// container to wait on, so the clause disappears entirely and each service retries on connect
|
|
330
400
|
// instead: which is also what covers a database that restarts *after* boot, something no
|
|
@@ -366,6 +436,63 @@ ${dbDependency}`
|
|
|
366
436
|
`
|
|
367
437
|
: "";
|
|
368
438
|
const realtimeServerEnv = realtime ? " SUPATYPE_REALTIME_URL: http://realtime:4000" : "";
|
|
439
|
+
// pg_keyspace registers background workers and requests shared memory at
|
|
440
|
+
// postmaster start, so it has to be in `shared_preload_libraries` -- there is
|
|
441
|
+
// no runtime toggle. The image turns it on from the environment
|
|
442
|
+
// (SUPATYPE_KEYSPACE_ENABLED) and writes the configuration itself, which is
|
|
443
|
+
// why this does not restate the preload list: the entrypoint appends
|
|
444
|
+
// pg_keyspace to the image's own list, in the right place (before
|
|
445
|
+
// supatype_mask, so the mask stays outermost and the image's
|
|
446
|
+
// pg_keyspace.require_mask = on is satisfied rather than refusing to serve).
|
|
447
|
+
// Restating it here would be a copy that goes stale the first time the image
|
|
448
|
+
// adds a library.
|
|
449
|
+
//
|
|
450
|
+
// Durability is `ephemeral` for everything, with ACME the one exception.
|
|
451
|
+
// A response cache that went through the WAL would put this stack's busiest
|
|
452
|
+
// write on disk to keep a copy of something that expires in seconds; a
|
|
453
|
+
// certificate that did not survive `docker compose restart db` would be
|
|
454
|
+
// re-issued against Let's Encrypt's rate limits, or fail. So the default is
|
|
455
|
+
// the cheap one and the certificates are named.
|
|
456
|
+
//
|
|
457
|
+
// `kong_acme:` is not a guess. Kong's ACME plugin prefixes every key it
|
|
458
|
+
// stores with it and enforces that prefix in its own reserved_words.lua;
|
|
459
|
+
// proven on a live instance, where both ACME keys survived `kill -9` under
|
|
460
|
+
// this exact configuration and the response-cache key did not.
|
|
461
|
+
//
|
|
462
|
+
// It is set whether or not TLS is on today. The override costs nothing when
|
|
463
|
+
// no key matches it, and a stack that turns TLS on later should not need a
|
|
464
|
+
// database restart before its certificates are safe to store.
|
|
465
|
+
const durablePrefixes = config.cache?.durablePrefixes ?? [];
|
|
466
|
+
const durabilityOverrides = [ACME_KEY_PREFIX, ...durablePrefixes]
|
|
467
|
+
.map((prefix) => `${prefix}=durable`)
|
|
468
|
+
.join(", ");
|
|
469
|
+
// Sizing is shared memory, reserved at postmaster start whether or not the
|
|
470
|
+
// cache is used, so the defaults are a self-hosted stack's floor rather than
|
|
471
|
+
// the extension's own (1M keys x 512 B reserves ~689 MiB per worker before
|
|
472
|
+
// rings and row cache). These are measured on a live PG16 build, not derived:
|
|
473
|
+
// this profile reserves ~235 MiB, of which ~16 MiB is a fixed row-cache
|
|
474
|
+
// directory that rowcache_mb does not describe and cannot be declined.
|
|
475
|
+
const keyspaceDbEnv = keyspaceInPg
|
|
476
|
+
? ` # The RESP keyspace, in place of a Valkey sidecar. The image writes
|
|
477
|
+
# /etc/postgresql-custom/pg_keyspace.conf from these before any server starts.
|
|
478
|
+
SUPATYPE_KEYSPACE_ENABLED: "1"
|
|
479
|
+
# Durable keys are rows in this database; without it they land in \`postgres\`.
|
|
480
|
+
SUPATYPE_KEYSPACE_DATABASE: \${POSTGRES_DB:-supatype}
|
|
481
|
+
SUPATYPE_KEYSPACE_DURABILITY: ephemeral
|
|
482
|
+
SUPATYPE_KEYSPACE_DURABILITY_OVERRIDES: "${durabilityOverrides}"
|
|
483
|
+
SUPATYPE_KEYSPACE_KEYS: "200000"
|
|
484
|
+
SUPATYPE_KEYSPACE_RING_MB: "16"
|
|
485
|
+
SUPATYPE_KEYSPACE_ROWCACHE_MB: "64"
|
|
486
|
+
`
|
|
487
|
+
: "";
|
|
488
|
+
// Not published to the host: the keyspace is reachable to the compose network
|
|
489
|
+
// (server, Kong) and nothing else. A RESP port on a public interface is an
|
|
490
|
+
// unauthenticated read of every cached response.
|
|
491
|
+
const keyspaceExpose = keyspaceInPg
|
|
492
|
+
? ` expose:
|
|
493
|
+
- "6379"
|
|
494
|
+
`
|
|
495
|
+
: "";
|
|
369
496
|
const dbServiceBlock = external
|
|
370
497
|
? ` # No \`db\` service: database.external points this stack at a Postgres it does not manage.
|
|
371
498
|
# Every service reads \${DATABASE_URL} from .env, and \`supatype db check\` reports what that
|
|
@@ -379,7 +506,7 @@ ${dbDependency}`
|
|
|
379
506
|
POSTGRES_DB: \${POSTGRES_DB:-supatype}
|
|
380
507
|
# Read by the image's init to password the \`authenticator\` role PostgREST connects as.
|
|
381
508
|
AUTHENTICATOR_PASSWORD: \${AUTHENTICATOR_PASSWORD:?AUTHENTICATOR_PASSWORD is missing from .env}
|
|
382
|
-
${dbPorts} volumes:
|
|
509
|
+
${keyspaceDbEnv}${dbPorts}${keyspaceExpose} volumes:
|
|
383
510
|
- db-data:/var/lib/postgresql/data
|
|
384
511
|
healthcheck:
|
|
385
512
|
# -h 127.0.0.1 forces TCP. Without it \`pg_isready\` uses the Unix socket, which the
|
|
@@ -416,7 +543,7 @@ ${dbServiceBlock} postgrest:
|
|
|
416
543
|
# Derived from schema.pg_schema (or schema.api_schemas). Hardcoding this is why choosing a
|
|
417
544
|
# non-public pg_schema used to give a correct push and an API that answered PGRST106 for
|
|
418
545
|
# everything: the engine moved and PostgREST was never told.
|
|
419
|
-
PGRST_DB_SCHEMA: "${
|
|
546
|
+
PGRST_DB_SCHEMA: "${restSchemas}"
|
|
420
547
|
PGRST_DB_ANON_ROLE: anon
|
|
421
548
|
PGRST_JWT_SECRET: \${JWT_SECRET:?JWT_SECRET is missing from .env}
|
|
422
549
|
PGRST_DB_EXTRA_SEARCH_PATH: public,extensions
|
|
@@ -430,10 +557,10 @@ ${dbDependency}
|
|
|
430
557
|
PORT: 5000
|
|
431
558
|
DATABASE_URL: "${ownerUrl}"
|
|
432
559
|
JWT_SECRET: \${JWT_SECRET:?JWT_SECRET is missing from .env}
|
|
433
|
-
S3_ENDPOINT: http://
|
|
560
|
+
S3_ENDPOINT: http://seaweedfs:8333
|
|
434
561
|
S3_REGION: us-east-1
|
|
435
|
-
S3_ACCESS_KEY:
|
|
436
|
-
S3_SECRET_KEY:
|
|
562
|
+
S3_ACCESS_KEY: ${OBJECT_STORE_ACCESS_KEY}
|
|
563
|
+
S3_SECRET_KEY: ${OBJECT_STORE_SECRET_KEY}
|
|
437
564
|
S3_FORCE_PATH_STYLE: "true"
|
|
438
565
|
${dbDependency}
|
|
439
566
|
functions-worker:
|
|
@@ -449,6 +576,10 @@ ${dbDependency}
|
|
|
449
576
|
# outside. One worker rather than two: a second container would cost a pod per project on
|
|
450
577
|
# cloud, for isolation the route boundary already provides.
|
|
451
578
|
SUPATYPE_HOOKS_ROOT: /project/hooks
|
|
579
|
+
# Every log line the worker writes carries this, and on cloud it is the label Loki indexes
|
|
580
|
+
# each project's logs under. Without it a line is collected and filed under no project, which
|
|
581
|
+
# is the same as losing it.
|
|
582
|
+
SUPATYPE_PROJECT_REF: ${JSON.stringify(config.project.name)}
|
|
452
583
|
PORT: "8001"
|
|
453
584
|
# In-compose loopback to Kong (not API_EXTERNAL_URL / localhost, unreachable from this container).
|
|
454
585
|
SUPATYPE_URL: http://kong:8000
|
|
@@ -512,7 +643,7 @@ ${serverPorts} volumes:
|
|
|
512
643
|
SUPATYPE_FUNCTIONS_WORKER_URL: http://functions-worker:8001
|
|
513
644
|
${realtimeServerEnv}
|
|
514
645
|
SUPATYPE_CONTROL_PLANE_URL: http://control-plane:8080
|
|
515
|
-
SUPATYPE_VALKEY_ADDR:
|
|
646
|
+
SUPATYPE_VALKEY_ADDR: ${respHost}:6379
|
|
516
647
|
${appEnv}
|
|
517
648
|
SUPATYPE_API_HOST: 0.0.0.0
|
|
518
649
|
SUPATYPE_API_PORT: 9999
|
|
@@ -545,9 +676,7 @@ ${appEnv}
|
|
|
545
676
|
SUPATYPE_DISABLE_SIGNUP: \${DISABLE_SIGNUP:-false}
|
|
546
677
|
${devLocal ? " STUDIO_OPEN_DEV: \"1\"\n" : ""}
|
|
547
678
|
depends_on:
|
|
548
|
-
${dbDependencyClause} valkey:
|
|
549
|
-
condition: service_started
|
|
550
|
-
postgrest:
|
|
679
|
+
${dbDependencyClause}${keyspaceInPg ? "" : " valkey:\n condition: service_started\n"} postgrest:
|
|
551
680
|
condition: service_started
|
|
552
681
|
storage:
|
|
553
682
|
condition: service_started
|
|
@@ -556,15 +685,7 @@ ${dbDependencyClause} valkey:
|
|
|
556
685
|
${realtimeDependency} control-plane:
|
|
557
686
|
condition: service_started
|
|
558
687
|
|
|
559
|
-
|
|
560
|
-
image: minio/minio:RELEASE.2024-11-07T00-52-20Z
|
|
561
|
-
command: server /data --console-address ":9001"
|
|
562
|
-
environment:
|
|
563
|
-
MINIO_ROOT_USER: supatype
|
|
564
|
-
MINIO_ROOT_PASSWORD: supatype-secret
|
|
565
|
-
${minioPorts} volumes:
|
|
566
|
-
- minio-data:/data
|
|
567
|
-
|
|
688
|
+
${objectStoreBlock}
|
|
568
689
|
schema-engine:
|
|
569
690
|
image: \${SUPATYPE_ENGINE_IMAGE:-supatype/schema-engine:latest}
|
|
570
691
|
profiles: ["tools"]
|
|
@@ -581,6 +702,16 @@ ${dbDependency}${studioBlock}${valkeyBlock}${tlsHintComment} kong:
|
|
|
581
702
|
KONG_ADMIN_ACCESS_LOG: /dev/stdout
|
|
582
703
|
KONG_PROXY_ERROR_LOG: /dev/stderr
|
|
583
704
|
KONG_ADMIN_ERROR_LOG: /dev/stderr
|
|
705
|
+
# Cookies are not scoped by port, so every project a developer runs on localhost shares one
|
|
706
|
+
# cookie jar and every request through this gateway carries the lot, which overruns nginx's
|
|
707
|
+
# default buffers and answers "Request header or cookie too large" about cookies belonging to
|
|
708
|
+
# something else entirely.
|
|
709
|
+
#
|
|
710
|
+
# Kept equal to large_client_header_buffers in packages/studio/nginx.conf, where the reason
|
|
711
|
+
# for the two numbers is written down. Both hops need it and they need the same value: this
|
|
712
|
+
# one carries API calls, that one the page, and a request that clears one and fails the other
|
|
713
|
+
# is worse to diagnose than one that fails outright.
|
|
714
|
+
KONG_NGINX_HTTP_LARGE_CLIENT_HEADER_BUFFERS: "4 32k"
|
|
584
715
|
${kongTlsEnv} volumes:
|
|
585
716
|
- ${kongMount}:/etc/kong/kong.yml:ro
|
|
586
717
|
ports:
|
|
@@ -740,12 +871,24 @@ function resolveFieldMaskingTier(cwd, config, options) {
|
|
|
740
871
|
return options.fieldMaskingTier;
|
|
741
872
|
return fieldMaskingTierFromProject(cwd, config);
|
|
742
873
|
}
|
|
874
|
+
/**
|
|
875
|
+
* Whether this project has a versioned model, unless the caller already knows.
|
|
876
|
+
*
|
|
877
|
+
* Same seam as the tier above, and the same reason: the renderer does not load the schema, so a
|
|
878
|
+
* caller that has can say, and `writeSelfHostCompose` answers for the callers that have not.
|
|
879
|
+
*/
|
|
880
|
+
function resolveDrafts(cwd, config, options) {
|
|
881
|
+
if (options?.drafts !== undefined)
|
|
882
|
+
return options.drafts;
|
|
883
|
+
return projectHasVersionedModels(cwd, config);
|
|
884
|
+
}
|
|
743
885
|
export function writeSelfHostCompose(cwd, config, options) {
|
|
744
886
|
assertExternalUrlMatchesEnv(cwd, config);
|
|
745
887
|
const tier = resolveFieldMaskingTier(cwd, config, options);
|
|
746
888
|
const resolved = {
|
|
747
889
|
...options,
|
|
748
890
|
...(tier !== undefined && { fieldMaskingTier: tier }),
|
|
891
|
+
drafts: resolveDrafts(cwd, config, options),
|
|
749
892
|
};
|
|
750
893
|
assertExternalUrlReachableFromContainers(config);
|
|
751
894
|
const paths = selfHostComposePaths(cwd);
|
|
@@ -753,6 +896,7 @@ export function writeSelfHostCompose(cwd, config, options) {
|
|
|
753
896
|
ensureProjectFunctionsDir(cwd, config);
|
|
754
897
|
ensureComposeManifest(cwd, config);
|
|
755
898
|
writeFileSync(paths.composePath, renderSelfHostCompose(config, cwd, resolved), "utf8");
|
|
899
|
+
writeFileSync(paths.s3ConfigPath, renderSeaweedIdentities(), "utf8");
|
|
756
900
|
const studioHostDev = options?.devLocal === true && hasStudioOverride(config);
|
|
757
901
|
const tlsEnabled = selfHostTlsEnabled(config, options?.devLocal === true);
|
|
758
902
|
const domain = config.server.domain?.trim();
|
|
@@ -763,8 +907,18 @@ export function writeSelfHostCompose(cwd, config, options) {
|
|
|
763
907
|
studioServiceUrl: COMPOSE_STUDIO_HOST_URL,
|
|
764
908
|
studioStripPath: false,
|
|
765
909
|
}),
|
|
910
|
+
// Kong stores its certificates wherever the RESP server is. With
|
|
911
|
+
// pg_keyspace that is the database container, and they are durable
|
|
912
|
+
// there because the keyspace defaults to durable and nothing names
|
|
913
|
+
// Kong's keys as an exception.
|
|
766
914
|
...(tlsEnabled && domain && acmeEmail
|
|
767
|
-
? {
|
|
915
|
+
? {
|
|
916
|
+
acme: {
|
|
917
|
+
email: acmeEmail,
|
|
918
|
+
domain,
|
|
919
|
+
redisHost: keyspaceInPostgres(config) ? "db" : "valkey",
|
|
920
|
+
},
|
|
921
|
+
}
|
|
768
922
|
: {}),
|
|
769
923
|
}), "utf8");
|
|
770
924
|
return paths;
|