Skip to content

Commit efa16c8

Browse files
committed
Switch to remix
1 parent e5e6433 commit efa16c8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+5629
-2358
lines changed

.editorconfig

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ indent_size = 2
1010

1111
# YAML doesn't support hard tabs 🙃
1212
# Templates that will be weird with hard tabs in the website editor
13-
[{**.yml,**.md,**.rs,**.mdx,justfile,**.json}]
13+
[{**.yml,**.yaml,**.md,**.rs,**.mdx,justfile,**.json}]
1414
indent_style = space
1515

1616
[*.rs]
17-
indent_size = 4
17+
indent_size = 4

.github/workflows/main.yaml

+5-25
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,19 @@ jobs:
1414
uses: actions/setup-node@v4
1515
with:
1616
node-version: 20
17+
cache: 'pnpm'
1718

18-
- uses: pnpm/action-setup@v2
19-
name: Install pnpm
20-
id: pnpm-install
21-
with:
22-
version: 8.6.3
23-
run_install: false
24-
25-
- name: Get pnpm store directory
26-
id: pnpm-cache
27-
shell: bash
28-
run: |
29-
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
30-
31-
- uses: actions/cache@v4
32-
name: Setup pnpm cache
33-
with:
34-
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
35-
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
36-
restore-keys: |
37-
${{ runner.os }}-pnpm-store-
19+
- run: corepack enable
3820

3921
- name: Install dependencies
4022
run: pnpm install
4123

4224
- name: Build
4325
run: pnpm build
4426

45-
- name: Publish
46-
uses: cloudflare/pages-action@1
27+
- name: Deploy
28+
uses: cloudflare/wrangler-action@v3
4729
with:
4830
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
4931
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
50-
projectName: edge-cms # e.g. 'my-project'
51-
directory: dist/client # e.g. 'dist'
52-
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
32+
command: pages deploy

.gitignore

