@cellajs/create-cella 0.1.7 → 0.2.1

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/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # @cellajs/create-cella
2
+
3
+ CLI tool to scaffold a new Cella project from the template.
4
+
5
+ ## Overview
6
+
7
+ This CLI creates a new Cella project by downloading the latest template, setting up your development environment, and configuring git with upstream tracking for future syncs.
8
+
9
+ ## Usage
10
+
11
+ ```bash
12
+ pnpm create @cellajs/cella my-app
13
+ ```
14
+
15
+ Running without arguments starts interactive mode, prompting for:
16
+
17
+ 1. **Project name** – Directory name and package name
18
+ 2. **New branch** – Optionally create a dev branch alongside `main`
19
+ 3. **Directory conflict** – If target exists, choose to cancel or continue
20
+
21
+ ## CLI Options
22
+
23
+ ```bash
24
+ pnpm create @cellajs/cella [directory] [options]
25
+ ```
26
+
27
+ ## What It Does
28
+
29
+ 1. Downloads latest Cella template via [giget](https://github.com/unjs/giget)
30
+ 2. Cleans template files (removes cella-specific docs, configs)
31
+ 3. Installs dependencies with `pnpm install`
32
+ 4. Generates initial database migrations
33
+ 5. Initializes git repository with initial commit
34
+ 6. Creates optional working branch
35
+ 7. Adds Cella as upstream remote for future syncs
36
+
37
+ ## Development
38
+
39
+ ```bash
40
+ cd cli/create-cella
41
+
42
+ # Type check
43
+ pnpm ts
44
+
45
+ # Lint
46
+ pnpm lint:fix
47
+
48
+ # Run tests
49
+ pnpm test
50
+
51
+ # Run locally
52
+ pnpm start
53
+
54
+ # Build for npm publish
55
+ pnpm build
56
+ ```
57
+
@@ -0,0 +1,404 @@
1
+ /**
2
+ * Placeholder default config for new forks created by `create-cella`.
3
+ *
4
+ * This file replaces `shared/config/config.default.ts` during project creation.
5
+ * Tokens `__project_name__` and `__project_slug__` are interpolated with the
6
+ * project name chosen by the user. All Cella-specific branding, URLs, tokens
7
+ * and company details are replaced with safe placeholder values.
8
+ *
9
+ * NOTE: This file is NOT compiled or imported — it is copied and interpolated
10
+ * as plain text. The import path below is relative to `shared/config/` (its destination).
11
+ */
12
+ import type { BaseAuthStrategies, BaseOAuthProviders, ConfigMode, RequiredConfig, S3Config } from '../src/builder/types';
13
+
14
+ // Re-export for external consumers
15
+ export { roles, hierarchy } from './hierarchy-config';
16
+
17
+ export const config = {
18
+
19
+ /******************************************************************************
20
+ * ENTITY DATA MODEL
21
+ ******************************************************************************/
22
+
23
+ /** All entity types in the app - must match hierarchy.allTypes. Explicit tuple for Drizzle compatibility. */
24
+ entityTypes: ['user', 'organization', 'attachment', 'page'] as const,
25
+
26
+ /** Context entities with memberships - must match hierarchy.contextTypes. Explicit tuple for Drizzle compatibility. */
27
+ contextEntityTypes: ['organization'] as const,
28
+
29
+ /** Product/content entities - must match hierarchy.productTypes. Explicit tuple for Drizzle compatibility. */
30
+ productEntityTypes: ['attachment', 'page'] as const,
31
+
32
+ /**
33
+ * Parentless product entities (no organization_id) - must match hierarchy.parentlessProductTypes.
34
+ * Explicit tuple required for Drizzle compatibility. Compile-time validated in shared/index.ts.
35
+ */
36
+ parentlessProductEntityTypes: ['page'] as const,
37
+
38
+ /** Product entity types tracked for seen/unseen counts. Must be org-scoped (not parentless). */
39
+ seenTrackedEntityTypes: ['attachment'] as const,
40
+
41
+ /** Maps entity types to their ID column names - must match entityTypes */
42
+ entityIdColumnKeys: {
43
+ user: 'userId',
44
+ organization: 'organizationId',
45
+ attachment: 'attachmentId',
46
+ page: 'pageId',
47
+ } as const,
48
+
49
+ /** Available CRUD actions for permission checks */
50
+ entityActions: ['create', 'read', 'update', 'delete'] as const,
51
+
52
+ /** Resource types that are not entities but have activities logged */
53
+ resourceTypes: ['request', 'membership', 'inactive_membership', 'tenant'] as const,
54
+
55
+ /**
56
+ * User menu structure of context entities with optional nested subentities.
57
+ * If subentityType is set, the table must include `${entity}Id` foreign key.
58
+ */
59
+ menuStructure: [
60
+ { entityType: 'organization',subentityType: null} as const,
61
+ ],
62
+
63
+ /** Default restrictions for tenants (entity quotas and rate limits) */
64
+ defaultRestrictions: {
65
+ quotas: {
66
+ organization: 5,
67
+ user: 1000,
68
+ attachment: 100,
69
+ },
70
+ rateLimits: {
71
+ apiPointsPerHour: 1000,
72
+ },
73
+ } as const,
74
+
75
+ /** Public tenant for platform-wide content (pages, docs, etc.) */
76
+ publicTenant: { id: 'public', name: 'Public' },
77
+
78
+ /******************************************************************************
79
+ * SYSTEM ROLES
80
+ ******************************************************************************/
81
+
82
+ /**
83
+ * System-wide roles stored in DB.
84
+ * Must include 'admin' for system administration access.
85
+ */
86
+ systemRoles: ['admin'] as const,
87
+
88
+ /******************************************************************************
89
+ * APP IDENTITY
90
+ ******************************************************************************/
91
+
92
+ /** App display name shown in UI and emails */
93
+ name: '__project_name__',
94
+ /** URL-safe identifier used in paths and storage */
95
+ slug: '__project_slug__',
96
+ /** Primary domain for the app */
97
+ domain: '__project_slug__.example.com',
98
+ /** App description for SEO and meta tags */
99
+ description: '__project_name__ — powered by Cella.',
100
+ /** SEO keywords for search engines */
101
+ keywords:
102
+ 'starter kit, fullstack, monorepo, typescript, hono, honojs, drizzle, shadcn, react, postgres, pwa, offline, instant§ updates, realtime data, sync engine',
103
+
104
+ /******************************************************************************
105
+ * URLS & ENDPOINTS
106
+ ******************************************************************************/
107
+
108
+ /** Frontend SPA base URL */
109
+ frontendUrl: 'https://__project_slug__.example.com',
110
+ /** Backend API base URL */
111
+ backendUrl: 'https://api.__project_slug__.example.com',
112
+ /** OAuth callback base URL */
113
+ backendAuthUrl: 'https://api.__project_slug__.example.com/auth',
114
+
115
+ /** About page URL */
116
+ aboutUrl: 'https://__project_slug__.example.com/about',
117
+ /** Status page URL for uptime monitoring */
118
+ statusUrl: 'https://status.__project_slug__.example.com',
119
+ /** Canonical production URL */
120
+ productionUrl: 'https://__project_slug__.example.com',
121
+
122
+ /** Default redirect path after login */
123
+ defaultRedirectPath: '/home',
124
+ /** Redirect path for first-time users */
125
+ welcomeRedirectPath: '/welcome',
126
+
127
+ /******************************************************************************
128
+ * EMAIL
129
+ ******************************************************************************/
130
+
131
+ /** Email address for user support inquiries */
132
+ supportEmail: 'support@__project_slug__.example.com',
133
+
134
+ /** From address for system notifications */
135
+ senderEmail: 'notifications@__project_slug__.example.com',
136
+
137
+ /** Receive security warnings */
138
+ securityEmail: 'security@__project_slug__.example.com',
139
+
140
+ /******************************************************************************
141
+ * MODE & FLAGS
142
+ ******************************************************************************/
143
+
144
+ /** Runtime mode - overridden per environment file */
145
+ mode: 'development' as ConfigMode,
146
+ /** Enable debug logging and dev tools */
147
+ debug: false,
148
+ /** Enable maintenance mode (blocks all requests) */
149
+ maintenance: false,
150
+ /** Cookie version - increment when changing cookie structure to invalidate old cookies */
151
+ cookieVersion: 'v1',
152
+
153
+ /******************************************************************************
154
+ * FEATURE FLAGS
155
+ ******************************************************************************/
156
+
157
+ /**
158
+ * Feature toggles for app capabilities.
159
+ * Use to enable/disable major features without code changes.
160
+ */
161
+ has: {
162
+ /** Progressive Web App support for preloading static assets and offline support */
163
+ pwa: true,
164
+ /** Allow users to sign up. If false, the app is by invitation only */
165
+ registrationEnabled: true,
166
+ /** Suggest a waitlist for unknown emails when sign up is disabled */
167
+ waitlist: true,
168
+ /** S3 fully configured - if false, files will be stored in local browser (IndexedDB) */
169
+ uploadEnabled: false,
170
+ },
171
+
172
+ /******************************************************************************
173
+ * AUTHENTICATION
174
+ ******************************************************************************/
175
+
176
+ /**
177
+ * Enabled authentication strategies.
178
+ * TOTP can only be used as MFA fallback with passkey as primary.
179
+ */
180
+ enabledAuthStrategies: ['password', 'passkey', 'totp'] satisfies BaseAuthStrategies[],
181
+
182
+ /** Enabled OAuth providers - currently supports: github, google, microsoft */
183
+ enabledOAuthProviders: [] satisfies BaseOAuthProviders[],
184
+
185
+ /** Token types used for verification flows */
186
+ tokenTypes: ['email-verification', 'oauth-verification', 'password-reset', 'invitation', 'confirm-mfa'] as const,
187
+
188
+ /** TOTP configuration for MFA */
189
+ totpConfig: {
190
+ intervalInSeconds: 30,
191
+ gracePeriodInSeconds: 60,
192
+ digits: 6,
193
+ },
194
+
195
+ /******************************************************************************
196
+ * API CONFIGURATION
197
+ ******************************************************************************/
198
+
199
+ /** API version prefix for endpoints */
200
+ apiVersion: 'v1',
201
+ /** API documentation description shown in Scalar */
202
+ apiDescription: `⚠️ ATTENTION: PRERELEASE!
203
+ This API is organized into modules based on logical domains (e.g. \`auth\`, \`organizations\`, \`memberships\`).
204
+ Each module includes a set of endpoints that expose functionality related to a specific resource or cross resource logic.
205
+
206
+ The documentation is generated from source code using \`zod\` schemas, converted into OpenAPI via \`zod-openapi\` and served through the \`hono\` framework.`,
207
+
208
+
209
+ /******************************************************************************
210
+ * REQUEST LIMITS
211
+ ******************************************************************************/
212
+
213
+ /**
214
+ * Default page sizes for list endpoints. Backend enforces max 1000.
215
+ * Must include 'default' key as fallback.
216
+ */
217
+ requestLimits: {
218
+ default: 40,
219
+ users: 100,
220
+ members: 40,
221
+ organizations: 40,
222
+ requests: 40,
223
+ attachments: 40,
224
+ pages: 40,
225
+ pendingMemberships: 20,
226
+ },
227
+
228
+ /** Max JSON body size in bytes */
229
+ jsonBodyLimit: 1 * 1024 * 1024,
230
+ /** Max file upload size in bytes */
231
+ fileUploadLimit: 20 * 1024 * 1024,
232
+ /** Default body size limit in bytes */
233
+ defaultBodyLimit: 1 * 1024 * 1024,
234
+
235
+ /******************************************************************************
236
+ * STORAGE & UPLOADS (S3)
237
+ ******************************************************************************/
238
+
239
+ /** S3-compatible storage configuration */
240
+ s3: {
241
+ /** Prefix to namespace files when sharing a bucket across apps or envs */
242
+ bucketPrefix: '__project_slug__',
243
+ /** Public bucket name for publicly accessible files */
244
+ publicBucket: '',
245
+ /** Private bucket name for authenticated-only files */
246
+ privateBucket: '',
247
+ /** S3 region identifier */
248
+ region: '',
249
+ /** S3 host endpoint */
250
+ host: '',
251
+ /** CDN URL for private bucket (signed URLs) */
252
+ privateCDNUrl: '',
253
+ /** CDN URL for public bucket */
254
+ publicCDNUrl: '',
255
+ } satisfies S3Config,
256
+
257
+ /** Upload template IDs for Transloadit processing pipelines */
258
+ uploadTemplateIds: ['avatar', 'cover', 'attachment'] as const,
259
+
260
+ /** Uppy upload widget default restrictions */
261
+ uppy: {
262
+ defaultRestrictions: {
263
+ maxFileSize: 10 * 1024 * 1024,
264
+ maxNumberOfFiles: 1,
265
+ allowedFileTypes: ['.jpg', '.jpeg', '.png'],
266
+ maxTotalFileSize: 100 * 1024 * 1024,
267
+ minFileSize: null,
268
+ minNumberOfFiles: null,
269
+ requiredMetaFields: [],
270
+ },
271
+ },
272
+
273
+ /**
274
+ * Local blob storage restrictions (IndexedDB/Dexie).
275
+ * Controls which attachments are cached locally for offline access.
276
+ */
277
+ localBlobStorage: {
278
+ enabled: true, // Enable local blob caching
279
+ maxFileSize: 10 * 1024 * 1024, // 10MB - files larger than this are not cached locally
280
+ maxTotalSize: 100 * 1024 * 1024, // 100MB - total cache size, LRU eviction when exceeded
281
+ allowedContentTypes: [] as string[], // Empty = all types allowed
282
+ excludedContentTypes: ['video/*'] as string[], // Excluded types (takes precedence over allowed)
283
+ downloadConcurrency: 2, // Max concurrent background downloads
284
+ uploadRetryAttempts: 3, // Max retry attempts for failed uploads
285
+ uploadRetryDelays: [60000, 300000, 900000] as const, // Retry delays in ms (1min, 5min, 15min)
286
+ },
287
+
288
+ /******************************************************************************
289
+ * THIRD-PARTY SERVICES
290
+ ******************************************************************************/
291
+
292
+ /** Paddle client token for payments */
293
+ paddleToken: '',
294
+ /** Paddle price IDs for subscription products */
295
+ paddlePriceIds: {
296
+ donate: '',
297
+ },
298
+ /** Sentry DSN for error tracking */
299
+ sentryDsn: '',
300
+ /** Upload source maps to Sentry on build */
301
+ sentSentrySourceMaps: false,
302
+ /** Gleap token for customer support widget */
303
+ gleapToken: '',
304
+ /** Google Maps API key */
305
+ googleMapsKey: '',
306
+ /** Matrix homeserver URL for chat integration */
307
+ matrixURL: 'https://matrix-client.matrix.org',
308
+
309
+ /******************************************************************************
310
+ * THEMING & UI
311
+ ******************************************************************************/
312
+
313
+ /** Primary theme color for PWA manifest and browser chrome */
314
+ themeColor: '#26262b',
315
+ /** Theme configuration for UI components */
316
+ theme: {
317
+ navigation: {
318
+ hasSidebarTextLabels: false,
319
+ sidebarWidthExpanded: '16rem',
320
+ sidebarWidthCollapsed: '4rem',
321
+ sheetPanelWidth: '20rem',
322
+ },
323
+ colors: {
324
+ rose: '#e11d48',
325
+ },
326
+ strokeWidth: 1.5,
327
+ screenSizes: {
328
+ xs: '420px',
329
+ sm: '640px',
330
+ md: '768px',
331
+ lg: '1024px',
332
+ xl: '1280px',
333
+ '2xl': '1400px',
334
+ },
335
+ } as const,
336
+ /** Placeholder background colors for avatars without images */
337
+ placeholderColors: [
338
+ 'bg-blue-300',
339
+ 'bg-lime-300',
340
+ 'bg-orange-300',
341
+ 'bg-yellow-300',
342
+ 'bg-green-300',
343
+ 'bg-teal-300',
344
+ 'bg-indigo-300',
345
+ 'bg-purple-300',
346
+ 'bg-pink-300',
347
+ 'bg-red-300',
348
+ ],
349
+
350
+ /******************************************************************************
351
+ * LOCALIZATION
352
+ ******************************************************************************/
353
+
354
+ /** Default language code */
355
+ defaultLanguage: 'en' as const,
356
+ /** Available language codes - first is fallback */
357
+ languages: ['en', 'nl'] as const,
358
+ /** Common reference data */
359
+ c: {
360
+ countries: ['fr', 'de', 'nl', 'ua', 'us', 'gb'],
361
+ timezones: [],
362
+ },
363
+
364
+ /******************************************************************************
365
+ * COMPANY DETAILS
366
+ ******************************************************************************/
367
+
368
+ /** Company/organization details for footer, legal pages, and contact info */
369
+ company: {
370
+ name: '__project_name__',
371
+ shortName: '__project_name__',
372
+ email: 'info@__project_slug__.example.com',
373
+ supportEmail: 'support@__project_slug__.example.com',
374
+ tel: '',
375
+ streetAddress: '',
376
+ postcode: '',
377
+ city: '',
378
+ country: '',
379
+ registration: '',
380
+ bankAccount: '',
381
+ googleMapsUrl: '',
382
+ scheduleCallUrl: '',
383
+ blueskyUrl: '',
384
+ blueskyHandle: '',
385
+ element: '',
386
+ githubUrl: '',
387
+ mapZoom: 4,
388
+ coordinates: {
389
+ lat: 0,
390
+ lng: 0,
391
+ },
392
+ },
393
+
394
+ /******************************************************************************
395
+ * USER DEFAULTS
396
+ ******************************************************************************/
397
+
398
+ /** Default user flags applied to new users */
399
+ defaultUserFlags: {
400
+ finishedOnboarding: false,
401
+ },
402
+ } satisfies RequiredConfig;
403
+
404
+ export default config;