@columnus/shared 0.1.54 → 0.1.56
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/apiProfile.d.ts +39 -0
- package/dist/apiProfile.js +19 -2
- package/dist/apiProfile.js.map +1 -1
- package/dist/assetFamily.d.ts +36 -0
- package/dist/assetFamily.js +73 -0
- package/dist/assetFamily.js.map +1 -0
- package/dist/assetFieldValues.d.ts +21 -0
- package/dist/{storageFieldValues.js → assetFieldValues.js} +159 -60
- package/dist/assetFieldValues.js.map +1 -0
- package/dist/assetGraph.d.ts +199 -0
- package/dist/assetGraph.js +214 -0
- package/dist/assetGraph.js.map +1 -0
- package/dist/assetJobs.d.ts +95 -0
- package/dist/assetJobs.js +41 -0
- package/dist/assetJobs.js.map +1 -0
- package/dist/assetSettings.d.ts +129 -0
- package/dist/assetSettings.js +87 -0
- package/dist/assetSettings.js.map +1 -0
- package/dist/assetValidators.d.ts +475 -0
- package/dist/assetValidators.js +83 -0
- package/dist/assetValidators.js.map +1 -0
- package/dist/bffProtocol.d.ts +29 -24
- package/dist/bffProtocol.js +5 -1
- package/dist/bffProtocol.js.map +1 -1
- package/dist/ciPreviewEnv.js +20 -3
- package/dist/ciPreviewEnv.js.map +1 -1
- package/dist/clipboardTransfer.js +112 -12
- package/dist/clipboardTransfer.js.map +1 -1
- package/dist/csv.js +118 -18
- package/dist/csv.js.map +1 -1
- package/dist/displayLabel.js +1 -1
- package/dist/displayLabel.js.map +1 -1
- package/dist/dotenv.js +5 -1
- package/dist/dotenv.js.map +1 -1
- package/dist/importMatch.js +118 -18
- package/dist/importMatch.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +741 -82
- package/dist/index.js.map +1 -1
- package/dist/postLoginPath.d.ts +21 -0
- package/dist/postLoginPath.js +24 -0
- package/dist/postLoginPath.js.map +1 -0
- package/dist/previewDeployName.d.ts +0 -7
- package/dist/previewDeployName.js +21 -4
- package/dist/previewDeployName.js.map +1 -1
- package/dist/recordTableColumns.js +112 -12
- package/dist/recordTableColumns.js.map +1 -1
- package/dist/recordTablePreload.js.map +1 -1
- package/dist/refDisplayRequests.js +112 -12
- package/dist/refDisplayRequests.js.map +1 -1
- package/dist/richDoc.d.ts +2 -2
- package/dist/richDoc.js +5 -5
- package/dist/richDoc.js.map +1 -1
- package/dist/schemaGenerator.d.ts +25 -1
- package/dist/schemaGenerator.js +4569 -18
- package/dist/schemaGenerator.js.map +1 -1
- package/dist/schemaShrink.d.ts +3 -1
- package/dist/schemaShrink.js +4451 -1
- package/dist/schemaShrink.js.map +1 -1
- package/dist/schemaShrinkValidators.d.ts +2 -2
- package/dist/schemaTypes.d.ts +123 -0
- package/dist/schemaTypes.js +107 -13
- package/dist/schemaTypes.js.map +1 -1
- package/dist/share.js +6 -1
- package/dist/share.js.map +1 -1
- package/dist/shareApiBridge.js +6 -1
- package/dist/shareApiBridge.js.map +1 -1
- package/dist/shareProposal.js +112 -12
- package/dist/shareProposal.js.map +1 -1
- package/dist/spaceBundle.js +112 -12
- package/dist/spaceBundle.js.map +1 -1
- package/dist/syncChannel.d.ts +15 -0
- package/dist/syncChannel.js +4642 -0
- package/dist/syncChannel.js.map +1 -0
- package/package.json +1 -1
- package/dist/storageFieldValues.d.ts +0 -10
- package/dist/storageFieldValues.js.map +0 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const ASSET_FAMILIES: readonly ["image", "document", "audio", "video", "vector", "other"];
|
|
2
|
+
export type AssetFamily = (typeof ASSET_FAMILIES)[number];
|
|
3
|
+
/**
|
|
4
|
+
* Narrow an untyped `family` read off a row. Convex hands asset rows back
|
|
5
|
+
* untyped — the table is generated per tenant — so a reader that needs the
|
|
6
|
+
* union has to check it rather than assert it.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isAssetFamily(value: unknown): value is AssetFamily;
|
|
9
|
+
/** Vector types a browser can render in an `<img>`; the rest fall back to an icon. */
|
|
10
|
+
export declare const DISPLAYABLE_VECTOR_CONTENT_TYPES: readonly ["image/svg+xml"];
|
|
11
|
+
/** True when this MIME may be decoded into the G21 rendition graph. */
|
|
12
|
+
export declare function isRasterRenditionSource(contentType: string | undefined): boolean;
|
|
13
|
+
/** `accept` value for a file input restricted to family `vector`. */
|
|
14
|
+
export declare const VECTOR_FILE_ACCEPT = ".svg,.eps,.ai,image/svg+xml,application/postscript,application/illustrator";
|
|
15
|
+
export declare function isVectorContentType(contentType: string | undefined, filename?: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* True when the asset can be shown directly in an `<img>` even though it is
|
|
18
|
+
* not family `image`: SVG only, so EPS keeps the file icon.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isDisplayableVectorContentType(contentType: string | undefined, filename?: string): boolean;
|
|
21
|
+
/** Derive the stable family used by profiles, graphs, and library filtering. */
|
|
22
|
+
export declare function assetFamilyForContentType(contentType: string | undefined, filename?: string): AssetFamily;
|
|
23
|
+
/**
|
|
24
|
+
* G20: ExifTool extract runs for `image` and `vector` only. Rendition graphs
|
|
25
|
+
* are a stricter gate (`assetBuildsRenditions`: raster `image`).
|
|
26
|
+
*/
|
|
27
|
+
export declare function isExtractableFamily(family: AssetFamily | undefined): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Library eligibility for an `image` field picker: family `image` plus vector
|
|
30
|
+
* assets a browser can display. EPS stays reachable from `file` fields only.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isImageFieldPickable(asset: {
|
|
33
|
+
family?: string;
|
|
34
|
+
contentType?: string;
|
|
35
|
+
filename?: string;
|
|
36
|
+
}): boolean;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// packages/@columnus/shared/src/assetFamily.ts
|
|
2
|
+
var ASSET_FAMILIES = ["image", "document", "audio", "video", "vector", "other"];
|
|
3
|
+
var ASSET_FAMILY_SET = new Set(ASSET_FAMILIES);
|
|
4
|
+
function isAssetFamily(value) {
|
|
5
|
+
return typeof value === "string" && ASSET_FAMILY_SET.has(value);
|
|
6
|
+
}
|
|
7
|
+
var VECTOR_CONTENT_TYPES = /* @__PURE__ */ new Set([
|
|
8
|
+
"image/svg+xml",
|
|
9
|
+
"application/postscript",
|
|
10
|
+
"application/eps",
|
|
11
|
+
"application/x-eps",
|
|
12
|
+
"image/eps",
|
|
13
|
+
"image/x-eps",
|
|
14
|
+
"application/illustrator",
|
|
15
|
+
"application/vnd.adobe.illustrator"
|
|
16
|
+
]);
|
|
17
|
+
var DISPLAYABLE_VECTOR_CONTENT_TYPES = ["image/svg+xml"];
|
|
18
|
+
var DISPLAYABLE_VECTOR_CONTENT_TYPE_SET = new Set(
|
|
19
|
+
DISPLAYABLE_VECTOR_CONTENT_TYPES
|
|
20
|
+
);
|
|
21
|
+
var RASTER_RENDITION_CONTENT_TYPES = /* @__PURE__ */ new Set([
|
|
22
|
+
"image/jpeg",
|
|
23
|
+
"image/pjpeg",
|
|
24
|
+
"image/png",
|
|
25
|
+
"image/webp",
|
|
26
|
+
"image/avif",
|
|
27
|
+
"image/tiff",
|
|
28
|
+
"image/heic",
|
|
29
|
+
"image/heif",
|
|
30
|
+
"image/gif"
|
|
31
|
+
]);
|
|
32
|
+
function isRasterRenditionSource(contentType) {
|
|
33
|
+
return RASTER_RENDITION_CONTENT_TYPES.has(normalizeContentType(contentType));
|
|
34
|
+
}
|
|
35
|
+
var VECTOR_FILE_ACCEPT = ".svg,.eps,.ai,image/svg+xml,application/postscript,application/illustrator";
|
|
36
|
+
function normalizeContentType(contentType) {
|
|
37
|
+
return contentType?.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
38
|
+
}
|
|
39
|
+
function hasVectorExtension(filename) {
|
|
40
|
+
return filename?.trim().toLowerCase().endsWith(".svg") ?? false;
|
|
41
|
+
}
|
|
42
|
+
function isVectorContentType(contentType, filename) {
|
|
43
|
+
const value = normalizeContentType(contentType);
|
|
44
|
+
if (!value) return hasVectorExtension(filename);
|
|
45
|
+
return VECTOR_CONTENT_TYPES.has(value);
|
|
46
|
+
}
|
|
47
|
+
function isDisplayableVectorContentType(contentType, filename) {
|
|
48
|
+
const value = normalizeContentType(contentType);
|
|
49
|
+
if (!value) return hasVectorExtension(filename);
|
|
50
|
+
return DISPLAYABLE_VECTOR_CONTENT_TYPE_SET.has(value);
|
|
51
|
+
}
|
|
52
|
+
function assetFamilyForContentType(contentType, filename) {
|
|
53
|
+
const value = normalizeContentType(contentType);
|
|
54
|
+
if (isVectorContentType(contentType, filename)) return "vector";
|
|
55
|
+
if (value.startsWith("image/")) return "image";
|
|
56
|
+
if (value.startsWith("audio/")) return "audio";
|
|
57
|
+
if (value.startsWith("video/")) return "video";
|
|
58
|
+
if (value === "application/pdf" || value.startsWith("text/") || value.startsWith("application/msword") || value.startsWith("application/vnd.openxmlformats-officedocument") || value.startsWith("application/vnd.oasis.opendocument")) {
|
|
59
|
+
return "document";
|
|
60
|
+
}
|
|
61
|
+
return "other";
|
|
62
|
+
}
|
|
63
|
+
function isExtractableFamily(family) {
|
|
64
|
+
return family === "image" || family === "vector";
|
|
65
|
+
}
|
|
66
|
+
function isImageFieldPickable(asset) {
|
|
67
|
+
if (asset.family === "image") return true;
|
|
68
|
+
return isDisplayableVectorContentType(asset.contentType, asset.filename);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { ASSET_FAMILIES, DISPLAYABLE_VECTOR_CONTENT_TYPES, VECTOR_FILE_ACCEPT, assetFamilyForContentType, isAssetFamily, isDisplayableVectorContentType, isExtractableFamily, isImageFieldPickable, isRasterRenditionSource, isVectorContentType };
|
|
72
|
+
//# sourceMappingURL=assetFamily.js.map
|
|
73
|
+
//# sourceMappingURL=assetFamily.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/assetFamily.ts"],"names":[],"mappings":"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","file":"assetFamily.js","sourcesContent":["// Media family classification shared by the host, the component, Studio, and\n// the generated clients. `vector` was added by 059 S0 (061 grill 2026-08-23):\n// SVG/EPS/Illustrator are their own family so the raster rendition DAG (G38)\n// and the spinner-for-derived rule (G36) never apply to them.\n\nexport const ASSET_FAMILIES = [\"image\", \"document\", \"audio\", \"video\", \"vector\", \"other\"] as const;\nexport type AssetFamily = (typeof ASSET_FAMILIES)[number];\n\nconst ASSET_FAMILY_SET: ReadonlySet<string> = new Set(ASSET_FAMILIES);\n\n/**\n * Narrow an untyped `family` read off a row. Convex hands asset rows back\n * untyped — the table is generated per tenant — so a reader that needs the\n * union has to check it rather than assert it.\n */\nexport function isAssetFamily(value: unknown): value is AssetFamily {\n return typeof value === \"string\" && ASSET_FAMILY_SET.has(value);\n}\n\n/**\n * Vector MIME table (G20/G38). `application/pdf` deliberately stays\n * `document`, which also covers PDF-based `.ai` files.\n */\nconst VECTOR_CONTENT_TYPES = new Set([\n \"image/svg+xml\",\n \"application/postscript\",\n \"application/eps\",\n \"application/x-eps\",\n \"image/eps\",\n \"image/x-eps\",\n \"application/illustrator\",\n \"application/vnd.adobe.illustrator\",\n]);\n\n/** Vector types a browser can render in an `<img>`; the rest fall back to an icon. */\nexport const DISPLAYABLE_VECTOR_CONTENT_TYPES = [\"image/svg+xml\"] as const;\nconst DISPLAYABLE_VECTOR_CONTENT_TYPE_SET: ReadonlySet<string> = new Set(\n DISPLAYABLE_VECTOR_CONTENT_TYPES,\n);\n\n/**\n * G38 raster allowlist: only these get a rendition DAG (and therefore the G36\n * spinner). Animated GIF/WebP are included and rendered **first frame**.\n * Everything else that is family `image` — BMP, ICO, camera RAW — keeps its\n * original and never enters the render pipeline.\n */\nconst RASTER_RENDITION_CONTENT_TYPES: ReadonlySet<string> = new Set([\n \"image/jpeg\",\n \"image/pjpeg\",\n \"image/png\",\n \"image/webp\",\n \"image/avif\",\n \"image/tiff\",\n \"image/heic\",\n \"image/heif\",\n \"image/gif\",\n]);\n\n/** True when this MIME may be decoded into the G21 rendition graph. */\nexport function isRasterRenditionSource(contentType: string | undefined): boolean {\n return RASTER_RENDITION_CONTENT_TYPES.has(normalizeContentType(contentType));\n}\n\n/** `accept` value for a file input restricted to family `vector`. */\nexport const VECTOR_FILE_ACCEPT =\n \".svg,.eps,.ai,image/svg+xml,application/postscript,application/illustrator\";\n\nfunction normalizeContentType(contentType: string | undefined): string {\n return contentType?.split(\";\")[0]?.trim().toLowerCase() ?? \"\";\n}\n\n/** Only `.svg` is inferred from the filename, and only when the MIME is missing. */\nfunction hasVectorExtension(filename: string | undefined): boolean {\n return filename?.trim().toLowerCase().endsWith(\".svg\") ?? false;\n}\n\nexport function isVectorContentType(contentType: string | undefined, filename?: string): boolean {\n const value = normalizeContentType(contentType);\n if (!value) return hasVectorExtension(filename);\n return VECTOR_CONTENT_TYPES.has(value);\n}\n\n/**\n * True when the asset can be shown directly in an `<img>` even though it is\n * not family `image`: SVG only, so EPS keeps the file icon.\n */\nexport function isDisplayableVectorContentType(\n contentType: string | undefined,\n filename?: string,\n): boolean {\n const value = normalizeContentType(contentType);\n if (!value) return hasVectorExtension(filename);\n return DISPLAYABLE_VECTOR_CONTENT_TYPE_SET.has(value);\n}\n\n/** Derive the stable family used by profiles, graphs, and library filtering. */\nexport function assetFamilyForContentType(\n contentType: string | undefined,\n filename?: string,\n): AssetFamily {\n const value = normalizeContentType(contentType);\n if (isVectorContentType(contentType, filename)) return \"vector\";\n if (value.startsWith(\"image/\")) return \"image\";\n if (value.startsWith(\"audio/\")) return \"audio\";\n if (value.startsWith(\"video/\")) return \"video\";\n if (\n value === \"application/pdf\" ||\n value.startsWith(\"text/\") ||\n value.startsWith(\"application/msword\") ||\n value.startsWith(\"application/vnd.openxmlformats-officedocument\") ||\n value.startsWith(\"application/vnd.oasis.opendocument\")\n ) {\n return \"document\";\n }\n return \"other\";\n}\n\n/**\n * G20: ExifTool extract runs for `image` and `vector` only. Rendition graphs\n * are a stricter gate (`assetBuildsRenditions`: raster `image`).\n */\nexport function isExtractableFamily(family: AssetFamily | undefined): boolean {\n return family === \"image\" || family === \"vector\";\n}\n\n/**\n * Library eligibility for an `image` field picker: family `image` plus vector\n * assets a browser can display. EPS stays reachable from `file` fields only.\n */\nexport function isImageFieldPickable(asset: {\n family?: string;\n contentType?: string;\n filename?: string;\n}): boolean {\n if (asset.family === \"image\") return true;\n return isDisplayableVectorContentType(asset.contentType, asset.filename);\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Field, FieldType } from "./schemaTypes.ts";
|
|
2
|
+
export declare function isValidAssetId(value: string): boolean;
|
|
3
|
+
/** Collect persisted asset ids from image/file fields, including nested objects. */
|
|
4
|
+
export declare function collectAssetIds(value: unknown, type: FieldType, out?: Set<string>): Set<string>;
|
|
5
|
+
export declare function collectAssetIdsFromRow(row: Record<string, unknown> | undefined, fields: readonly Field[], out?: Set<string>): Set<string>;
|
|
6
|
+
/**
|
|
7
|
+
* One reverse-reference placement for a stored Media value. `fieldName` is a
|
|
8
|
+
* stable manifest path; a top-level file array uses `arrayIndex`, while deeper
|
|
9
|
+
* arrays include their index in the path to keep the component key unique.
|
|
10
|
+
*/
|
|
11
|
+
export type AssetFieldRef = {
|
|
12
|
+
assetId: string;
|
|
13
|
+
fieldName: string;
|
|
14
|
+
arrayIndex: number | null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Collect placement-precise asset references from a row. This is deliberately
|
|
18
|
+
* separate from `collectAssetIdsFromRow`: display batching only needs ids,
|
|
19
|
+
* whereas the DAM ref index must distinguish two placements of the same id.
|
|
20
|
+
*/
|
|
21
|
+
export declare function collectAssetRefsFromRow(row: Record<string, unknown> | undefined, fields: readonly Field[]): AssetFieldRef[];
|
|
@@ -4180,7 +4180,13 @@ var RESERVED_TABLE_NAMES = /* @__PURE__ */ new Set([
|
|
|
4180
4180
|
"columnus_api_output_secrets",
|
|
4181
4181
|
"columnus_api_sync_routes",
|
|
4182
4182
|
"columnus_api_outbox",
|
|
4183
|
-
"columnus_api_delivery"
|
|
4183
|
+
"columnus_api_delivery",
|
|
4184
|
+
"columnus_assets",
|
|
4185
|
+
"columnus_asset_versions",
|
|
4186
|
+
"columnus_asset_refs",
|
|
4187
|
+
"columnus_asset_profiles",
|
|
4188
|
+
"columnus_asset_settings",
|
|
4189
|
+
"columnus_asset_jobs"
|
|
4184
4190
|
]);
|
|
4185
4191
|
var displayTemplatesSchema = external_exports.object({
|
|
4186
4192
|
id: external_exports.string().optional(),
|
|
@@ -4213,6 +4219,12 @@ var TABLE_COLORS = [
|
|
|
4213
4219
|
"lavender"
|
|
4214
4220
|
];
|
|
4215
4221
|
var tableColorSchema = external_exports.enum(TABLE_COLORS);
|
|
4222
|
+
var TABLE_KINDS = ["record", "asset"];
|
|
4223
|
+
var tableKindSchema = external_exports.enum(TABLE_KINDS);
|
|
4224
|
+
var assetBindingSchema = external_exports.object({
|
|
4225
|
+
profile: external_exports.string().min(1),
|
|
4226
|
+
enforced: external_exports.boolean().optional()
|
|
4227
|
+
});
|
|
4216
4228
|
var fieldTypeSchema = external_exports.lazy(
|
|
4217
4229
|
() => external_exports.discriminatedUnion("kind", [
|
|
4218
4230
|
external_exports.object({ kind: external_exports.literal("string") }),
|
|
@@ -4240,7 +4252,9 @@ var fieldTypeSchema = external_exports.lazy(
|
|
|
4240
4252
|
name: external_exports.string().regex(IDENT),
|
|
4241
4253
|
label: external_exports.string().optional(),
|
|
4242
4254
|
type: fieldTypeSchema,
|
|
4243
|
-
optional: external_exports.boolean()
|
|
4255
|
+
optional: external_exports.boolean(),
|
|
4256
|
+
/** Nested image/file placements bind a Media profile like top-level ones. */
|
|
4257
|
+
asset: assetBindingSchema.optional()
|
|
4244
4258
|
})
|
|
4245
4259
|
)
|
|
4246
4260
|
}),
|
|
@@ -4254,7 +4268,9 @@ var fieldSchema = external_exports.object({
|
|
|
4254
4268
|
name: external_exports.string().regex(IDENT, "must be a valid identifier"),
|
|
4255
4269
|
label: external_exports.string().optional(),
|
|
4256
4270
|
type: fieldTypeSchema,
|
|
4257
|
-
optional: external_exports.boolean()
|
|
4271
|
+
optional: external_exports.boolean(),
|
|
4272
|
+
/** Image/file fields may pin a Media profile; existence is enforced at upload/pick. */
|
|
4273
|
+
asset: assetBindingSchema.optional()
|
|
4258
4274
|
});
|
|
4259
4275
|
var indexSchema = external_exports.object({
|
|
4260
4276
|
name: external_exports.string().regex(IDENT),
|
|
@@ -4271,6 +4287,8 @@ var tableSchema = external_exports.object({
|
|
|
4271
4287
|
}),
|
|
4272
4288
|
label: external_exports.string().optional(),
|
|
4273
4289
|
color: tableColorSchema.optional(),
|
|
4290
|
+
/** Asset metadata tables are typed root tables but never ordinary user records. */
|
|
4291
|
+
kind: tableKindSchema.optional().default("record"),
|
|
4274
4292
|
fields: external_exports.array(fieldSchema),
|
|
4275
4293
|
indexes: external_exports.array(indexSchema).default([]),
|
|
4276
4294
|
searchIndexes: external_exports.array(searchIndexSchema).default([]),
|
|
@@ -4280,6 +4298,7 @@ external_exports.object({
|
|
|
4280
4298
|
tables: external_exports.array(tableSchema)
|
|
4281
4299
|
}).superRefine((manifest, ctx) => {
|
|
4282
4300
|
const tableNames = /* @__PURE__ */ new Set();
|
|
4301
|
+
const tablesByName = /* @__PURE__ */ new Map();
|
|
4283
4302
|
for (const t of manifest.tables) {
|
|
4284
4303
|
if (tableNames.has(t.name)) {
|
|
4285
4304
|
ctx.addIssue({
|
|
@@ -4289,6 +4308,37 @@ external_exports.object({
|
|
|
4289
4308
|
});
|
|
4290
4309
|
}
|
|
4291
4310
|
tableNames.add(t.name);
|
|
4311
|
+
tablesByName.set(t.name, t);
|
|
4312
|
+
if (tableKind(t) === "asset") {
|
|
4313
|
+
if (t.indexes.length > 0) {
|
|
4314
|
+
ctx.addIssue({
|
|
4315
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4316
|
+
message: `${t.name} is an asset metadata table and cannot define indexes`,
|
|
4317
|
+
path: ["tables"]
|
|
4318
|
+
});
|
|
4319
|
+
}
|
|
4320
|
+
if (t.searchIndexes.length > 0) {
|
|
4321
|
+
ctx.addIssue({
|
|
4322
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4323
|
+
message: `${t.name} is an asset metadata table and cannot define search indexes`,
|
|
4324
|
+
path: ["tables"]
|
|
4325
|
+
});
|
|
4326
|
+
}
|
|
4327
|
+
if (t.displayTemplates !== void 0) {
|
|
4328
|
+
ctx.addIssue({
|
|
4329
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4330
|
+
message: `${t.name} is an asset metadata table and cannot define display templates`,
|
|
4331
|
+
path: ["tables"]
|
|
4332
|
+
});
|
|
4333
|
+
}
|
|
4334
|
+
if (t.color !== void 0) {
|
|
4335
|
+
ctx.addIssue({
|
|
4336
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4337
|
+
message: `${t.name} is an asset metadata table and cannot define a color`,
|
|
4338
|
+
path: ["tables"]
|
|
4339
|
+
});
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4292
4342
|
const fieldNames = /* @__PURE__ */ new Set();
|
|
4293
4343
|
for (const f of t.fields) {
|
|
4294
4344
|
if (fieldNames.has(f.name)) {
|
|
@@ -4299,36 +4349,43 @@ external_exports.object({
|
|
|
4299
4349
|
});
|
|
4300
4350
|
}
|
|
4301
4351
|
fieldNames.add(f.name);
|
|
4352
|
+
assertAssetBindingAllowed(ctx, t, f);
|
|
4302
4353
|
}
|
|
4303
4354
|
}
|
|
4304
4355
|
for (const t of manifest.tables) {
|
|
4305
4356
|
for (const f of t.fields) {
|
|
4306
|
-
const
|
|
4307
|
-
if (
|
|
4357
|
+
const invalidRef = findInvalidReference(f.type, tablesByName);
|
|
4358
|
+
if (invalidRef) {
|
|
4308
4359
|
ctx.addIssue({
|
|
4309
4360
|
code: external_exports.ZodIssueCode.custom,
|
|
4310
|
-
message: `${t.name}.${f.name}
|
|
4361
|
+
message: `${t.name}.${f.name} ${invalidRef}`,
|
|
4311
4362
|
path: ["tables"]
|
|
4312
4363
|
});
|
|
4313
4364
|
}
|
|
4314
4365
|
}
|
|
4315
4366
|
}
|
|
4316
4367
|
});
|
|
4317
|
-
function
|
|
4368
|
+
function findInvalidReference(t, tablesByName) {
|
|
4318
4369
|
switch (t.kind) {
|
|
4319
|
-
case "id":
|
|
4320
|
-
|
|
4370
|
+
case "id": {
|
|
4371
|
+
const target = tablesByName.get(t.table);
|
|
4372
|
+
if (!target) return `references unknown table: ${t.table}`;
|
|
4373
|
+
if (tableKind(target) === "asset") {
|
|
4374
|
+
return `cannot reference asset metadata table: ${t.table}`;
|
|
4375
|
+
}
|
|
4376
|
+
return null;
|
|
4377
|
+
}
|
|
4321
4378
|
case "array":
|
|
4322
|
-
return
|
|
4379
|
+
return findInvalidReference(t.element, tablesByName);
|
|
4323
4380
|
case "object":
|
|
4324
4381
|
for (const f of t.fields) {
|
|
4325
|
-
const r =
|
|
4382
|
+
const r = findInvalidReference(f.type, tablesByName);
|
|
4326
4383
|
if (r) return r;
|
|
4327
4384
|
}
|
|
4328
4385
|
return null;
|
|
4329
4386
|
case "union":
|
|
4330
4387
|
for (const o of t.options) {
|
|
4331
|
-
const r =
|
|
4388
|
+
const r = findInvalidReference(o, tablesByName);
|
|
4332
4389
|
if (r) return r;
|
|
4333
4390
|
}
|
|
4334
4391
|
return null;
|
|
@@ -4336,6 +4393,9 @@ function findDanglingRef(t, known) {
|
|
|
4336
4393
|
return null;
|
|
4337
4394
|
}
|
|
4338
4395
|
}
|
|
4396
|
+
function tableKind(table) {
|
|
4397
|
+
return table.kind ?? "record";
|
|
4398
|
+
}
|
|
4339
4399
|
function isFileFieldType(t) {
|
|
4340
4400
|
return t.kind === "file" || t.kind === "image";
|
|
4341
4401
|
}
|
|
@@ -4345,6 +4405,37 @@ function isFileArrayFieldType(t) {
|
|
|
4345
4405
|
function isStorageFieldType(t) {
|
|
4346
4406
|
return isFileFieldType(t) || isFileArrayFieldType(t);
|
|
4347
4407
|
}
|
|
4408
|
+
function assertAssetBindingAllowed(ctx, table, field) {
|
|
4409
|
+
if (field.asset && tableKind(table) === "asset") {
|
|
4410
|
+
ctx.addIssue({
|
|
4411
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4412
|
+
message: `${table.name}.${field.name} asset metadata fields cannot define a Media profile`,
|
|
4413
|
+
path: ["tables"]
|
|
4414
|
+
});
|
|
4415
|
+
} else if (field.asset && !isStorageFieldType(field.type)) {
|
|
4416
|
+
ctx.addIssue({
|
|
4417
|
+
code: external_exports.ZodIssueCode.custom,
|
|
4418
|
+
message: `${table.name}.${field.name} asset profile can only be set on image/file fields`,
|
|
4419
|
+
path: ["tables"]
|
|
4420
|
+
});
|
|
4421
|
+
}
|
|
4422
|
+
assertAssetBindingsInType(ctx, table, field.type);
|
|
4423
|
+
}
|
|
4424
|
+
function assertAssetBindingsInType(ctx, table, type) {
|
|
4425
|
+
switch (type.kind) {
|
|
4426
|
+
case "array":
|
|
4427
|
+
assertAssetBindingsInType(ctx, table, type.element);
|
|
4428
|
+
return;
|
|
4429
|
+
case "object":
|
|
4430
|
+
for (const field of type.fields) assertAssetBindingAllowed(ctx, table, field);
|
|
4431
|
+
return;
|
|
4432
|
+
case "union":
|
|
4433
|
+
for (const option of type.options) assertAssetBindingsInType(ctx, table, option);
|
|
4434
|
+
return;
|
|
4435
|
+
default:
|
|
4436
|
+
return;
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4348
4439
|
|
|
4349
4440
|
// packages/@columnus/shared/src/displayLabel.ts
|
|
4350
4441
|
function toDocumentId(value) {
|
|
@@ -4352,70 +4443,78 @@ function toDocumentId(value) {
|
|
|
4352
4443
|
return typeof value === "string" ? value : String(value);
|
|
4353
4444
|
}
|
|
4354
4445
|
|
|
4355
|
-
// packages/@columnus/shared/src/
|
|
4356
|
-
var
|
|
4357
|
-
function
|
|
4358
|
-
return
|
|
4446
|
+
// packages/@columnus/shared/src/assetFieldValues.ts
|
|
4447
|
+
var ASSET_ID = /^[a-z0-9]+$/i;
|
|
4448
|
+
function isValidAssetId(value) {
|
|
4449
|
+
return ASSET_ID.test(value) && value.length >= 10;
|
|
4359
4450
|
}
|
|
4360
|
-
function
|
|
4451
|
+
function collectAssetIds(value, type, out = /* @__PURE__ */ new Set()) {
|
|
4361
4452
|
if (isFileFieldType(type)) {
|
|
4362
4453
|
const id = toDocumentId(value);
|
|
4363
4454
|
if (id) out.add(id);
|
|
4364
4455
|
return out;
|
|
4365
4456
|
}
|
|
4366
|
-
if (
|
|
4367
|
-
for (const item of value)
|
|
4368
|
-
|
|
4369
|
-
|
|
4457
|
+
if (type.kind === "array" && Array.isArray(value)) {
|
|
4458
|
+
for (const item of value) collectAssetIds(item, type.element, out);
|
|
4459
|
+
return out;
|
|
4460
|
+
}
|
|
4461
|
+
if (type.kind === "object" && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4462
|
+
const record = value;
|
|
4463
|
+
for (const field of type.fields) {
|
|
4464
|
+
collectAssetIds(record[field.name], field.type, out);
|
|
4370
4465
|
}
|
|
4466
|
+
return out;
|
|
4467
|
+
}
|
|
4468
|
+
if (type.kind === "union") {
|
|
4469
|
+
for (const option of type.options) collectAssetIds(value, option, out);
|
|
4371
4470
|
}
|
|
4372
4471
|
return out;
|
|
4373
4472
|
}
|
|
4374
|
-
function
|
|
4473
|
+
function collectAssetIdsFromRow(row, fields, out = /* @__PURE__ */ new Set()) {
|
|
4375
4474
|
if (!row) return out;
|
|
4376
4475
|
for (const field of fields) {
|
|
4377
|
-
|
|
4378
|
-
collectStorageIds(row[field.name], field.type, out);
|
|
4476
|
+
collectAssetIds(row[field.name], field.type, out);
|
|
4379
4477
|
}
|
|
4380
4478
|
return out;
|
|
4381
4479
|
}
|
|
4382
|
-
function
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
const
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4480
|
+
function collectAssetRefsFromRow(row, fields) {
|
|
4481
|
+
if (!row) return [];
|
|
4482
|
+
const refs = /* @__PURE__ */ new Map();
|
|
4483
|
+
const add = (assetId, fieldName, arrayIndex) => {
|
|
4484
|
+
const ref = { assetId, fieldName, arrayIndex };
|
|
4485
|
+
refs.set(`${assetId}\0${fieldName}\0${arrayIndex ?? ""}`, ref);
|
|
4486
|
+
};
|
|
4487
|
+
const visit = (value, type, fieldName, arrayIndex) => {
|
|
4488
|
+
if (isFileFieldType(type)) {
|
|
4489
|
+
const assetId = toDocumentId(value);
|
|
4490
|
+
if (assetId) add(assetId, fieldName, arrayIndex);
|
|
4491
|
+
return;
|
|
4492
|
+
}
|
|
4493
|
+
if (type.kind === "array" && Array.isArray(value)) {
|
|
4494
|
+
for (const [index, item] of value.entries()) {
|
|
4495
|
+
if (isFileFieldType(type.element)) {
|
|
4496
|
+
visit(item, type.element, fieldName, index);
|
|
4497
|
+
} else {
|
|
4498
|
+
visit(item, type.element, `${fieldName}[${index}]`, null);
|
|
4499
|
+
}
|
|
4395
4500
|
}
|
|
4501
|
+
return;
|
|
4396
4502
|
}
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
const patch = pendingEdits.get(rowId);
|
|
4411
|
-
if (patch) collectStorageIdsFromRow(patch, fields, referenced);
|
|
4412
|
-
}
|
|
4413
|
-
return referenced;
|
|
4414
|
-
}
|
|
4415
|
-
function isDraftRowId(rowId) {
|
|
4416
|
-
return rowId.startsWith("__draft__");
|
|
4503
|
+
if (type.kind === "object" && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4504
|
+
const record = value;
|
|
4505
|
+
for (const field of type.fields) {
|
|
4506
|
+
visit(record[field.name], field.type, `${fieldName}.${field.name}`, arrayIndex);
|
|
4507
|
+
}
|
|
4508
|
+
return;
|
|
4509
|
+
}
|
|
4510
|
+
if (type.kind === "union") {
|
|
4511
|
+
for (const option of type.options) visit(value, option, fieldName, arrayIndex);
|
|
4512
|
+
}
|
|
4513
|
+
};
|
|
4514
|
+
for (const field of fields) visit(row[field.name], field.type, field.name, null);
|
|
4515
|
+
return [...refs.values()];
|
|
4417
4516
|
}
|
|
4418
4517
|
|
|
4419
|
-
export {
|
|
4420
|
-
//# sourceMappingURL=
|
|
4421
|
-
//# sourceMappingURL=
|
|
4518
|
+
export { collectAssetIds, collectAssetIdsFromRow, collectAssetRefsFromRow, isValidAssetId };
|
|
4519
|
+
//# sourceMappingURL=assetFieldValues.js.map
|
|
4520
|
+
//# sourceMappingURL=assetFieldValues.js.map
|