+5-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
.pnp.*
2-
.yarn/*
3-
!.yarn/patches
4-
!.yarn/plugins
5-
!.yarn/releases
6-
!.yarn/sdks
7-
!.yarn/versions
8-
9-
dist
101
node_modules
11-
/data
122

13-
# /wrangler.toml
3+
/.cache
4+
/build
5+
.env
6+
.dev.vars
147

15-
/bin
8+
.wrangler

.vscode/settings.json

+15-5
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,26 @@
66
"typescript.enablePromptUseWorkspaceTsdk": true,
77
"typescript.preferences.importModuleSpecifier": "non-relative",
88
"javascript.preferences.importModuleSpecifier": "non-relative",
9-
"editor.defaultFormatter": "esbenp.prettier-vscode",
9+
"editor.defaultFormatter": "biomejs.biome",
1010
"typescript.tsdk": "node_modules/typescript/lib",
1111
"cSpell.words": ["rjsf"],
1212
"[typescriptreact]": {
1313
"editor.defaultFormatter": "biomejs.biome"
1414
},
1515
"[typescript]": {
1616
"editor.defaultFormatter": "biomejs.biome"
17-
},
18-
"[jsonc]": {
19-
"editor.defaultFormatter": "biomejs.biome"
20-
}
17+
},
18+
"[jsonc]": {
19+
"editor.defaultFormatter": "biomejs.biome"
20+
},
21+
"[json]": {
22+
"editor.defaultFormatter": "biomejs.biome"
23+
},
24+
"[sql]": {
25+
"editor.defaultFormatter": "adpyke.vscode-sql-formatter"
26+
},
27+
"editor.codeActionsOnSave": {
28+
"quickfix.biome": "explicit",
29+
"source.organizeImports.biome": "explicit"
30+
}
2131
}

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,11 @@ node scripts/generate-wrangler.js
3636
```
3737

3838
If you run without sops set up it will still work but some values will be undefined.
39+
40+
41+
## Wishlist
42+
43+
- tenants
44+
- user sso
45+
- can host posts for a blog, etc
46+
- fix overlap API bug
File renamed without changes.

src/routes/$error.tsx app/components/error-page.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import type { FallbackProps } from 'rakkasjs';
2-
import { flattenError } from 'src/utils/wrap-server-query';
1+
import { flattenError } from '~/utils/wrap-server-query';
32

4-
export default function ErrorPage(props: FallbackProps) {
3+
export function ErrorPage(props: {
4+
error: any;
5+
/** @deprecated not used */
6+
resetErrorBoundary?: () => void;
7+
}) {
58
// const message =
69
// typeof props.error?.stack === 'string'
710
// ? props.error.stack
File renamed without changes.

src/components/icons.tsx app/components/icons.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const IconX = () => (
77
stroke="currentColor"
88
className="w-6 h-6"
99
>
10+
<title>Cross</title>
1011
<path
1112
strokeLinecap="round"
1213
strokeLinejoin="round"
@@ -24,6 +25,7 @@ export const IconMenu = () => (
2425
stroke="currentColor"
2526
className="w-6 h-6"
2627
>
28+
<title>Menu</title>
2729
<path
2830
strokeLinecap="round"
2931
strokeLinejoin="round"
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import MonacoEditor, { loader } from '@monaco-editor/react';
2+
import * as monaco from 'monaco-editor';
3+
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
4+
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
5+
// import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
6+
// import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
7+
// import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
8+
9+
self.MonacoEnvironment = {
10+
getWorker(_, label) {
11+
if (label === 'json') {
12+
return new jsonWorker();
13+
}
14+
// if (label === 'css' || label === 'scss' || label === 'less') {
15+
// return new cssWorker();
16+
// }
17+
// if (label === 'html' || label === 'handlebars' || label === 'razor') {
18+
// return new htmlWorker();
19+
// }
20+
// if (label === 'typescript' || label === 'javascript') {
21+
// return new tsWorker();
22+
// }
23+
return new editorWorker();
24+
},
25+
};
26+
27+
loader.config({ monaco });
28+
29+
export { MonacoEditor };

src/components/show.tsx app/components/show.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { FC, ReactNode } from 'react';
22

33
export const Show: FC<{
4-
when?: {};
4+
when?: any;
55
fallback?: ReactNode;
66
children?: ReactNode;
77
}> = ({ when, fallback, children }) => {

app/components/styled-link.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { NavLink } from '@remix-run/react';
2+
import clsx from 'clsx';
3+
4+
export function StyledLink({
5+
children,
6+
...props
7+
}: React.ComponentProps<typeof NavLink> & { activeClass?: string }) {
8+
const { activeClass, ...rest } = props;
9+
return (
10+
<NavLink
11+
{...rest}
12+
className={({ isActive }) =>
13+
clsx(props.className, isActive && props.activeClass)
14+
}
15+
>
16+
{children}
17+
</NavLink>
18+
);
19+
}

app/components/view-entity.tsx

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import clsx from 'clsx';
2+
import type { JSONSchema6 } from 'json-schema';
3+
import type { FC } from 'react';
4+
import { compactStringify } from '~/utils/compact-stringify';
5+
import { For } from '~/components/for';
6+
7+
export const ViewEntity: FC<{
8+
data: any;
9+
schema: JSONSchema6;
10+
type?: 'json' | 'pretty';
11+
}> = ({ data, schema, type }) => {
12+
const properties = Object.entries(schema.properties ?? {}).map(
13+
([key, value]) => ({
14+
key,
15+
value,
16+
}),
17+
);
18+
19+
if (type === 'json') {
20+
return <pre className="whitespace-pre-wrap">{compactStringify(data)}</pre>;
21+
} else {
22+
return (
23+
<For
24+
each={properties}
25+
as={({ key, value }) => (
26+
<Property
27+
key={key}
28+
name={key}
29+
schema={value as JSONSchema6}
30+
value={data?.[key]}
31+
/>
32+
)}
33+
/>
34+
);
35+
}
36+
};
37+
38+
const Property: FC<{
39+
name: string;
40+
schema: JSONSchema6;
41+
value: any;
42+
}> = ({ name, schema, ...props }) => {
43+
const type = schema.type;
44+
45+
let value: any;
46+
let showWhiteSpace: boolean;
47+
48+
if (['string', 'number'].includes(typeof props.value)) {
49+
value = props.value;
50+
showWhiteSpace = schema['ui:widget'] === 'textarea';
51+
} else {
52+
value = compactStringify(props.value);
53+
showWhiteSpace = true;
54+
}
55+
56+
return (
57+
<div>
58+
<div className={clsx('font-bold')}>{name}</div>
59+
<div className={clsx(showWhiteSpace && 'whitespace-pre-wrap')}>
60+
{value}
61+
</div>
62+
</div>
63+
);
64+
};
File renamed without changes.

src/db/load-entity-data.ts app/db/load-entity-data.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import type { AppLoadContext } from '@remix-run/cloudflare';
12
import type { JSONSchema6 } from 'json-schema';
2-
import type { RequestContext } from 'rakkasjs';
33
import sql, { join, raw } from 'sql-template-tag';
44
import { getSystemTable, isSystemTable } from './migrator/system-tables';
55
import { getOrm } from './orm';
@@ -10,7 +10,7 @@ export const loadEntityData = async ({
1010
withEntities,
1111
byId,
1212
}: {
13-
context: RequestContext;
13+
context: AppLoadContext;
1414
entityName: string;
1515
withEntities?: boolean;
1616
byId?: string | number;
@@ -73,11 +73,11 @@ export const loadEntityData = async ({
7373
};
7474

7575
export const insertItem = async (
76-
context: RequestContext,
76+
context: AppLoadContext,
7777
entityName: string,
7878
data: any,
7979
) => {
80-
console.log(`insert item`, entityName, data);
80+
console.log('insert item', entityName, data);
8181

8282
const dataPairs = Object.entries(data);
8383

@@ -95,6 +95,10 @@ export const insertItem = async (
9595
.bind(...query.values)
9696
.first<{ id: string | number }>();
9797

98+
if (!result) {
99+
throw new Error(`Could not insert item ${JSON.stringify(data)}`);
100+
}
101+
98102
return result;
99103
};
100104

@@ -104,7 +108,7 @@ export const updateItem = async ({
104108
id,
105109
data,
106110
}: {
107-
context: RequestContext;
111+
context: AppLoadContext;
108112
entityName: string;
109113
// NOTE: id must be passed separately to account for the case
110114
// where id is changed inside the update
File renamed without changes.

src/db/migrator/create-table.ts app/db/migrator/create-table.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { JSONSchema6 } from 'json-schema';
2-
import { formatSql } from 'src/utils/format-sqlite';
2+
import { formatSql } from '~/utils/format-sqlite';
33
import { convertJsonSchemaToDatabaseSchema } from './convert-schema';
44
import { generateMigrationStepCreateTable } from './diff-schema';
55

@@ -13,7 +13,7 @@ export const getCreateTableQuery = (
1313
) => {
1414
const name = jsonSchema.title;
1515

16-
if (!name) throw new Error(`Name of table is required`);
16+
if (!name) throw new Error('Name of table is required');
1717

1818
const databaseSchema = convertJsonSchemaToDatabaseSchema(jsonSchema);
1919

src/db/migrator/diff-schema.ts app/db/migrator/diff-schema.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { formatSql } from 'src/utils/format-sqlite';
1+
import { formatSql } from '~/utils/format-sqlite';
22
import { escapeIdIfNeeded } from './shared';
33
import type {
44
MigrationStep,
@@ -79,7 +79,7 @@ export const generateMigrationStepCreateTable = (
7979
) => {
8080
const name = step.table.name;
8181

82-
if (!name) throw new Error(`Name of table is required`);
82+
if (!name) throw new Error('Name of table is required');
8383

8484
return [
8585
'CREATE TABLE',
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
WITH all_tables AS (
2+
SELECT
3+
name
4+
FROM
5+
sqlite_schema
6+
WHERE
7+
type = 'table'
8+
AND name NOT IN ('d1_kv', '_cf_KV') -- ignore system tables
9+
)
10+
SELECT
11+
at.name name,
12+
json_group_array(
13+
json_object(
14+
'cid',
15+
pti.cid,
16+
'name',
17+
pti.name,
18+
'type',
19+
pti.type,
20+
'dflt_value',
21+
pti.dflt_value,
22+
'notnull',
23+
pti."notnull",
24+
'pk',
25+
pti.pk
26+
)
27+
) as columns
28+
FROM
29+
all_tables at
30+
INNER JOIN pragma_table_info(at.name) pti
31+
GROUP BY
32+
at.name
33+
ORDER BY
34+
name;
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)