Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 10 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
dist
build
coverage
.turbo
pnpm-lock.yaml
**/database/migrations
**/src/database/migrations
**/.arkormx
**/storage
9 changes: 9 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"plugins": ["prettier-plugin-brace-style"],
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120,
"tabWidth": 2,
"braceStyle": "1tbs"
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format follows semantic versioning principles.

### Added

- `RealtimeConfig.importModule` loads the transport SDKs (`pusher-js`, `firebase/*`) for every transport and for device tokens, so pages without a bundler can load them from a CDN. Defaults to a dynamic `import()`. The `createPusherTransport`, `createFirebaseTransport`, `createFirebaseDatabaseTransport` and `requestDeviceToken` helpers accept it as an extra argument.
- `RealtimeClient.deviceToken({ serviceWorker })` takes a service worker registration or script URL (registered with the Firebase web config as `firebaseConfig`), returns `null` where web push is unsupported, and falls back to the `firebase` config when streaming over another transport. `requestDeviceToken()` issues a token without a client.
- Added the `Broadcast` facade to `@arkstack/notifications`: a channel authorization registry (`Broadcast.channel('private-team.{teamId}', authorizer)`) used by every transport, `Broadcast.broadcast()` for arbitrary events, `Broadcast.handleAuth()` for custom auth routes, `Broadcast.clientConfig()`, and `Broadcast.routes()` registering `POST /realtime/auth` and `GET /realtime/config`.
- Added the `firebase-database` realtime transport (Firebase Realtime Database channels with per-user, time-limited grants checked by security rules, plus bounded `prune()`), the signal-only `polling` transport, and the `memory` transport for tests, on both server and client.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Arkstack uses structured error classes and centralized error middleware.
Example:

```ts
throw new RequestError('Profile not found', 404);
throw new RequestError('Profile not found', 404)
```

