create-odori 0.0.2 → 0.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-odori",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "description": "Scaffold a odori video project.",
6
6
  "license": "Apache-2.0",
@@ -21,7 +21,7 @@
21
21
  "devDependencies": {
22
22
  "@types/node": "22.19.0",
23
23
  "typescript": "5.9.3",
24
- "@odori/registry": "0.0.2"
24
+ "@odori/registry": "0.0.4"
25
25
  },
26
26
  "scripts": {
27
27
  "typecheck": "tsc --noEmit",
package/src/index.ts CHANGED
@@ -1,18 +1,33 @@
1
- import {cp, mkdir, readFile, readdir, writeFile} from "node:fs/promises";
1
+ import {cp, mkdir, readFile, readdir, rename, writeFile} from "node:fs/promises";
2
2
  import {existsSync} from "node:fs";
3
3
  import {dirname, join, resolve} from "node:path";
4
4
  import {fileURLToPath} from "node:url";
5
5
 
6
6
  const templateRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "template");
7
7
 
8
+ /**
9
+ * What a directory can hold and still count as empty.
10
+ *
11
+ * The usual first move is to create the repository on GitHub, clone it, and
12
+ * scaffold into the clone — at which point the directory holds a `.git` the
13
+ * scaffolder did not put there. Refusing that is refusing the common path.
14
+ */
15
+ const NOT_CONTENT = new Set([".git", ".DS_Store"]);
16
+
8
17
  export const createProject = async (target: string, options: {name?: string} = {}) => {
9
18
  const root = resolve(process.cwd(), target);
10
- if (existsSync(root) && (await readdir(root)).length > 0) {
19
+ if (existsSync(root) && (await readdir(root)).some((entry) => !NOT_CONTENT.has(entry))) {
11
20
  throw new Error(`${root} already exists and is not empty.`);
12
21
  }
13
22
  await mkdir(root, {recursive: true});
14
23
  await cp(templateRoot, root, {recursive: true});
15
24
 
25
+ // npm drops files named `.gitignore` from a published tarball, without
26
+ // saying so. The template therefore carries the undotted name and the dot is
27
+ // restored here; otherwise every project scaffolded from a release starts
28
+ // with no ignore file and commits `node_modules/`, `out/`, and `.odori/`.
29
+ await rename(join(root, "gitignore"), join(root, ".gitignore"));
30
+
16
31
  const packageFile = join(root, "package.json");
17
32
  const contents = (await readFile(packageFile, "utf8")).replace(
18
33
  "PROJECT_NAME",
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ .odori
3
+ out
@@ -12,10 +12,10 @@
12
12
  "dependencies": {
13
13
  "react": "19.2.3",
14
14
  "react-dom": "19.2.3",
15
- "odori": "^0.0.2"
15
+ "odori": "^0.0.4"
16
16
  },
17
17
  "devDependencies": {
18
- "@odori/cli": "^0.0.2",
18
+ "@odori/cli": "^0.0.4",
19
19
  "@types/react": "19.2.7",
20
20
  "typescript": "5.9.3"
21
21
  }
@@ -3,7 +3,7 @@ import {EndCard} from "./end-card";
3
3
 
4
4
  export default defineComponentPreview({
5
5
  title: "End card",
6
- category: "Brand",
6
+ category: "Narrative",
7
7
  description: "The closing frame: title, supporting line, and a call to action.",
8
8
  component: EndCard,
9
9
  canvas: {width: 1920, height: 1080, duration: "3s"},
@@ -3,7 +3,7 @@ import {TitleReveal} from "./title-reveal";
3
3
 
4
4
  export default defineComponentPreview({
5
5
  title: "Title reveal",
6
- category: "Typography",
6
+ category: "Typography/Titles",
7
7
  description: "A staggered, word-masked headline.",
8
8
  component: TitleReveal,
9
9
  canvas: {width: 1920, height: 1080, duration: "4s"},
@@ -12,7 +12,7 @@ export const productBrand = defineBrand({
12
12
  },
13
13
  /**
14
14
  * Sounds are named here, not in a composition, so re-scoring every video is
15
- * one edit. The block starts empty on purpose: `odori add @odori/bed-pulse`
15
+ * one edit. The block starts empty on purpose: `odori add bed-pulse`
16
16
  * writes into it, and without somewhere to write it can only print the two
17
17
  * lines and ask you to paste them.
18
18
  */