@pro-laico/payload-seed 0.0.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.
Files changed (71) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +9 -0
  3. package/dist/bin/seed.d.ts +9 -0
  4. package/dist/bin/seed.d.ts.map +1 -0
  5. package/dist/bin/seed.js +36 -0
  6. package/dist/bin/seed.js.map +1 -0
  7. package/dist/components/SeedButton.d.ts +11 -0
  8. package/dist/components/SeedButton.d.ts.map +1 -0
  9. package/dist/components/SeedButton.js +82 -0
  10. package/dist/components/SeedButton.js.map +1 -0
  11. package/dist/defineSeed.d.ts +43 -0
  12. package/dist/defineSeed.d.ts.map +1 -0
  13. package/dist/defineSeed.js +51 -0
  14. package/dist/defineSeed.js.map +1 -0
  15. package/dist/endpoint.d.ts +10 -0
  16. package/dist/endpoint.d.ts.map +1 -0
  17. package/dist/endpoint.js +60 -0
  18. package/dist/endpoint.js.map +1 -0
  19. package/dist/engine/files.d.ts +15 -0
  20. package/dist/engine/files.d.ts.map +1 -0
  21. package/dist/engine/files.js +72 -0
  22. package/dist/engine/files.js.map +1 -0
  23. package/dist/engine/graph.d.ts +61 -0
  24. package/dist/engine/graph.d.ts.map +1 -0
  25. package/dist/engine/graph.js +0 -0
  26. package/dist/engine/graph.js.map +1 -0
  27. package/dist/engine/run.d.ts +46 -0
  28. package/dist/engine/run.d.ts.map +1 -0
  29. package/dist/engine/run.js +387 -0
  30. package/dist/engine/run.js.map +1 -0
  31. package/dist/engine/tokens.d.ts +16 -0
  32. package/dist/engine/tokens.d.ts.map +1 -0
  33. package/dist/engine/tokens.js +37 -0
  34. package/dist/engine/tokens.js.map +1 -0
  35. package/dist/engine/validate.d.ts +28 -0
  36. package/dist/engine/validate.d.ts.map +1 -0
  37. package/dist/engine/validate.js +79 -0
  38. package/dist/engine/validate.js.map +1 -0
  39. package/dist/guard.d.ts +11 -0
  40. package/dist/guard.d.ts.map +1 -0
  41. package/dist/guard.js +11 -0
  42. package/dist/guard.js.map +1 -0
  43. package/dist/index.d.ts +9 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +13 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/options.d.ts +29 -0
  48. package/dist/options.d.ts.map +1 -0
  49. package/dist/options.js +10 -0
  50. package/dist/options.js.map +1 -0
  51. package/dist/plugin.d.ts +14 -0
  52. package/dist/plugin.d.ts.map +1 -0
  53. package/dist/plugin.js +73 -0
  54. package/dist/plugin.js.map +1 -0
  55. package/dist/refs.d.ts +56 -0
  56. package/dist/refs.d.ts.map +1 -0
  57. package/dist/refs.js +39 -0
  58. package/dist/refs.js.map +1 -0
  59. package/dist/registry.d.ts +31 -0
  60. package/dist/registry.d.ts.map +1 -0
  61. package/dist/registry.js +20 -0
  62. package/dist/registry.js.map +1 -0
  63. package/dist/typegen.d.ts +13 -0
  64. package/dist/typegen.d.ts.map +1 -0
  65. package/dist/typegen.js +40 -0
  66. package/dist/typegen.js.map +1 -0
  67. package/dist/types.d.ts +81 -0
  68. package/dist/types.d.ts.map +1 -0
  69. package/dist/types.js +3 -0
  70. package/dist/types.js.map +1 -0
  71. package/package.json +70 -0
