Skip to content

Commit 7e9f982

Browse files
committed
make upload json
1 parent b9f03ef commit 7e9f982

5 files changed

Lines changed: 76 additions & 8 deletions

File tree

packages/data-types/types/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ INSERT INTO customers (domain) VALUES
158158
### Image and Attachment Domains
159159

160160
The `image` domain stores JSON objects with URL and MIME type information. The `attachment` domain accepts either that JSON shape or a plain URL string.
161+
The `upload` domain uses the same JSON object shape as `image`, ensuring both the file URL and MIME type are present.
161162

162163
```sql
163164
-- Valid image
@@ -184,7 +185,7 @@ INSERT INTO customers (document) VALUES ('https://storage.example.com/favicon.ic
184185
| `hostname` | `text` | Domain name without protocol | `example.com` |
185186
| `image` | `json` | Image metadata with URL and MIME | `{"url": "...", "mime": "image/jpeg"}` |
186187
| `attachment` | `json` | File attachment URL or metadata | `{"url": "...", "mime": "application/pdf"}` or `https://example.com/favicon.ico` |
187-
| `upload` | `text` | File upload identifier | Various formats |
188+
| `upload` | `json` | File upload metadata (URL + MIME) | `{"url": "...", "mime": "application/pdf"}` |
188189
| `single_select` | `text` | Single selection value | Text value |
189190
| `multiple_select` | `text[]` | Multiple selection values | Array of text values |
190191

@@ -212,7 +213,7 @@ The test suite validates:
212213
- Email format validation (valid and invalid cases)
213214
- URL format validation with extensive test cases
214215
- Hostname format validation
215-
- Image and attachment JSON structure validation
216+
- Image, upload, and attachment JSON structure validation
216217

217218
## Related Tooling
218219

packages/data-types/types/__tests__/domains.pgutils.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ const invalidImages = [
6464
{ url: 'https://foo.bar/some.png' }
6565
];
6666

67+
const validUploads = [
68+
{ url: 'http://www.foo.bar/some.jpg', mime: 'image/jpg' },
69+
{ url: 'https://foo.bar/some.PNG', mime: 'image/png' }
70+
];
71+
72+
const invalidUploads = [
73+
{ url: 'hi there' },
74+
{ url: 'https://foo.bar/some.png' },
75+
{ url: 'ftp://foo.bar/some.png', mime: 'image/png' }
76+
];
77+
6778
let pg: PgTestClient;
6879
let teardown: () => Promise<void>;
6980

@@ -79,7 +90,8 @@ CREATE TABLE customers (
7990
image image,
8091
attachment attachment,
8192
domain hostname,
82-
email email
93+
email email,
94+
upload upload
8395
);
8496
`);
8597
});
@@ -129,6 +141,24 @@ describe('types', () => {
129141
}
130142
});
131143

144+
it('valid upload', async () => {
145+
for (const upload of validUploads) {
146+
await pg.any(`INSERT INTO customers (upload) VALUES ($1::json);`, [upload]);
147+
}
148+
});
149+
150+
it('invalid upload', async () => {
151+
for (const upload of invalidUploads) {
152+
let failed = false;
153+
try {
154+
await pg.any(`INSERT INTO customers (upload) VALUES ($1::json);`, [upload]);
155+
} catch (e) {
156+
failed = true;
157+
}
158+
expect(failed).toBe(true);
159+
}
160+
});
161+
132162
it('valid url', async () => {
133163
for (const value of validUrls) {
134164
await pg.any(`INSERT INTO customers (url) VALUES ($1);`, [value]);

packages/data-types/types/__tests__/domains.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ const invalidImages = [
6464
{ url: 'https://foo.bar/some.png' }
6565
];
6666

67+
const validUploads = [
68+
{ url: 'http://www.foo.bar/some.jpg', mime: 'image/jpg' },
69+
{ url: 'https://foo.bar/some.PNG', mime: 'image/png' }
70+
];
71+
72+
const invalidUploads = [
73+
{ url: 'hi there' },
74+
{ url: 'https://foo.bar/some.png' },
75+
{ url: 'ftp://foo.bar/some.png', mime: 'image/png' }
76+
];
77+
6778
let pg: PgTestClient;
6879
let teardown: () => Promise<void>;
6980

@@ -79,7 +90,8 @@ CREATE TABLE customers (
7990
image image,
8091
attachment attachment,
8192
domain hostname,
82-
email email
93+
email email,
94+
upload upload
8395
);
8496
`);
8597
});
@@ -129,6 +141,24 @@ describe('types', () => {
129141
}
130142
});
131143

144+
it('valid upload', async () => {
145+
for (const upload of validUploads) {
146+
await pg.any(`INSERT INTO customers (upload) VALUES ($1::json);`, [upload]);
147+
}
148+
});
149+
150+
it('invalid upload', async () => {
151+
for (const upload of invalidUploads) {
152+
let failed = false;
153+
try {
154+
await pg.any(`INSERT INTO customers (upload) VALUES ($1::json);`, [upload]);
155+
} catch (e) {
156+
failed = true;
157+
}
158+
expect(failed).toBe(true);
159+
}
160+
});
161+
132162
it('valid url', async () => {
133163
for (const value of validUrls) {
134164
await pg.any(`INSERT INTO customers (url) VALUES ($1);`, [value]);

packages/data-types/types/deploy/schemas/public/domains/upload.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44

55
BEGIN;
66

7-
CREATE DOMAIN upload AS text CHECK (VALUE ~ '^(https?)://[^\s/$.?#].[^\s]*$');
7+
CREATE DOMAIN upload AS jsonb CHECK (
8+
value ?& ARRAY['url', 'mime']
9+
AND
10+
value->>'url' ~ '^(https?)://[^\s/$.?#].[^\s]*$'
11+
);
812
COMMENT ON DOMAIN upload IS E'@name launchqlInternalTypeUpload';
913

1014
COMMIT;

packages/data-types/types/sql/launchql-types--0.9.0.sql

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ CREATE DOMAIN single_select AS jsonb
3535

3636
COMMENT ON DOMAIN single_select IS '@name launchqlInternalTypeSingleSelect';
3737

38-
CREATE DOMAIN upload AS text
39-
CHECK (value ~ E'^(https?)://[^\\s/$.?#].[^\\s]*$');
38+
CREATE DOMAIN upload AS jsonb
39+
CHECK (
40+
value ?& ARRAY['url', 'mime']
41+
AND (value ->> 'url') ~ E'^(https?)://[^\\s/$.?#].[^\\s]*$'
42+
);
4043

4144
COMMENT ON DOMAIN upload IS '@name launchqlInternalTypeUpload';
4245

4346
CREATE DOMAIN url AS text
4447
CHECK (value ~ E'^(https?)://[^\\s/$.?#].[^\\s]*$');
4548

46-
COMMENT ON DOMAIN url IS '@name launchqlInternalTypeUrl';
49+
COMMENT ON DOMAIN url IS '@name launchqlInternalTypeUrl';

0 commit comments

Comments
 (0)