create-sprinkles 0.2.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.
Files changed (59) hide show
  1. package/dist/bin.mjs +295 -0
  2. package/dist/index.d.mts +46 -0
  3. package/dist/index.mjs +180 -0
  4. package/package.json +45 -0
  5. package/templates/react-router-convex/.env.local +2 -0
  6. package/templates/react-router-convex/convex/schema.ts +9 -0
  7. package/templates/react-router-rsc/app/home.tsx.hbs +31 -0
  8. package/templates/react-router-rsc/app/root.tsx.hbs +55 -0
  9. package/templates/react-router-rsc/tsconfig.json.hbs +31 -0
  10. package/templates/react-router-rsc/workers/entry.rsc.tsx +44 -0
  11. package/templates/react-router-rsc/workers/entry.ssr.tsx +41 -0
  12. package/templates/react-router-rsc/wrangler.rsc.jsonc.hbs +25 -0
  13. package/templates/react-router-rsc/wrangler.ssr.jsonc.hbs +14 -0
  14. package/templates/react-router-rsc-content-layer/app/content.config.ts.hbs +26 -0
  15. package/templates/react-router-rsc-content-layer/content-layer/api.ts +350 -0
  16. package/templates/react-router-rsc-content-layer/content-layer/codegen.ts +89 -0
  17. package/templates/react-router-rsc-content-layer/content-layer/config.ts +20 -0
  18. package/templates/react-router-rsc-content-layer/content-layer/digest.ts +6 -0
  19. package/templates/react-router-rsc-content-layer/content-layer/frontmatter.ts +19 -0
  20. package/templates/react-router-rsc-content-layer/content-layer/loaders/file.ts +55 -0
  21. package/templates/react-router-rsc-content-layer/content-layer/loaders/glob.ts +82 -0
  22. package/templates/react-router-rsc-content-layer/content-layer/loaders/index.ts +2 -0
  23. package/templates/react-router-rsc-content-layer/content-layer/plugin.ts +419 -0
  24. package/templates/react-router-rsc-content-layer/content-layer/resolve-hook.js +12 -0
  25. package/templates/react-router-rsc-content-layer/content-layer/runtime.ts +73 -0
  26. package/templates/react-router-rsc-content-layer/content-layer/store.ts +59 -0
  27. package/templates/react-router-spa/app/home.tsx.hbs +7 -0
  28. package/templates/react-router-spa/app/root.tsx.hbs +60 -0
  29. package/templates/react-router-spa/tsconfig.json.hbs +26 -0
  30. package/templates/react-router-spa/wrangler.jsonc.hbs +9 -0
  31. package/templates/react-router-ssr/app/home.tsx.hbs +21 -0
  32. package/templates/react-router-ssr/app/root.tsx.hbs +105 -0
  33. package/templates/react-router-ssr/convex/schema.ts +7 -0
  34. package/templates/react-router-ssr/tsconfig.json.hbs +28 -0
  35. package/templates/react-router-ssr/wrangler.jsonc.hbs +13 -0
  36. package/templates/react-router-ssr-convex/app/lib/client.ts +19 -0
  37. package/templates/react-router-ssr-convex/app/tanstack-query-integration/middleware.ts +18 -0
  38. package/templates/react-router-ssr-convex/app/tanstack-query-integration/query-preloader.ts +125 -0
  39. package/templates/react-shared/app/routes.ts.hbs +3 -0
  40. package/templates/react-shared/app/styles/tailwind.css +1 -0
  41. package/templates/react-shared/react-compiler.plugin.ts.hbs +10 -0
  42. package/templates/react-shared/react-router.config.ts.hbs +9 -0
  43. package/templates/shared/.gitignore.hbs +23 -0
  44. package/templates/shared/.node-version +1 -0
  45. package/templates/shared/.vscode/extensions.json.hbs +8 -0
  46. package/templates/shared/.vscode/settings.json.hbs +72 -0
  47. package/templates/shared/AGENTS.md.hbs +599 -0
  48. package/templates/shared/README.md.hbs +24 -0
  49. package/templates/shared/package.json.hbs +41 -0
  50. package/templates/shared/vite.config.ts.hbs +384 -0
  51. package/templates/ts-package/src/index.ts +3 -0
  52. package/templates/ts-package/tests/index.test.ts +9 -0
  53. package/templates/ts-package/tsconfig.json +18 -0
  54. package/templates/ts-package-cli/bin/index.ts.hbs +1 -0
  55. package/templates/ts-package-cli/src/cli.ts.hbs +37 -0
  56. package/templates/ts-package-generator/bin/create.ts.hbs +2 -0
  57. package/templates/ts-package-generator/src/template.ts.hbs +22 -0
  58. package/templates/ts-package-sea/sea-config.json.hbs +2 -0
  59. package/templates/ts-package-sea/src/sea-entry.ts.hbs +4 -0