@@ -0,0 +1,81 @@
1
+ import type { CollectionSlug, DataFromGlobalSlug, GlobalSlug, RequiredDataFromCollectionSlug } from 'payload';
2
+ import type { file, FileToken, ref, Ref } from './refs';
3
+ /**
4
+ * Recursively widens a generated Payload data type so a {@link Ref} may appear at any object
5
+ * field or array element — that's how relationship values are supplied as tokens instead of ids.
6
+ * The shape (field names, required-ness) is still enforced, so changing a collection's schema still
7
+ * surfaces a TS error in its seed file. Files aren't widened in here — they go on the record's
8
+ * `_file` meta-key, not in a data field. Intentionally permissive at the leaf for v1: the runtime
9
+ * validator checks that each ref actually lands in a field whose config allows it.
10
+ */
11
+ export type WithRefs<T> = T extends Ref ? T : T extends Date ? T : T extends (infer U)[] ? Array<WithRefs<U> | Ref> : T extends object ? {
12
+ [K in keyof T]: WithRefs<T[K]> | Ref;
13
+ } : T;
14
+ /** A single collection seed record: the collection's create-data, a local `_key` reference
15
+ * handle, and an optional `_file` attaching a source file (for upload / provider collections). */
16
+ export type CollectionSeedData<TSlug extends CollectionSlug> = WithRefs<RequiredDataFromCollectionSlug<TSlug>> & {
17
+ _key: string;
18
+ _file?: FileToken;
19
+ };
20
+ /** A global's seed data (globals are singletons — no `_key`). The generated global type
21
+ * carries `id`/`globalType`/timestamps that `updateGlobal` doesn't accept as input, so
22
+ * they're stripped here. */
23
+ export type GlobalSeedData<TSlug extends GlobalSlug> = WithRefs<Omit<DataFromGlobalSlug<TSlug>, 'id' | 'globalType' | 'createdAt' | 'updatedAt'>>;
24
+ /** Tokens handed to every seed builder: `ref` (point at another seeded doc) and `file`
25
+ * (attach a source file to an upload/provider doc via its `_file`). */
26
+ export interface SeedTokens {
27
+ ref: typeof ref;
28
+ file: typeof file;
29
+ }
30
+ /**
31
+ * A collection's `custom.seedAsset` marker: declares a collection whose `_file` bytes are ingested
32
+ * by the collection's own hook rather than stored as a Payload upload — e.g. `@pro-laico/payload-mux`'s
33
+ * `mux-video` (uploaded to Mux). Set on the collection config:
34
+ *
35
+ * { slug: 'mux-video', custom: { seedAsset: { sourceField: 'source' } }, ... }
36
+ *
37
+ * Instead of uploading bytes, the seed engine resolves the `_file` under `subdir` and sets it as
38
+ * `{ file, ...options }` on the doc's `sourceField`, for the collection's ingest hook to consume.
39
+ * `true` is shorthand for the defaults (`sourceField: 'source'`, `subdir`: the collection slug).
40
+ * Plain config — no import of the seed package needed, so the owning plugin stays decoupled from it.
41
+ */
42
+ export type SeedAssetMarker = true | {
43
+ /** Doc field the engine sets to `{ file, ...options }` for the ingest hook. @default 'source' */
44
+ sourceField?: string;
45
+ /** Subdirectory under the assets dir holding the source files. @default the collection slug */
46
+ subdir?: string;
47
+ };
48
+ /**
49
+ * A collection's `custom.seedDisabled` marker: declares that the collection cannot be seeded right
50
+ * now (typically missing credentials), set by the owning plugin from its own config/env:
51
+ *
52
+ * { slug: 'mux-video', custom: { seedDisabled: 'Mux credentials not set (MUX_TOKEN_ID / MUX_TOKEN_SECRET)' } }
53
+ *
54
+ * The engine skips the collection's definition at runtime with a warning (a string is used as the
55
+ * reason) and drops any optional field whose `ref()` points at it — a required ref is a hard error.
56
+ * Because the definition stays registered, the generated seed-ref types don't change with the
57
+ * environment; set the env vars and the next run seeds it, nothing else to touch. Plain config —
58
+ * no import of the seed package needed, so the owning plugin stays decoupled from it.
59
+ */
60
+ export type SeedDisabledMarker = boolean | string;
61
+ /** A seed builder receives the ref/file tokens and returns the seed data. Deferred
62
+ * (not eager data) so refs resolve against the full definition set. */
63
+ export type SeedBuilder<T> = (tokens: SeedTokens) => T;
64
+ export interface CollectionSeedDefinition<TSlug extends CollectionSlug = CollectionSlug> {
65
+ readonly kind: 'collection';
66
+ readonly slug: TSlug;
67
+ readonly build: SeedBuilder<Array<CollectionSeedData<TSlug>>>;
68
+ /** Skip this definition at seed time (a string is used as the warning's reason). The definition
69
+ * still contributes to the generated seed-ref types, so gating it doesn't shift types. Also set
70
+ * automatically when the target collection declares `custom.seedDisabled`. */
71
+ readonly disabled?: SeedDisabledMarker;
72
+ }
73
+ export interface GlobalSeedDefinition<TSlug extends GlobalSlug = GlobalSlug> {
74
+ readonly kind: 'global';
75
+ readonly slug: TSlug;
76
+ readonly build: SeedBuilder<GlobalSeedData<TSlug>>;
77
+ /** Skip this definition at seed time (a string is used as the warning's reason). */
78
+ readonly disabled?: SeedDisabledMarker;
79
+ }
80
+ export type SeedDefinition = CollectionSeedDefinition | GlobalSeedDefinition;
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,UAAU,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAA;AAC7G,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,GACnC,CAAC,GACD,CAAC,SAAS,IAAI,GACZ,CAAC,GACD,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACnB,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GACxB,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG;CAAE,GACxC,CAAC,CAAA;AAEX;mGACmG;AACnG,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,cAAc,IAAI,QAAQ,CAAC,8BAA8B,CAAC,KAAK,CAAC,CAAC,GAAG;IAC/G,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED;;6BAE6B;AAC7B,MAAM,MAAM,cAAc,CAAC,KAAK,SAAS,UAAU,IAAI,QAAQ,CAC7D,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC,CACjF,CAAA;AAED;wEACwE;AACxE,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,OAAO,GAAG,CAAA;IACf,IAAI,EAAE,OAAO,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GACvB,IAAI,GACJ;IACE,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAEL;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,MAAM,CAAA;AAEjD;wEACwE;AACxE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,CAAA;AAEtD,MAAM,WAAW,wBAAwB,CAAC,KAAK,SAAS,cAAc,GAAG,cAAc;IACrF,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC7D;;mFAE+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;CACvC;AAED,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU;IACzE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAClD,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;CACvC;AAED,MAAM,MAAM,cAAc,GAAG,wBAAwB,GAAG,oBAAoB,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug, DataFromGlobalSlug, GlobalSlug, RequiredDataFromCollectionSlug } from 'payload'\nimport type { file, FileToken, ref, Ref } from './refs'\n\n/**\n * Recursively widens a generated Payload data type so a {@link Ref} may appear at any object\n * field or array element — that's how relationship values are supplied as tokens instead of ids.\n * The shape (field names, required-ness) is still enforced, so changing a collection's schema still\n * surfaces a TS error in its seed file. Files aren't widened in here — they go on the record's\n * `_file` meta-key, not in a data field. Intentionally permissive at the leaf for v1: the runtime\n * validator checks that each ref actually lands in a field whose config allows it.\n */\nexport type WithRefs<T> = T extends Ref\n ? T\n : T extends Date\n ? T\n : T extends (infer U)[]\n ? Array<WithRefs<U> | Ref>\n : T extends object\n ? { [K in keyof T]: WithRefs<T[K]> | Ref }\n : T\n\n/** A single collection seed record: the collection's create-data, a local `_key` reference\n * handle, and an optional `_file` attaching a source file (for upload / provider collections). */\nexport type CollectionSeedData<TSlug extends CollectionSlug> = WithRefs<RequiredDataFromCollectionSlug<TSlug>> & {\n _key: string\n _file?: FileToken\n}\n\n/** A global's seed data (globals are singletons — no `_key`). The generated global type\n * carries `id`/`globalType`/timestamps that `updateGlobal` doesn't accept as input, so\n * they're stripped here. */\nexport type GlobalSeedData<TSlug extends GlobalSlug> = WithRefs<\n Omit<DataFromGlobalSlug<TSlug>, 'id' | 'globalType' | 'createdAt' | 'updatedAt'>\n>\n\n/** Tokens handed to every seed builder: `ref` (point at another seeded doc) and `file`\n * (attach a source file to an upload/provider doc via its `_file`). */\nexport interface SeedTokens {\n ref: typeof ref\n file: typeof file\n}\n\n/**\n * A collection's `custom.seedAsset` marker: declares a collection whose `_file` bytes are ingested\n * by the collection's own hook rather than stored as a Payload upload — e.g. `@pro-laico/payload-mux`'s\n * `mux-video` (uploaded to Mux). Set on the collection config:\n *\n * { slug: 'mux-video', custom: { seedAsset: { sourceField: 'source' } }, ... }\n *\n * Instead of uploading bytes, the seed engine resolves the `_file` under `subdir` and sets it as\n * `{ file, ...options }` on the doc's `sourceField`, for the collection's ingest hook to consume.\n * `true` is shorthand for the defaults (`sourceField: 'source'`, `subdir`: the collection slug).\n * Plain config — no import of the seed package needed, so the owning plugin stays decoupled from it.\n */\nexport type SeedAssetMarker =\n | true\n | {\n /** Doc field the engine sets to `{ file, ...options }` for the ingest hook. @default 'source' */\n sourceField?: string\n /** Subdirectory under the assets dir holding the source files. @default the collection slug */\n subdir?: string\n }\n\n/**\n * A collection's `custom.seedDisabled` marker: declares that the collection cannot be seeded right\n * now (typically missing credentials), set by the owning plugin from its own config/env:\n *\n * { slug: 'mux-video', custom: { seedDisabled: 'Mux credentials not set (MUX_TOKEN_ID / MUX_TOKEN_SECRET)' } }\n *\n * The engine skips the collection's definition at runtime with a warning (a string is used as the\n * reason) and drops any optional field whose `ref()` points at it — a required ref is a hard error.\n * Because the definition stays registered, the generated seed-ref types don't change with the\n * environment; set the env vars and the next run seeds it, nothing else to touch. Plain config —\n * no import of the seed package needed, so the owning plugin stays decoupled from it.\n */\nexport type SeedDisabledMarker = boolean | string\n\n/** A seed builder receives the ref/file tokens and returns the seed data. Deferred\n * (not eager data) so refs resolve against the full definition set. */\nexport type SeedBuilder<T> = (tokens: SeedTokens) => T\n\nexport interface CollectionSeedDefinition<TSlug extends CollectionSlug = CollectionSlug> {\n readonly kind: 'collection'\n readonly slug: TSlug\n readonly build: SeedBuilder<Array<CollectionSeedData<TSlug>>>\n /** Skip this definition at seed time (a string is used as the warning's reason). The definition\n * still contributes to the generated seed-ref types, so gating it doesn't shift types. Also set\n * automatically when the target collection declares `custom.seedDisabled`. */\n readonly disabled?: SeedDisabledMarker\n}\n\nexport interface GlobalSeedDefinition<TSlug extends GlobalSlug = GlobalSlug> {\n readonly kind: 'global'\n readonly slug: TSlug\n readonly build: SeedBuilder<GlobalSeedData<TSlug>>\n /** Skip this definition at seed time (a string is used as the warning's reason). */\n readonly disabled?: SeedDisabledMarker\n}\n\nexport type SeedDefinition = CollectionSeedDefinition | GlobalSeedDefinition\n"],"names":[],"mappings":"AAmGA,WAA4E"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@pro-laico/payload-seed",
3
+ "version": "0.0.0",
4
+ "description": "Schema-aware, type-safe seeding plugin for Payload CMS: typed cross-file references with dependency tracking, robust media uploads, a POST /api/seed endpoint, and a SeedRegistry injected into payload-types.ts.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/pro-laico/payload-plugins.git",
9
+ "directory": "packages/payload-seed"
10
+ },
11
+ "keywords": [
12
+ "payload",
13
+ "payloadcms",
14
+ "plugin",
15
+ "seed",
16
+ "seeding",
17
+ "fixtures"
18
+ ],
19
+ "sideEffects": false,
20
+ "type": "module",
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "main": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "default": "./dist/index.js"
31
+ },
32
+ "./components/SeedButton": {
33
+ "types": "./dist/components/SeedButton.d.ts",
34
+ "import": "./dist/components/SeedButton.js",
35
+ "default": "./dist/components/SeedButton.js"
36
+ }
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "peerDependencies": {
42
+ "@payloadcms/ui": "^3.0.0",
43
+ "payload": "^3.0.0",
44
+ "react": "^19.0.0",
45
+ "react-dom": "^19.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "@payloadcms/ui": "^3.85.1",
49
+ "@types/node": "^26.0.1",
50
+ "@types/react": "^19.2.17",
51
+ "@types/react-dom": "^19.2.3",
52
+ "payload": "^3.85.1",
53
+ "react": "^19.2.7",
54
+ "react-dom": "^19.2.7",
55
+ "typescript": "^6.0.3",
56
+ "vitest": "^4.1.9"
57
+ },
58
+ "engines": {
59
+ "node": ">=18"
60
+ },
61
+ "scripts": {
62
+ "build": "pnpm clean && pnpm build:types && pnpm build:swc",
63
+ "clean": "rimraf dist tsconfig.tsbuildinfo",
64
+ "typecheck": "tsc -p tsconfig.json --noEmit",
65
+ "test": "vitest run",
66
+ "test:watch": "vitest",
67
+ "build:swc": "swc ./src -d ./dist --config-file ../../.swcrc --strip-leading-paths",
68
+ "build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly --noCheck"
69
+ }
70
+ }