@read-frog/definitions 0.1.2 → 0.1.3
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/index.d.ts +19 -7
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -14
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
- package/src/constants/app.ts +1 -0
- package/src/constants/auth.ts +6 -0
- package/src/constants/beta-access.ts +9 -0
- package/src/constants/column.ts +2 -0
- package/src/constants/dictionary.ts +2379 -0
- package/src/constants/url.ts +22 -0
- package/src/index.ts +10 -0
- package/src/schemas/cell-value.ts +54 -0
- package/src/schemas/version.ts +101 -0
- package/src/types/column.ts +60 -0
- package/src/types/languages.ts +905 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const CHROME_EXTENSION_ORIGIN = "chrome-extension://modkelfkcfjpgbfmnbnllalkiogfofhb"
|
|
2
|
+
export const EDGE_EXTENSION_ORIGIN = "extension://cbcbomlgikfbdnoaohcjfledcoklcjbo"
|
|
3
|
+
|
|
4
|
+
export const READFROG_DOMAIN = "readfrog.app"
|
|
5
|
+
export const LOCALHOST_DOMAIN = "localhost"
|
|
6
|
+
|
|
7
|
+
// Browser-accessible TanStack Start dev server.
|
|
8
|
+
export const WEBSITE_DEV_PORT = 8888
|
|
9
|
+
export const WEBSITE_DEV_URL = `http://localhost:${WEBSITE_DEV_PORT}`
|
|
10
|
+
|
|
11
|
+
// Legacy Next.js Caddy proxy kept for compatibility while the old app is still present.
|
|
12
|
+
export const CADDY_DEV_PORT = 4433
|
|
13
|
+
export const WEBSITE_CADDY_DEV_URL = `https://localhost:${CADDY_DEV_PORT}`
|
|
14
|
+
|
|
15
|
+
export const WEBSITE_PROD_URL = "https://www.readfrog.app"
|
|
16
|
+
export const TRUSTED_ORIGINS = [CHROME_EXTENSION_ORIGIN, EDGE_EXTENSION_ORIGIN, WEBSITE_PROD_URL]
|
|
17
|
+
export const API_DEV_PORT = 7777
|
|
18
|
+
export const API_DEV_URL = `http://localhost:${API_DEV_PORT}`
|
|
19
|
+
export const API_PROD_URL = "https://api.readfrog.app"
|
|
20
|
+
|
|
21
|
+
// Domain constants for cookie monitoring and other domain-based operations
|
|
22
|
+
export const AUTH_DOMAINS = [READFROG_DOMAIN, LOCALHOST_DOMAIN] as const
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./constants/app"
|
|
2
|
+
export * from "./constants/auth"
|
|
3
|
+
export * from "./constants/beta-access"
|
|
4
|
+
export * from "./constants/column"
|
|
5
|
+
export * from "./constants/dictionary"
|
|
6
|
+
export * from "./constants/url"
|
|
7
|
+
export * from "./schemas/cell-value"
|
|
8
|
+
export * from "./schemas/version"
|
|
9
|
+
export * from "./types/column"
|
|
10
|
+
export * from "./types/languages"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ColumnConfig } from "@/types/column"
|
|
2
|
+
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create a Zod schema for a cell value based on column config.
|
|
7
|
+
* All cell schemas are nullable (empty cells are valid).
|
|
8
|
+
*/
|
|
9
|
+
export function createCellSchema(config: ColumnConfig): z.ZodType {
|
|
10
|
+
switch (config.type) {
|
|
11
|
+
case "string":
|
|
12
|
+
return z.string().nullable()
|
|
13
|
+
case "number":
|
|
14
|
+
return z.number({ message: "Must be a valid number" }).nullable()
|
|
15
|
+
case "boolean":
|
|
16
|
+
return z.boolean().nullable()
|
|
17
|
+
case "date":
|
|
18
|
+
return z.iso.date().nullable()
|
|
19
|
+
case "select":
|
|
20
|
+
if (config.options.length === 0) {
|
|
21
|
+
return z.string().nullable()
|
|
22
|
+
}
|
|
23
|
+
return z
|
|
24
|
+
.enum(config.options.map(o => o.id) as [string, ...string[]])
|
|
25
|
+
.nullable()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Create a Zod schema for an entire row based on column definitions.
|
|
31
|
+
* Each column becomes a field in the object schema.
|
|
32
|
+
*/
|
|
33
|
+
export function createRowSchema(
|
|
34
|
+
columns: Array<{ id: string, name: string, config: ColumnConfig }>,
|
|
35
|
+
): z.ZodObject<Record<string, z.ZodType>> {
|
|
36
|
+
const shape: Record<string, z.ZodType> = {}
|
|
37
|
+
|
|
38
|
+
for (const column of columns) {
|
|
39
|
+
// Use column name as description for AI schema generation
|
|
40
|
+
shape[column.id] = createCellSchema(column.config).describe(column.name)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return z.object(shape)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert row schema to JSON Schema for AI structured outputs.
|
|
48
|
+
* Use this when generating prompts for LLMs that support structured outputs.
|
|
49
|
+
*/
|
|
50
|
+
export function rowSchemaToJsonSchema(
|
|
51
|
+
columns: Array<{ id: string, name: string, config: ColumnConfig }>,
|
|
52
|
+
) {
|
|
53
|
+
return z.toJSONSchema(createRowSchema(columns))
|
|
54
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Semantic version regex pattern
|
|
5
|
+
* Matches versions like: 1.0.0, 10.20.30
|
|
6
|
+
* Does NOT match: v1.0.0, 1.0.0-alpha, 1.0, 1.-1.0
|
|
7
|
+
*/
|
|
8
|
+
export const SEMANTIC_VERSION_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Zod schema for semantic version validation
|
|
12
|
+
* Validates semantic version strings according to SemVer conventions
|
|
13
|
+
* Requires exactly 3 parts: major.minor.patch
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* semanticVersionSchema.parse('1.0.0') // ✓ valid
|
|
17
|
+
* semanticVersionSchema.parse('10.20.30') // ✓ valid
|
|
18
|
+
* semanticVersionSchema.parse('1.11') // ✗ throws error (must have 3 parts)
|
|
19
|
+
* semanticVersionSchema.parse('v1.0.0') // ✗ throws error
|
|
20
|
+
* semanticVersionSchema.parse('1.0.0-alpha') // ✗ throws error
|
|
21
|
+
*/
|
|
22
|
+
export const semanticVersionSchema = z.string().regex(
|
|
23
|
+
SEMANTIC_VERSION_REGEX,
|
|
24
|
+
"Must be a valid semantic version with exactly 3 parts (e.g., 1.0.0, 10.20.30)",
|
|
25
|
+
).refine(
|
|
26
|
+
(version) => {
|
|
27
|
+
// Additional validation: ensure all parts are non-negative numbers
|
|
28
|
+
const parts = version.split(".")
|
|
29
|
+
return parts.length === 3 && parts.every(part => !Number.isNaN(Number(part)) && Number(part) >= 0)
|
|
30
|
+
},
|
|
31
|
+
{ message: "Version must have exactly 3 parts and all parts must be non-negative numbers" },
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Type for semantic version string
|
|
36
|
+
*/
|
|
37
|
+
export type SemanticVersion = z.infer<typeof semanticVersionSchema>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Version type classification
|
|
41
|
+
*/
|
|
42
|
+
export type VersionType = "major" | "minor" | "patch"
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parse a semantic version string into its components
|
|
46
|
+
* Validates the input using semanticVersionSchema before parsing
|
|
47
|
+
*
|
|
48
|
+
* @param version - The version string to parse (must be in format major.minor.patch)
|
|
49
|
+
* @returns An object containing the major, minor, and patch numbers
|
|
50
|
+
* @throws {z.ZodError} If the version string is invalid
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* parseSemanticVersion('1.2.3') // { major: 1, minor: 2, patch: 3 }
|
|
54
|
+
* parseSemanticVersion('10.20.30') // { major: 10, minor: 20, patch: 30 }
|
|
55
|
+
* parseSemanticVersion('1.0') // throws error - must have 3 parts
|
|
56
|
+
* parseSemanticVersion('v1.0.0') // throws error - invalid format
|
|
57
|
+
*/
|
|
58
|
+
export function parseSemanticVersion(version: string): {
|
|
59
|
+
major: number
|
|
60
|
+
minor: number
|
|
61
|
+
patch: number
|
|
62
|
+
} {
|
|
63
|
+
// Validate the version string first
|
|
64
|
+
const validatedVersion = semanticVersionSchema.parse(version)
|
|
65
|
+
|
|
66
|
+
const parts = validatedVersion.split(".")
|
|
67
|
+
return {
|
|
68
|
+
major: Number.parseInt(parts[0]!, 10),
|
|
69
|
+
minor: Number.parseInt(parts[1]!, 10),
|
|
70
|
+
patch: Number.parseInt(parts[2]!, 10),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Determine the version type (major, minor, or patch) based on semantic versioning rules
|
|
76
|
+
* Validates the input using semanticVersionSchema before classification
|
|
77
|
+
*
|
|
78
|
+
* @param version - The version string to classify
|
|
79
|
+
* @returns The version type classification
|
|
80
|
+
* @throws {z.ZodError} If the version string is invalid
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* getVersionType('1.0.0') // 'major'
|
|
84
|
+
* getVersionType('1.2.0') // 'minor'
|
|
85
|
+
* getVersionType('1.2.3') // 'patch'
|
|
86
|
+
* getVersionType('1.0') // throws error - must have 3 parts
|
|
87
|
+
*/
|
|
88
|
+
export function getVersionType(version: string): VersionType {
|
|
89
|
+
// parseSemanticVersion already validates the version
|
|
90
|
+
const { major, minor, patch } = parseSemanticVersion(version)
|
|
91
|
+
|
|
92
|
+
if (major > 0 && minor === 0 && patch === 0) {
|
|
93
|
+
return "major"
|
|
94
|
+
}
|
|
95
|
+
else if (minor > 0 && patch === 0) {
|
|
96
|
+
return "minor"
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return "patch"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
|
|
3
|
+
// Source of truth - can be iterated at runtime
|
|
4
|
+
export const COLUMN_TYPES = ["string", "number", "boolean", "date", "select"] as const
|
|
5
|
+
|
|
6
|
+
export type ColumnType = (typeof COLUMN_TYPES)[number]
|
|
7
|
+
|
|
8
|
+
export const selectOptionSchema = z.object({
|
|
9
|
+
id: z.string(),
|
|
10
|
+
value: z.string(),
|
|
11
|
+
color: z.string().regex(/^#[0-9a-f]{6}$/i, "Color must be a valid hex color"),
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export const columnConfigSchema = z.discriminatedUnion("type", [
|
|
15
|
+
z.object({ type: z.literal("string") }),
|
|
16
|
+
z.object({
|
|
17
|
+
type: z.literal("number"),
|
|
18
|
+
decimal: z.number().int().min(0).default(0),
|
|
19
|
+
format: z.enum(["number", "currency", "percent"]).default("number"),
|
|
20
|
+
}),
|
|
21
|
+
z.object({ type: z.literal("boolean") }),
|
|
22
|
+
z.object({
|
|
23
|
+
type: z.literal("date"),
|
|
24
|
+
dateFormat: z.string().optional(),
|
|
25
|
+
}),
|
|
26
|
+
z.object({
|
|
27
|
+
type: z.literal("select"),
|
|
28
|
+
options: z.array(selectOptionSchema).default([]),
|
|
29
|
+
}),
|
|
30
|
+
])
|
|
31
|
+
|
|
32
|
+
export type ColumnConfig = z.infer<typeof columnConfigSchema>
|
|
33
|
+
export type SelectOption = z.infer<typeof selectOptionSchema>
|
|
34
|
+
|
|
35
|
+
// Column type metadata (label, default config)
|
|
36
|
+
export const COLUMN_TYPE_INFO: Record<
|
|
37
|
+
ColumnType,
|
|
38
|
+
{ label: string, defaultConfig: ColumnConfig }
|
|
39
|
+
> = {
|
|
40
|
+
string: { label: "Text", defaultConfig: { type: "string" } },
|
|
41
|
+
number: {
|
|
42
|
+
label: "Number",
|
|
43
|
+
defaultConfig: { type: "number", decimal: 0, format: "number" },
|
|
44
|
+
},
|
|
45
|
+
boolean: { label: "Checkbox", defaultConfig: { type: "boolean" } },
|
|
46
|
+
date: { label: "Date", defaultConfig: { type: "date" } },
|
|
47
|
+
select: { label: "Select", defaultConfig: { type: "select", options: [] } },
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function isNumberConfig(
|
|
51
|
+
config: ColumnConfig,
|
|
52
|
+
): config is Extract<ColumnConfig, { type: "number" }> {
|
|
53
|
+
return config.type === "number"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function isSelectConfig(
|
|
57
|
+
config: ColumnConfig,
|
|
58
|
+
): config is Extract<ColumnConfig, { type: "select" }> {
|
|
59
|
+
return config.type === "select"
|
|
60
|
+
}
|