@@ -0,0 +1,384 @@
1
+ {{#if isRSC}}
2
+ import { cloudflare } from "@cloudflare/vite-plugin";
3
+ {{#if hasContentLayer}}
4
+ import mdx from "@mdx-js/rollup";
5
+ {{/if}}
6
+ import { unstable_reactRouterRSC as reactRouter } from "@react-router/dev/vite";
7
+ import tailwindcss from "@tailwindcss/vite";
8
+ import rsc from "@vitejs/plugin-rsc";
9
+ import devtoolsJson from "vite-plugin-devtools-json";
10
+ import { defineConfig } from "vite-plus";
11
+
12
+ {{#if hasContentLayer}}
13
+ import { contentLayer } from "./content-layer/plugin.ts";
14
+ {{/if}}
15
+ import { reactCompiler } from "./react-compiler.plugin.ts";
16
+ {{else if isReactRouter}}
17
+ import { cloudflare } from "@cloudflare/vite-plugin";
18
+ import { reactRouter } from "@react-router/dev/vite";
19
+ import tailwindcss from "@tailwindcss/vite";
20
+ import devtoolsJson from "vite-plugin-devtools-json";
21
+ import { defineConfig } from "vite-plus";
22
+
23
+ import { reactCompiler } from "./react-compiler.plugin.ts";
24
+ {{else}}
25
+ import { defineConfig } from "vite-plus";
26
+ {{/if}}
27
+
28
+ {{#if isReactRouter}}
29
+ const IS_TEST = Boolean(process.env.VITEST);
30
+
31
+ {{/if}}
32
+ export default defineConfig({
33
+ {{#if isRSC}}
34
+ css: {
35
+ transformer: "lightningcss",
36
+ },
37
+ environments: {
38
+ client: {
39
+ optimizeDeps: {
40
+ include: [
41
+ "react-router",
42
+ "react-router/dom",
43
+ "react-router/internal/react-server-client",
44
+ ],
45
+ },
46
+ },
47
+ rsc: {
48
+ optimizeDeps: {
49
+ exclude: ["react-router"],
50
+ },
51
+ resolve: {
52
+ conditions: ["react-server"],
53
+ },
54
+ },
55
+ ssr: {
56
+ optimizeDeps: {
57
+ exclude: ["react-router"],
58
+ },
59
+ },
60
+ },
61
+ {{/if}}
62
+ fmt: {
63
+ arrowParens: "avoid",
64
+ overrides: [
65
+ {
66
+ files: ["**/*.jsonc"],
67
+ options: {
68
+ trailingComma: "none",
69
+ },
70
+ },
71
+ {
72
+ files: ["**/.vscode/**"],
73
+ options: {
74
+ trailingComma: "all",
75
+ },
76
+ },
77
+ ],
78
+ sortImports: {
79
+ groups: [
80
+ "type-import",
81
+ ["value-builtin", "value-external"],
82
+ "type-internal",
83
+ "value-internal",
84
+ ["type-parent", "type-sibling", "type-index"],
85
+ ["value-parent", "value-sibling", "value-index"],
86
+ "unknown",
87
+ ],
88
+ partitionByComment: true,
89
+ },
90
+ {{#if isReactRouter}}
91
+ sortTailwindcss: {
92
+ functions: ["cx", "cva"],
93
+ stylesheet: "./app/styles/tailwind.css",
94
+ },
95
+ {{/if}}
96
+ tabWidth: 4,
97
+ },
98
+ lint: {
99
+ categories: {
100
+ correctness: "error",
101
+ suspicious: "error",
102
+ },
103
+ env: {
104
+ {{#if isReactRouter}}
105
+ browser: true,
106
+ {{/if}}
107
+ node: true,
108
+ },
109
+ {{#if isRSC}}
110
+ ignorePatterns: ["**/worker-configuration.d.ts"],
111
+ {{/if}}
112
+ {{#if isReactRouter}}
113
+ jsPlugins: [
114
+ "eslint-plugin-perfectionist",
115
+ { name: "react-compiler", specifier: "eslint-plugin-react-hooks" },
116
+ ],
117
+ {{/if}}
118
+ options: {
119
+ typeAware: true,
120
+ typeCheck: true,
121
+ },
122
+ {{#if isReactRouter}}
123
+ plugins: ["react", "jsx-a11y", "jsdoc", "import", "node", "promise", "vitest"],
124
+ {{else}}
125
+ plugins: ["jsdoc", "import", "node", "promise", "vitest"],
126
+ {{/if}}
127
+ rules: {
128
+ "eslint/default-param-last": "error",
129
+ "eslint/func-style": ["error", "declaration"],
130
+ "eslint/id-length": "off",
131
+ "eslint/init-declarations": "off",
132
+ "eslint/max-lines": "off",
133
+ "eslint/max-lines-per-function": "off",
134
+ "eslint/max-statements": "off",
135
+ "eslint/capitalized-comments": "off",
136
+ "eslint/no-cond-assign": "off",
137
+ "eslint/no-continue": "off",
138
+ "eslint/no-dupe-else-if": "error",
139
+ "eslint/no-duplicate-imports": "off",
140
+ "eslint/no-else-return": "error",
141
+ "eslint/no-empty-pattern": "warn",
142
+ "eslint/no-irregular-whitespace": "error",
143
+ "eslint/no-lonely-if": "warn",
144
+ "eslint/no-magic-numbers": "off",
145
+ "eslint/no-param-reassign": "error",
146
+ "eslint/no-shadow": "off",
147
+ "eslint/no-template-curly-in-string": "warn",
148
+ "eslint/no-ternary": "off",
149
+ "eslint/no-undefined": "off",
150
+ "eslint/no-unused-expressions": "error",
151
+ "eslint/no-warning-comments": "off",
152
+ "eslint/no-unused-vars": "off",
153
+ "eslint/no-useless-escape": "warn",
154
+ "eslint/require-await": "off",
155
+ "eslint/sort-imports": "off",
156
+ "eslint/sort-keys": "off",
157
+
158
+ "import/extensions": [
159
+ "error",
160
+ "ignorePackages",
161
+ {
162
+ cjs: "always",
163
+ cts: "always",
164
+ js: "always",
165
+ jsx: "always",
166
+ mjs: "always",
167
+ mts: "always",
168
+ ts: "always",
169
+ tsx: "always",
170
+ },
171
+ ],
172
+ "import/exports-last": "off",
173
+ "import/group-exports": "off",
174
+ "import/no-commonjs": "warn",
175
+ "import/no-default-export": "off",
176
+ "import/no-named-export": "off",
177
+ "import/no-nodejs-modules": "off",
178
+ "import/no-relative-parent-imports": "off",
179
+ "import/prefer-default-export": "off",
180
+
181
+ {{#if isReactRouter}}
182
+ "jest/require-hook": "off",
183
+
184
+ "jsx-a11y/no-autofocus": "off",
185
+
186
+ "node/no-process-env": "off",
187
+
188
+ "perfectionist/sort-jsx-props": "warn",
189
+ "react-compiler/component-hook-factories": "error",
190
+ "react-compiler/error-boundaries": "error",
191
+ "react-compiler/globals": "error",
192
+ "react-compiler/immutability": "error",
193
+ "react-compiler/incompatible-library": "error",
194
+ "react-compiler/preserve-manual-memoization": "error",
195
+ "react-compiler/purity": "error",
196
+ "react-compiler/refs": "error",
197
+ "react-compiler/set-state-in-effect": "error",
198
+ "react-compiler/set-state-in-render": "error",
199
+ "react-compiler/static-components": "error",
200
+ "react-compiler/unsupported-syntax": "error",
201
+ "react-compiler/use-memo": "error",
202
+ "react/exhaustive-deps": "warn",
203
+ "react/jsx-boolean-value": "warn",
204
+ "react/jsx-filename-extension": "off",
205
+ "react/jsx-max-depth": "off",
206
+ "react/jsx-fragments": "warn",
207
+ "react/jsx-key": "error",
208
+ "react/jsx-no-constructed-context-values": "error",
209
+ "react/jsx-no-duplicate-props": "error",
210
+ "react/jsx-no-script-url": "error",
211
+ "react/jsx-no-target-blank": "warn",
212
+ "react/jsx-no-useless-fragment": "warn",
213
+ "react/jsx-pascal-case": "error",
214
+ "react/jsx-props-no-spread-multi": "error",
215
+ "react/no-array-index-key": "off",
216
+ "react/no-multi-comp": "off",
217
+ "react/react-in-jsx-scope": "off",
218
+ "react/only-export-components": [
219
+ "error",
220
+ {
221
+ allowExportNames: [
222
+ "meta",
223
+ "links",
224
+ "headers",
225
+ "loader",
226
+ "action",
227
+ "clientLoader",
228
+ "clientAction",
229
+ "middleware",
230
+ "shouldRevalidate",
231
+ "handle",
232
+ ],
233
+ },
234
+ ],
235
+ "react/rules-of-hooks": "error",
236
+ "react/self-closing-comp": "error",
237
+
238
+ {{/if}}
239
+ "typescript/consistent-type-imports": "error",
240
+ "typescript/no-empty-interface": "warn",
241
+ "typescript/no-explicit-any": "warn",
242
+ "typescript/no-inferrable-types": "error",
243
+ "typescript/no-non-null-assertion": "warn",
244
+ "typescript/prefer-as-const": "error",
245
+ "typescript/prefer-enum-initializers": "error",
246
+
247
+ "unicorn/no-lonely-if": "warn",
248
+ "unicorn/prefer-at": "warn",
249
+ "unicorn/prefer-string-slice": "warn",
250
+ "unicorn/prefer-string-trim-start-end": "error",
251
+ },
252
+ settings: {
253
+ {{#if isReactRouter}}
254
+ "jsx-a11y": {
255
+ components: {
256
+ Link: "a",
257
+ NavLink: "a",
258
+ },
259
+ polymorphicPropName: "as",
260
+ },
261
+ react: {
262
+ formComponents: ["Form"],
263
+ linkComponents: [
264
+ "DirectoryLink",
265
+ { attribute: "to", name: "Link" },
266
+ { attribute: "to", name: "NavLink" },
267
+ ],
268
+ },
269
+ {{/if}}
270
+ vitest: {
271
+ typecheck: true,
272
+ },
273
+ },
274
+ },
275
+ {{#if isPackage}}
276
+ pack: {
277
+ dts: {
278
+ tsgo: true,
279
+ },
280
+ exports: true,
281
+ },
282
+ {{/if}}
283
+ {{#if isRSC}}
284
+ plugins: [
285
+ {{#if hasContentLayer}}
286
+ contentLayer(),
287
+ mdx(),
288
+ {{/if}}
289
+ reactRouter(),
290
+ rsc(),
291
+ reactCompiler(),
292
+ !IS_TEST &&
293
+ cloudflare({
294
+ auxiliaryWorkers: [
295
+ {
296
+ configPath: "./wrangler.rsc.jsonc",
297
+ viteEnvironment: {
298
+ name: "rsc",
299
+ },
300
+ },
301
+ ],
302
+ configPath: "./wrangler.ssr.jsonc",
303
+ viteEnvironment: {
304
+ name: "ssr",
305
+ },
306
+ }),
307
+ tailwindcss(),
308
+ devtoolsJson(),
309
+ ],
310
+ {{else if isSSR}}
311
+ plugins: [
312
+ tailwindcss(),
313
+ reactRouter(),
314
+ reactCompiler(),
315
+ !IS_TEST &&
316
+ cloudflare({
317
+ configPath: "./wrangler.jsonc",
318
+ viteEnvironment: {
319
+ name: "ssr",
320
+ },
321
+ }),
322
+ devtoolsJson(),
323
+ ],
324
+ {{else if isSPA}}
325
+ plugins: [
326
+ tailwindcss(),
327
+ reactRouter(),
328
+ reactCompiler(),
329
+ !IS_TEST && cloudflare(),
330
+ devtoolsJson(),
331
+ ],
332
+ {{/if}}
333
+ {{#if isReactRouter}}
334
+ resolve: {
335
+ tsconfigPaths: true,
336
+ },
337
+ {{/if}}
338
+ run: {
339
+ tasks: {
340
+ {{#if isRSC}}
341
+ deploy: {
342
+ cache: false,
343
+ command: "vp build && wrangler deploy",
344
+ },
345
+ typecheck: {
346
+ command: "tsgo --noEmit",
347
+ dependsOn: ["typegen:react-router", "typegen:cloudflare"],
348
+ },
349
+ "typegen:cloudflare": {
350
+ command: "wrangler types -c wrangler.rsc.jsonc",
351
+ },
352
+ "typegen:react-router": {
353
+ command: "react-router typegen",
354
+ },
355
+ {{else if isReactRouter}}
356
+ deploy: {
357
+ cache: false,
358
+ command: "vp build && wrangler deploy",
359
+ },
360
+ typecheck: {
361
+ command: "tsgo --noEmit",
362
+ dependsOn: ["typegen:react-router"],
363
+ },
364
+ "typegen:react-router": {
365
+ command: "react-router typegen",
366
+ },
367
+ {{else}}
368
+ build: { command: "vp pack" },
369
+ dev: { command: "vp pack --watch" },
370
+ typecheck: { command: "tsgo --noEmit" },
371
+ {{/if}}
372
+ },
373
+ },
374
+ staged: {
375
+ "*": "vp check --fix",
376
+ },
377
+ test: {
378
+ {{#if isReactRouter}}
379
+ include: ["**/*.test.ts"],
380
+ {{else}}
381
+ exclude: [".claude/**", "node_modules/**"],
382
+ {{/if}}
383
+ },
384
+ });
@@ -0,0 +1,3 @@
1
+ export function greet(name: string): string {
2
+ return `Hello, ${name}!`;
3
+ }
@@ -0,0 +1,9 @@
1
+ import { describe, expect, it } from "vite-plus/test";
2
+
3
+ import { greet } from "../src/index.ts";
4
+
5
+ describe("greet", () => {
6
+ it("should return a greeting", () => {
7
+ expect(greet("world")).toBe("Hello, world!");
8
+ });
9
+ });
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "isolatedModules": true,
10
+ "declaration": true,
11
+ "declarationMap": true,
12
+ "sourceMap": true,
13
+ "outDir": "./dist",
14
+ "rootDir": "./src"
15
+ },
16
+ "include": ["src"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node import { cli } from "../src/cli.ts"; cli();
@@ -0,0 +1,37 @@
1
+ import { args } from "@bomb.sh/args";
2
+
3
+ export function cli(): void {
4
+ const { positionals, values } = args({
5
+ allowPositionals: true,
6
+ options: {
7
+ help: {
8
+ short: "h",
9
+ type: "boolean",
10
+ default: false,
11
+ description: "Show help",
12
+ },
13
+ version: {
14
+ short: "v",
15
+ type: "boolean",
16
+ default: false,
17
+ description: "Show version",
18
+ },
19
+ },
20
+ });
21
+
22
+ if (values.version) {
23
+ console.log("0.1.0");
24
+ return;
25
+ }
26
+
27
+ if (values.help || positionals.length === 0) {
28
+ console.log(`Usage: {{repository}} [options] <command>`);
29
+ console.log();
30
+ console.log("Options:");
31
+ console.log(" -h, --help Show help");
32
+ console.log(" -v, --version Show version");
33
+ return;
34
+ }
35
+
36
+ console.log(`Running {{repository}} with args:`, positionals);
37
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node import { runTemplateCLI } from "bingo"; import template from
2
+ "../src/template.ts"; await runTemplateCLI(template);
@@ -0,0 +1,22 @@
1
+ import { createTemplate } from "bingo";
2
+ import { handlebars } from "bingo-handlebars";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+
6
+ const templatesDir = path.join(import.meta.dirname, "../templates");
7
+
8
+ const options = {
9
+ name: z.string().describe("Project name"),
10
+ };
11
+
12
+ export default createTemplate({
13
+ about: {
14
+ description: "Scaffold a new project with {{repository}}.",
15
+ name: "@{{owner}}/{{repository}}",
16
+ },
17
+ options,
18
+ async produce({ options: opts }) {
19
+ const files = await handlebars(path.join(templatesDir, "default"), opts);
20
+ return { files };
21
+ },
22
+ });
@@ -0,0 +1,2 @@
1
+ { "main": "dist/sea-entry.mjs", "output": "sea-prep.blob", "disableExperimentalSEAWarning": true,
2
+ "useSnapshot": false, "useCodeCache": true }
@@ -0,0 +1,4 @@
1
+ /** * Single Executable Application entry point. * * This file is the main entry for the SEA build.
2
+ It will be bundled * into a single file and embedded into the Node.js binary. * * @see
3
+ https://nodejs.org/api/single-executable-applications.html */ import { greet } from "./index.ts";
4
+ const name = process.argv[2] ?? "world"; console.log(greet(name));