All errors return consistent JSON:
Expand All @@ -173,7 +173,7 @@ Standardized API responses:
return new UserResource(req, res, user).json().status(200).additional({
status: 'success',
message: 'User retrieved',
});
})
```

Response format:
Expand Down
34 changes: 17 additions & 17 deletions arkormx.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@ import { createArkormCurrentPageResolver } from 'resora'
import path from 'node:path'

const db = new Kysely<Record<string, never>>({
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL,
}),
dialect: new PostgresDialect({
pool: new Pool({
connectionString: process.env.DATABASE_URL,
}),
}),
})

export default defineConfig({
paths: {
models: path.join(process.cwd(), '/database/models'),
factories: path.join(process.cwd(), '/database/factories'),
seeders: path.join(process.cwd(), '/database/seeders'),
migrations: path.join(process.cwd(), '/database/migrations'),
buildOutput: './dist',
},
outputExt: 'ts',
adapter: createKyselyAdapter(db),
pagination: {
resolveCurrentPage: createArkormCurrentPageResolver(),
},
})
paths: {
models: path.join(process.cwd(), '/database/models'),
factories: path.join(process.cwd(), '/database/factories'),
seeders: path.join(process.cwd(), '/database/seeders'),
migrations: path.join(process.cwd(), '/database/migrations'),
buildOutput: './dist',
},
outputExt: 'ts',
adapter: createKyselyAdapter(db),
pagination: {
resolveCurrentPage: createArkormCurrentPageResolver(),
},
})
55 changes: 28 additions & 27 deletions create-arkstack/cleaner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,36 @@ import { existsSync, readFileSync } from 'node:fs'
import { cwd } from 'node:process'
import { join } from 'node:path'

const filesToPatch = [
'src/core/app.ts',
]
const filesToPatch = ['src/core/app.ts']

for (const file of filesToPatch) {
const filePath = join(cwd(), '../express', file)
if (!existsSync(filePath)) {
continue
}
const filePath = join(cwd(), '../express', file)
if (!existsSync(filePath)) {
continue
}

let content = readFileSync(filePath, 'utf-8')
let content = readFileSync(filePath, 'utf-8')

content = content
.replace('import { ModelNotFoundException } from \'arkormx\'\n', '')
.replace('import { prisma } from \'src/core/database\'\n', '')
.replace('import { Prisma } from \'@prisma/client\'\n', '')
.replace(' async shutdown () {\n await prisma.$disconnect()\n process.exit(0)\n }', ' async shutdown () {\n process.exit(0)\n }')
.replace(
' * Shuts down the application by disconnecting from the database and exiting the process.',
' * Shuts down the application and exits the process.',
)
.replace(
/\n\s*if \((?:err|cause) instanceof Prisma\.PrismaClientKnownRequestError && (?:err|cause)\.code === "P2025"\) \{\n\s*error\.code = 404\n\s*error\.message = `\$\{(?:err|cause)\.meta\?\.modelName\} not found!`\n\s*\}\n/g,
'\n',
)
.replace(
/\n\s*if \((?:err|cause) instanceof ModelNotFoundException\) \{\n\s*error\.code = 404\n\s*error\.message = `\$\{(?:err|cause)\.getModelName\(\)\} not found!`\n\s*\}\n/g,
'\n',
)
content = content
.replace("import { ModelNotFoundException } from 'arkormx'\n", '')
.replace("import { prisma } from 'src/core/database'\n", '')
.replace("import { Prisma } from '@prisma/client'\n", '')
.replace(
' async shutdown () {\n await prisma.$disconnect()\n process.exit(0)\n }',
' async shutdown () {\n process.exit(0)\n }',
)
.replace(
' * Shuts down the application by disconnecting from the database and exiting the process.',
' * Shuts down the application and exits the process.',
)
.replace(
/\n\s*if \((?:err|cause) instanceof Prisma\.PrismaClientKnownRequestError && (?:err|cause)\.code === "P2025"\) \{\n\s*error\.code = 404\n\s*error\.message = `\$\{(?:err|cause)\.meta\?\.modelName\} not found!`\n\s*\}\n/g,
'\n',
)
.replace(
/\n\s*if \((?:err|cause) instanceof ModelNotFoundException\) \{\n\s*error\.code = 404\n\s*error\.message = `\$\{(?:err|cause)\.getModelName\(\)\} not found!`\n\s*\}\n/g,
'\n',
)

console.log(content)
}
console.log(content)
}
19 changes: 8 additions & 11 deletions create-arkstack/src/Commands/CreateArkstackCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export class CreateArkstackCommand extends Command {
{--i|install: Install node_modules right away}
{--t|token?: Kit repo authentication token.}
{--d|desc?: Project Description.}
{--k|kit?: Runtime template. [${templates.map(e => e.alias).join(',')}]}
{--s|stack?: Inertia front-end stack. [${['none', ...inertiaStacks.map(e => e.value)].join(',')}]}
{--k|kit?: Runtime template. [${templates.map((e) => e.alias).join(',')}]}
{--s|stack?: Inertia front-end stack. [${['none', ...inertiaStacks.map((e) => e.value)].join(',')}]}
{--l|lean: Make a lean project.}
{--f|full: Make a full project (Ignored if lean is defined).}
{--p|pre: Download prerelease version if available.}
Expand Down Expand Up @@ -113,7 +113,10 @@ export class CreateArkstackCommand extends Command {
message: 'Add an Inertia front-end? (server-side adapter + client scaffolding):',
choices: [
{ name: 'None - plain server-rendered views', value: 'none' },
...inertiaStacks.map((e) => ({ name: `${e.name} - Inertia + ${e.name}`, value: e.value })),
...inertiaStacks.map((e) => ({
name: `${e.name} - Inertia + ${e.name}`,
value: e.value,
})),
],
default: 'none',
when: () => !options.stack,
Expand Down Expand Up @@ -205,20 +208,14 @@ export class CreateArkstackCommand extends Command {
}

if (kit.lean) {
spinner.info(Logger.parse([[
'Applying lean profile...',
'green',
]], '', false)).start()
spinner.info(Logger.parse([['Applying lean profile...', 'green']], '', false)).start()
await actions.makeLeanProfile(kitName)
} else {
await actions.makeFullProfile(kitName)
}

if (wantsInertia) {
spinner.info(Logger.parse([[
`Adding Inertia (${Str.title(stack)})...`,
'green',
]], '', false)).start()
spinner.info(Logger.parse([[`Adding Inertia (${Str.title(stack)})...`, 'green']], '', false)).start()
await actions.applyInertia(kitName, stack)
}

Expand Down
Loading
Loading