@shop-on/create-theme 0.0.0-stage → 0.1.0
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/dist/LICENSE.md +39 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +40 -0
- package/dist/index.d.mts +32 -0
- package/dist/index.mjs +81 -0
- package/package.json +28 -3
- package/template/.claude/skills/react-best-practices/AGENTS.md +3663 -0
- package/template/.claude/skills/react-best-practices/LICENSE.md +26 -0
- package/template/.claude/skills/react-best-practices/SKILL.md +178 -0
- package/template/.claude/skills/react-best-practices/metadata.json +15 -0
- package/template/.claude/skills/react-best-practices/rules/_sections.md +56 -0
- package/template/.claude/skills/react-best-practices/rules/_template.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-effect-event-deps.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-init-once.md +42 -0
- package/template/.claude/skills/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/template/.claude/skills/react-best-practices/rules/async-api-routes.md +35 -0
- package/template/.claude/skills/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/template/.claude/skills/react-best-practices/rules/async-defer-await.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/async-dependencies.md +48 -0
- package/template/.claude/skills/react-best-practices/rules/async-parallel.md +24 -0
- package/template/.claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-conditional.md +37 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-defer-third-party.md +48 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +34 -0
- package/template/.claude/skills/react-best-practices/rules/bundle-preload.md +44 -0
- package/template/.claude/skills/react-best-practices/rules/client-event-listeners.md +78 -0
- package/template/.claude/skills/react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/template/.claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/template/.claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/template/.claude/skills/react-best-practices/rules/compose-compound-components.md +42 -0
- package/template/.claude/skills/react-best-practices/rules/compose-context-shared-state.md +80 -0
- package/template/.claude/skills/react-best-practices/rules/compose-extract-render-methods.md +55 -0
- package/template/.claude/skills/react-best-practices/rules/compose-transparent-props.md +65 -0
- package/template/.claude/skills/react-best-practices/rules/effect-chains.md +67 -0
- package/template/.claude/skills/react-best-practices/rules/effect-data-fetching.md +57 -0
- package/template/.claude/skills/react-best-practices/rules/effect-external-store.md +59 -0
- package/template/.claude/skills/react-best-practices/rules/effect-reset-state-with-key.md +41 -0
- package/template/.claude/skills/react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/js-cache-storage.md +68 -0
- package/template/.claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/template/.claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/js-flatmap-filter.md +51 -0
- package/template/.claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/template/.claude/skills/react-best-practices/rules/js-length-check-first.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/template/.claude/skills/react-best-practices/rules/js-request-idle-callback.md +104 -0
- package/template/.claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/template/.claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +72 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-hydration-suppress-warning.md +26 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/template/.claude/skills/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-no-inline-components.md +75 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/template/.claude/skills/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/template/.claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/template/.claude/skills/react-best-practices/rules/server-auth-actions.md +96 -0
- package/template/.claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/template/.claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/template/.claude/skills/react-best-practices/rules/server-dedup-props.md +65 -0
- package/template/.claude/skills/react-best-practices/rules/server-hoist-static-io.md +142 -0
- package/template/.claude/skills/react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/template/.claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/template/.claude/skills/react-best-practices/rules/server-parallel-nested-fetching.md +30 -0
- package/template/.claude/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/template/.claude/skills/react-start/LICENSE.md +25 -0
- package/template/.claude/skills/react-start/SKILL.md +282 -0
- package/template/.claude/skills/router-core/LICENSE.md +25 -0
- package/template/.claude/skills/router-core/SKILL.md +139 -0
- package/template/.claude/skills/router-core-auth-and-guards/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-auth-and-guards/SKILL.md +454 -0
- package/template/.claude/skills/router-core-code-splitting/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-code-splitting/SKILL.md +317 -0
- package/template/.claude/skills/router-core-data-loading/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-data-loading/SKILL.md +478 -0
- package/template/.claude/skills/router-core-navigation/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-navigation/SKILL.md +432 -0
- package/template/.claude/skills/router-core-not-found-and-errors/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-not-found-and-errors/SKILL.md +435 -0
- package/template/.claude/skills/router-core-path-params/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-path-params/SKILL.md +382 -0
- package/template/.claude/skills/router-core-search-params/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-search-params/SKILL.md +342 -0
- package/template/.claude/skills/router-core-ssr/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-ssr/SKILL.md +419 -0
- package/template/.claude/skills/router-core-type-safety/LICENSE.md +25 -0
- package/template/.claude/skills/router-core-type-safety/SKILL.md +485 -0
- package/template/.claude/skills/start-core/LICENSE.md +25 -0
- package/template/.claude/skills/start-core/SKILL.md +205 -0
- package/template/.claude/skills/start-core-execution-model/LICENSE.md +25 -0
- package/template/.claude/skills/start-core-execution-model/SKILL.md +298 -0
- package/template/.claude/skills/start-core-middleware/LICENSE.md +25 -0
- package/template/.claude/skills/start-core-middleware/SKILL.md +350 -0
- package/template/.claude/skills/start-core-server-functions/LICENSE.md +25 -0
- package/template/.claude/skills/start-core-server-functions/SKILL.md +331 -0
- package/template/.claude/skills/start-core-server-routes/LICENSE.md +25 -0
- package/template/.claude/skills/start-core-server-routes/SKILL.md +280 -0
- package/template/.claude/skills/start-server-core/LICENSE.md +25 -0
- package/template/.claude/skills/start-server-core/SKILL.md +252 -0
- package/template/.claude/skills/theme-dev/SKILL.md +285 -0
- package/template/.claude/skills/theme-dev/recipes/block.md +116 -0
- package/template/.claude/skills/theme-dev/recipes/concepts.md +114 -0
- package/template/.claude/skills/theme-dev/recipes/container-block.md +122 -0
- package/template/.claude/skills/theme-dev/recipes/customer-auth.md +92 -0
- package/template/.claude/skills/theme-dev/recipes/data-fetching.md +126 -0
- package/template/.claude/skills/theme-dev/recipes/dynamic-sources.md +251 -0
- package/template/.claude/skills/theme-dev/recipes/input-settings.md +549 -0
- package/template/.claude/skills/theme-dev/recipes/locales.md +146 -0
- package/template/.claude/skills/theme-dev/recipes/picker-data.md +181 -0
- package/template/.claude/skills/theme-dev/recipes/quality.md +150 -0
- package/template/.claude/skills/theme-dev/recipes/section-group.md +140 -0
- package/template/.claude/skills/theme-dev/recipes/section.md +164 -0
- package/template/.claude/skills/theme-dev/recipes/snippet.md +75 -0
- package/template/.claude/skills/theme-dev/recipes/static-block.md +143 -0
- package/template/.claude/skills/theme-dev/recipes/styling.md +225 -0
- package/template/.claude/skills/theme-dev/recipes/template.md +129 -0
- package/template/.env.example +9 -0
- package/template/.oxfmtrc.json +11 -0
- package/template/CLAUDE.md +13 -0
- package/template/LICENSE.md +39 -0
- package/template/README.md +82 -0
- package/template/_gitignore +17 -0
- package/template/package.json +52 -0
- package/template/release-notes.md +4 -0
- package/template/scripts/backfill-defaults.mjs +8 -0
- package/template/scripts/check-locales.mjs +4 -0
- package/template/scripts/postbuild.mjs +12 -0
- package/template/scripts/theme-check.mjs +4 -0
- package/template/src/assets/icons/arrow-right.svg +4 -0
- package/template/src/assets/rte.css +89 -0
- package/template/src/assets/theme.css +25 -0
- package/template/src/components/template-renderer.test.ts +33 -0
- package/template/src/components/template-renderer.tsx +59 -0
- package/template/src/config/settings-schema.json +21 -0
- package/template/src/layouts/empty.json +4 -0
- package/template/src/layouts/empty.tsx +8 -0
- package/template/src/layouts/main.json +7 -0
- package/template/src/layouts/main.tsx +24 -0
- package/template/src/lib/i18n.server.ts +36 -0
- package/template/src/lib/i18n.ts +39 -0
- package/template/src/lib/listing-search.ts +109 -0
- package/template/src/lib/seo-head.ts +12 -0
- package/template/src/lib/theme-events.test.ts +67 -0
- package/template/src/lib/theme-events.ts +68 -0
- package/template/src/lib/use-analytics.ts +163 -0
- package/template/src/locales/en.default.json +22 -0
- package/template/src/locales/en.default.schema.json +60 -0
- package/template/src/locales/mn.default.json +22 -0
- package/template/src/locales/mn.default.schema.json +60 -0
- package/template/src/route-adapter.tsx +75 -0
- package/template/src/routeTree.gen.ts +613 -0
- package/template/src/router.tsx +10 -0
- package/template/src/routes/__root.tsx +274 -0
- package/template/src/routes/analytics.events.tsx +21 -0
- package/template/src/routes/analytics.script.tsx +22 -0
- package/template/src/routes/analytics.visits.tsx +21 -0
- package/template/src/routes/customer_logout.tsx +26 -0
- package/template/src/routes/robots[.]txt.tsx +27 -0
- package/template/src/routes/sitemap[.]xml.tsx +20 -0
- package/template/src/routes/{-$locale}/404.tsx +15 -0
- package/template/src/routes/{-$locale}/account/index.tsx +12 -0
- package/template/src/routes/{-$locale}/account/login.tsx +14 -0
- package/template/src/routes/{-$locale}/account/orders.tsx +14 -0
- package/template/src/routes/{-$locale}/account/verify.tsx +14 -0
- package/template/src/routes/{-$locale}/blogs/$blogHandle.tsx +15 -0
- package/template/src/routes/{-$locale}/blogs/$blogHandle_/articles/$articleHandle.tsx +16 -0
- package/template/src/routes/{-$locale}/cart.tsx +15 -0
- package/template/src/routes/{-$locale}/collections/$collectionHandle.tsx +15 -0
- package/template/src/routes/{-$locale}/collections/$collectionHandle_/products/$handle.tsx +18 -0
- package/template/src/routes/{-$locale}/collections/index.tsx +15 -0
- package/template/src/routes/{-$locale}/index.tsx +15 -0
- package/template/src/routes/{-$locale}/pages/$handle.tsx +15 -0
- package/template/src/routes/{-$locale}/password.tsx +15 -0
- package/template/src/routes/{-$locale}/policies/$handle.tsx +15 -0
- package/template/src/routes/{-$locale}/preview/section.tsx +23 -0
- package/template/src/routes/{-$locale}/products/$handle.tsx +21 -0
- package/template/src/routes/{-$locale}/search.tsx +15 -0
- package/template/src/routes/{-$locale}.tsx +14 -0
- package/template/src/section-groups/footer-group.json +11 -0
- package/template/src/section-groups/header-group.json +11 -0
- package/template/src/sections/footer.json +14 -0
- package/template/src/sections/footer.tsx +13 -0
- package/template/src/sections/header.json +15 -0
- package/template/src/sections/header.tsx +41 -0
- package/template/src/sections/hero.json +27 -0
- package/template/src/sections/hero.tsx +45 -0
- package/template/src/sections/main-article.json +7 -0
- package/template/src/sections/main-article.tsx +41 -0
- package/template/src/sections/main-blog.json +14 -0
- package/template/src/sections/main-blog.tsx +46 -0
- package/template/src/sections/main-cart.json +7 -0
- package/template/src/sections/main-cart.tsx +32 -0
- package/template/src/sections/main-collection-list.json +14 -0
- package/template/src/sections/main-collection-list.tsx +42 -0
- package/template/src/sections/main-collection.json +7 -0
- package/template/src/sections/main-collection.test.tsx +86 -0
- package/template/src/sections/main-collection.tsx +53 -0
- package/template/src/sections/main-page.json +14 -0
- package/template/src/sections/main-page.tsx +39 -0
- package/template/src/sections/main-password.json +19 -0
- package/template/src/sections/main-password.tsx +44 -0
- package/template/src/sections/main-policy.json +7 -0
- package/template/src/sections/main-policy.tsx +36 -0
- package/template/src/sections/main-product.json +7 -0
- package/template/src/sections/main-product.tsx +54 -0
- package/template/src/sections/main-search.json +7 -0
- package/template/src/sections/main-search.tsx +62 -0
- package/template/src/server/customer.ts +48 -0
- package/template/src/server/enrich-adapter.ts +43 -0
- package/template/src/server/i18n.server.test.ts +22 -0
- package/template/src/server/i18n.server.ts +41 -0
- package/template/src/server/i18n.ts +14 -0
- package/template/src/server/settings.ts +210 -0
- package/template/src/server/template-loader.ts +36 -0
- package/template/src/server.ts +27 -0
- package/template/src/snippets/link.tsx +25 -0
- package/template/src/snippets/localized-link.tsx +30 -0
- package/template/src/snippets/product-card.tsx +33 -0
- package/template/src/start.ts +6 -0
- package/template/src/templates/404.json +6 -0
- package/template/src/templates/article.json +8 -0
- package/template/src/templates/blog.json +8 -0
- package/template/src/templates/cart.json +8 -0
- package/template/src/templates/collection.json +8 -0
- package/template/src/templates/index.json +11 -0
- package/template/src/templates/list-collections.json +8 -0
- package/template/src/templates/page.json +8 -0
- package/template/src/templates/password.json +8 -0
- package/template/src/templates/policy.json +8 -0
- package/template/src/templates/product.json +8 -0
- package/template/src/templates/search.json +8 -0
- package/template/test/prose-coverage.test.ts +12 -0
- package/template/theme.config.json +3 -0
- package/template/tsconfig.json +30 -0
- package/template/vite.config.ts +6 -0
- package/template/vitest.config.ts +3 -0
- package/README.md +0 -3
package/dist/LICENSE.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Cody Theme Development License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cody LLC. All rights reserved except as granted below.
|
|
4
|
+
|
|
5
|
+
"The Software" is this package, its source, and its documentation. "The
|
|
6
|
+
Platform" is Cody, the commerce platform operated by Cody LLC.
|
|
7
|
+
|
|
8
|
+
## 1. Grant
|
|
9
|
+
|
|
10
|
+
You may use, copy and modify the Software, and distribute modified copies, solely
|
|
11
|
+
to develop, test, and distribute themes, apps and other extensions that run on
|
|
12
|
+
the Platform.
|
|
13
|
+
|
|
14
|
+
## 2. Restrictions
|
|
15
|
+
|
|
16
|
+
You may not:
|
|
17
|
+
|
|
18
|
+
1. use the Software, or anything derived from it, with any commerce platform,
|
|
19
|
+
storefront or hosting service other than the Platform;
|
|
20
|
+
2. use the Software to build a product that competes with the Platform;
|
|
21
|
+
3. sublicense the Software, or distribute it other than as part of a theme,
|
|
22
|
+
app or extension for the Platform;
|
|
23
|
+
4. remove or alter this license or any copyright notice in the Software.
|
|
24
|
+
|
|
25
|
+
## 3. Your work
|
|
26
|
+
|
|
27
|
+
Themes, apps and extensions you build with the Software are yours. The parts of
|
|
28
|
+
the Software they include stay under this license.
|
|
29
|
+
|
|
30
|
+
## 4. Termination
|
|
31
|
+
|
|
32
|
+
This license ends automatically if you break any of its terms. You must then
|
|
33
|
+
stop using the Software and delete your copies of it.
|
|
34
|
+
|
|
35
|
+
## 5. No warranty
|
|
36
|
+
|
|
37
|
+
The Software is provided "as is", without warranty of any kind. Cody LLC is not
|
|
38
|
+
liable for any claim, damages or other liability arising from the Software or
|
|
39
|
+
its use.
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { packageManagerCommands, scaffoldTheme } from "./index.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
//#region src/cli.ts
|
|
5
|
+
const USAGE = "usage: npm create @shop-on/theme <dir>";
|
|
6
|
+
const dir = process.argv[2];
|
|
7
|
+
if (dir === "-h" || dir === "--help") {
|
|
8
|
+
console.log(USAGE);
|
|
9
|
+
process.exit(0);
|
|
10
|
+
}
|
|
11
|
+
if (!dir || dir.startsWith("-")) {
|
|
12
|
+
console.error(USAGE);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
let theme;
|
|
16
|
+
try {
|
|
17
|
+
theme = scaffoldTheme({ dir });
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error(error instanceof Error ? error.message : error);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const commands = packageManagerCommands(process.env.npm_config_user_agent);
|
|
23
|
+
const [install, dev] = [commands.install.join(" "), commands.dev.join(" ")];
|
|
24
|
+
const relative = path.relative(process.cwd(), theme.dir);
|
|
25
|
+
const steps = [
|
|
26
|
+
...relative ? [`cd ${/\s/.test(relative) ? JSON.stringify(relative) : relative}`] : [],
|
|
27
|
+
install,
|
|
28
|
+
"cp .env.example .env # then fill in your store's storefront credentials",
|
|
29
|
+
dev
|
|
30
|
+
];
|
|
31
|
+
console.log(`
|
|
32
|
+
Theme scaffolded in ${theme.dir}
|
|
33
|
+
|
|
34
|
+
Next:
|
|
35
|
+
${steps.map((step, i) => ` ${i + 1}. ${step}`).join("\n")}
|
|
36
|
+
|
|
37
|
+
Once the Shop-On CLI is published, \`shop-on theme init\` does all this and fills in .env for you.
|
|
38
|
+
`);
|
|
39
|
+
//#endregion
|
|
40
|
+
export {};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* `{ [name]: packedName }`: the files `npm pack` leaves out of a tarball, which
|
|
4
|
+
* `template/` stores renamed and `scaffoldTheme` restores.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PACKED_NAMES: Record<string, string>;
|
|
7
|
+
export type ScaffoldThemeResult = {
|
|
8
|
+
/** Absolute path of the new theme. */
|
|
9
|
+
dir: string;
|
|
10
|
+
/** The `name` written to its `package.json`: `dir`'s basename, slugified. */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Every file written, relative to `dir`, `/`-separated, sorted. */
|
|
13
|
+
files: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Copies the theme starter into `dir`, creating it if needed, and names the
|
|
17
|
+
* package after it. Throws if `dir` exists and holds anything but `.git`.
|
|
18
|
+
* Writes no `.env` and touches no network.
|
|
19
|
+
*/
|
|
20
|
+
export declare function scaffoldTheme({ dir }: {
|
|
21
|
+
dir: string;
|
|
22
|
+
}): ScaffoldThemeResult;
|
|
23
|
+
/**
|
|
24
|
+
* The install and dev commands of the package manager that ran this process,
|
|
25
|
+
* which `npm_config_user_agent` names (e.g. `pnpm/10.33.0 npm/? node/v24.0.0
|
|
26
|
+
* darwin arm64`). npm when it names none.
|
|
27
|
+
*/
|
|
28
|
+
export declare function packageManagerCommands(userAgent: string | undefined): {
|
|
29
|
+
install: string[];
|
|
30
|
+
dev: string[];
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
//#region src/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* `{ [name]: packedName }`: the files `npm pack` leaves out of a tarball, which
|
|
7
|
+
* `template/` stores renamed and `scaffoldTheme` restores.
|
|
8
|
+
*/
|
|
9
|
+
const PACKED_NAMES = { ".gitignore": "_gitignore" };
|
|
10
|
+
const RESTORED_NAMES = Object.fromEntries(Object.entries(PACKED_NAMES).map(([name, packed]) => [packed, name]));
|
|
11
|
+
const TEMPLATE = fileURLToPath(new URL("../template", import.meta.url));
|
|
12
|
+
const isEmptyDir = (dir) => fs.statSync(dir).isDirectory() && fs.readdirSync(dir).every((entry) => entry === ".git");
|
|
13
|
+
const toPackageName = (dir) => path.basename(dir).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "shop-on-theme";
|
|
14
|
+
/**
|
|
15
|
+
* Copies the theme starter into `dir`, creating it if needed, and names the
|
|
16
|
+
* package after it. Throws if `dir` exists and holds anything but `.git`.
|
|
17
|
+
* Writes no `.env` and touches no network.
|
|
18
|
+
*/
|
|
19
|
+
function scaffoldTheme({ dir }) {
|
|
20
|
+
const target = path.resolve(dir);
|
|
21
|
+
if (fs.existsSync(target) && !fs.statSync(target).isDirectory()) throw new Error(`${target} is a file, not a directory. Pick a new directory.`);
|
|
22
|
+
if (fs.existsSync(target) && !isEmptyDir(target)) throw new Error(`${target} is not empty. Pick a new directory, or empty this one first.`);
|
|
23
|
+
if (!fs.existsSync(TEMPLATE)) throw new Error(`${TEMPLATE} is missing. In the repo, run \`pnpm -C packages/create-theme template\`.`);
|
|
24
|
+
const files = [];
|
|
25
|
+
for (const entry of fs.readdirSync(TEMPLATE, {
|
|
26
|
+
recursive: true,
|
|
27
|
+
withFileTypes: true
|
|
28
|
+
})) {
|
|
29
|
+
if (!entry.isFile()) continue;
|
|
30
|
+
const relativeDir = path.relative(TEMPLATE, entry.parentPath);
|
|
31
|
+
const file = path.join(relativeDir, RESTORED_NAMES[entry.name] ?? entry.name);
|
|
32
|
+
fs.mkdirSync(path.join(target, relativeDir), { recursive: true });
|
|
33
|
+
fs.copyFileSync(path.join(entry.parentPath, entry.name), path.join(target, file));
|
|
34
|
+
files.push(file.split(path.sep).join("/"));
|
|
35
|
+
}
|
|
36
|
+
const name = toPackageName(target);
|
|
37
|
+
const manifestPath = path.join(target, "package.json");
|
|
38
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
39
|
+
manifest.name = name;
|
|
40
|
+
fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
41
|
+
return {
|
|
42
|
+
dir: target,
|
|
43
|
+
name,
|
|
44
|
+
files: files.sort()
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The install and dev commands of the package manager that ran this process,
|
|
49
|
+
* which `npm_config_user_agent` names (e.g. `pnpm/10.33.0 npm/? node/v24.0.0
|
|
50
|
+
* darwin arm64`). npm when it names none.
|
|
51
|
+
*/
|
|
52
|
+
function packageManagerCommands(userAgent) {
|
|
53
|
+
switch (userAgent?.split("/")[0]) {
|
|
54
|
+
case "pnpm": return {
|
|
55
|
+
install: ["pnpm", "install"],
|
|
56
|
+
dev: ["pnpm", "dev"]
|
|
57
|
+
};
|
|
58
|
+
case "yarn": return {
|
|
59
|
+
install: ["yarn"],
|
|
60
|
+
dev: ["yarn", "dev"]
|
|
61
|
+
};
|
|
62
|
+
case "bun": return {
|
|
63
|
+
install: ["bun", "install"],
|
|
64
|
+
dev: [
|
|
65
|
+
"bun",
|
|
66
|
+
"run",
|
|
67
|
+
"dev"
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
default: return {
|
|
71
|
+
install: ["npm", "install"],
|
|
72
|
+
dev: [
|
|
73
|
+
"npm",
|
|
74
|
+
"run",
|
|
75
|
+
"dev"
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { PACKED_NAMES, packageManagerCommands, scaffoldTheme };
|
package/package.json
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shop-on/create-theme",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scaffolds a Shop-On storefront theme: `npm create @shop-on/theme <dir>`.",
|
|
5
|
+
"license": "SEE LICENSE IN dist/LICENSE.md",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-theme": "./dist/cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"template"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./dist/index.mjs",
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "26.6.3",
|
|
20
|
+
"typescript": "7.0.2",
|
|
21
|
+
"vitest": "5.0.3"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"template": "node scripts/template.mts",
|
|
28
|
+
"check-types": "tsc --noEmit",
|
|
29
|
+
"test": "vitest run"
|
|
30
|
+
}
|
|
6
31
|
}
|