├── .gitignore
├── README.md
├── license.md
├── strapify
├── .babelrc
├── .prettierrc
├── bundle
│ ├── .gitkeep
│ ├── main.js
│ ├── main.js.map
│ ├── strapify-v0.0.7.js
│ └── strapify-v0.0.7.js.map
├── jest.config.js
├── package-lock.json
├── package.json
├── src
│ ├── Strapify.js
│ ├── StrapifyCollection.js
│ ├── StrapifyControl.js
│ ├── StrapifyEZFormsForm.js
│ ├── StrapifyErrors.js
│ ├── StrapifyField.js
│ ├── StrapifyForm.js
│ ├── StrapifyParse.js
│ ├── StrapifyRelation.js
│ ├── StrapifyRepeatable.js
│ ├── StrapifySingleType.js
│ ├── StrapifyTemplate.js
│ ├── injector-backup.js
│ ├── injector.js
│ ├── strapify-parser.js
│ ├── strapify-parser.js.pegjs
│ └── util
│ │ └── strapiRequest.js
├── tests
│ ├── DOM.test.js
│ ├── Strapify.test.js
│ ├── html-templates.js
│ ├── html-templates
│ │ ├── collection.html
│ │ ├── combined-filter-sort-page.html
│ │ ├── components.html
│ │ ├── empty.html
│ │ ├── nested-collection-deep.html
│ │ ├── nested-collection.html
│ │ ├── nested-collections-and-relations.html
│ │ ├── single-type-components.html
│ │ ├── strapi-background-image.html
│ │ ├── strapi-class-add.html
│ │ ├── strapi-class-conditional.html
│ │ ├── strapi-class-replace.html
│ │ ├── strapi-css-rule.html
│ │ ├── strapi-delete.html
│ │ ├── strapi-field.html
│ │ ├── strapi-filter.html
│ │ ├── strapi-into.html
│ │ ├── strapi-page-and-strapi-page-size.html
│ │ ├── strapi-relation.html
│ │ ├── strapi-single-type-background-image.html
│ │ ├── strapi-single-type-class-add.html
│ │ ├── strapi-single-type-class-conditional.html
│ │ ├── strapi-single-type-class-replace.html
│ │ ├── strapi-single-type-css-rule.html
│ │ ├── strapi-single-type-field.html
│ │ ├── strapi-single-type-into.html
│ │ ├── strapi-single-type-relation.html
│ │ ├── strapi-single-type-repeatable.html
│ │ └── strapi-sort.html
│ ├── html-tests-validated
│ │ ├── .gitkeep
│ │ ├── collection.html
│ │ ├── combined-filter-sort-page.html
│ │ ├── components.html
│ │ ├── empty.html
│ │ ├── nested-collection-deep.html
│ │ ├── nested-collection.html
│ │ ├── nested-collections-and-relations.html
│ │ ├── single-type-components.html
│ │ ├── strapi-background-image.html
│ │ ├── strapi-class-add.html
│ │ ├── strapi-class-conditional.html
│ │ ├── strapi-class-replace.html
│ │ ├── strapi-css-rule.html
│ │ ├── strapi-delete.html
│ │ ├── strapi-field.html
│ │ ├── strapi-filter.html
│ │ ├── strapi-into.html
│ │ ├── strapi-page-and-strapi-page-size.html
│ │ ├── strapi-relation.html
│ │ ├── strapi-repeatable.html
│ │ ├── strapi-single-type-background-image.html
│ │ ├── strapi-single-type-class-add.html
│ │ ├── strapi-single-type-class-conditional.html
│ │ ├── strapi-single-type-class-replace.html
│ │ ├── strapi-single-type-css-rule.html
│ │ ├── strapi-single-type-field.html
│ │ ├── strapi-single-type-into.html
│ │ ├── strapi-single-type-relation.html
│ │ ├── strapi-single-type-repeatable.html
│ │ └── strapi-sort.html
│ ├── manual-tests
│ │ └── strapi-repeatable-pagination.html
│ ├── test-logs
│ │ └── .gitkeep
│ └── util.js
└── webpack.config.js
├── test-client
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ └── index.html
├── scripts
│ └── setupTypeScript.js
├── src
│ ├── components
│ │ ├── App.svelte
│ │ ├── Header.svelte
│ │ ├── StatusIndicator.svelte
│ │ └── URLInput.svelte
│ ├── global.css
│ ├── main.js
│ └── scripts
│ │ └── post-webflow-url.js
└── webpack.config.js
├── test-server
├── index.js
├── output
│ └── .gitkeep
├── package-lock.json
└── package.json
├── test-strapi
├── .editorconfig
├── .env.example
├── .eslintignore
├── .eslintrc
├── .gitignore
├── README.md
├── config
│ ├── admin.js
│ ├── api.js
│ ├── database.js
│ ├── middlewares.js
│ ├── plugins.js
│ └── server.js
├── database
│ └── migrations
│ │ └── .gitkeep
├── favicon.png
├── media-src-files
│ ├── Human Feeding The Little Squirrel.mp4
│ ├── clowfish.mp4
│ ├── dog tea.jpg
│ └── mammal.jpg
├── package-lock.json
├── package.json
├── public
│ ├── robots.txt
│ └── uploads
│ │ └── .gitkeep
├── src
│ ├── admin
│ │ ├── app.example.js
│ │ └── webpack.config.example.js
│ ├── api
│ │ ├── .gitkeep
│ │ ├── collection1
│ │ │ ├── content-types
│ │ │ │ └── collection1
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── collection1.js
│ │ │ ├── routes
│ │ │ │ └── collection1.js
│ │ │ └── services
│ │ │ │ └── collection1.js
│ │ ├── strapi-class-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-class-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-class-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-class-test.js
│ │ │ └── services
│ │ │ │ └── strapi-class-test.js
│ │ ├── strapi-components-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-components-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-components-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-components-test.js
│ │ │ └── services
│ │ │ │ └── strapi-components-test.js
│ │ ├── strapi-css-rule-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-css-rule-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-css-rule-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-css-rule-test.js
│ │ │ └── services
│ │ │ │ └── strapi-css-rule-test.js
│ │ ├── strapi-field-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-field-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-field-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-field-test.js
│ │ │ └── services
│ │ │ │ └── strapi-field-test.js
│ │ ├── strapi-filter-sort-page-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-filter-sort-page-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-filter-sort-page-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-filter-sort-page-test.js
│ │ │ └── services
│ │ │ │ └── strapi-filter-sort-page-test.js
│ │ ├── strapi-into-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-into-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-into-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-into-test.js
│ │ │ └── services
│ │ │ │ └── strapi-into-test.js
│ │ ├── strapi-relation-test-a
│ │ │ ├── content-types
│ │ │ │ └── strapi-relation-test-a
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-relation-test-a.js
│ │ │ ├── routes
│ │ │ │ └── strapi-relation-test-a.js
│ │ │ └── services
│ │ │ │ └── strapi-relation-test-a.js
│ │ ├── strapi-relation-test-b
│ │ │ ├── content-types
│ │ │ │ └── strapi-relation-test-b
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-relation-test-b.js
│ │ │ ├── routes
│ │ │ │ └── strapi-relation-test-b.js
│ │ │ └── services
│ │ │ │ └── strapi-relation-test-b.js
│ │ ├── strapi-repeatable-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-repeatable-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-repeatable-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-repeatable-test.js
│ │ │ └── services
│ │ │ │ └── strapi-repeatable-test.js
│ │ ├── strapi-single-type-class-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-single-type-class-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-single-type-class-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-single-type-class-test.js
│ │ │ └── services
│ │ │ │ └── strapi-single-type-class-test.js
│ │ ├── strapi-single-type-components-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-single-type-components-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-single-type-components-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-single-type-components-test.js
│ │ │ └── services
│ │ │ │ └── strapi-single-type-components-test.js
│ │ ├── strapi-single-type-css-rule-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-single-type-css-rule-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-single-type-css-rule-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-single-type-css-rule-test.js
│ │ │ └── services
│ │ │ │ └── strapi-single-type-css-rule-test.js
│ │ ├── strapi-single-type-field-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-single-type-field-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-single-type-field-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-single-type-field-test.js
│ │ │ └── services
│ │ │ │ └── strapi-single-type-field-test.js
│ │ ├── strapi-single-type-into-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-single-type-into-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-single-type-into-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-single-type-into-test.js
│ │ │ └── services
│ │ │ │ └── strapi-single-type-into-test.js
│ │ ├── strapi-single-type-relation-test
│ │ │ ├── content-types
│ │ │ │ └── strapi-single-type-relation-test
│ │ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ │ └── strapi-single-type-relation-test.js
│ │ │ ├── routes
│ │ │ │ └── strapi-single-type-relation-test.js
│ │ │ └── services
│ │ │ │ └── strapi-single-type-relation-test.js
│ │ └── strapi-single-type-repeatable-test
│ │ │ ├── content-types
│ │ │ └── strapi-single-type-repeatable-test
│ │ │ │ └── schema.json
│ │ │ ├── controllers
│ │ │ └── strapi-single-type-repeatable-test.js
│ │ │ ├── routes
│ │ │ └── strapi-single-type-repeatable-test.js
│ │ │ └── services
│ │ │ └── strapi-single-type-repeatable-test.js
│ ├── components
│ │ ├── general
│ │ │ ├── image-info.json
│ │ │ ├── name.json
│ │ │ └── repeatable-test-component.json
│ │ └── nesting-tests
│ │ │ ├── component-one-level-deep.json
│ │ │ └── component-two-levels-deep.json
│ ├── extensions
│ │ └── .gitkeep
│ └── index.js
└── types
│ └── generated
│ ├── components.d.ts
│ └── contentTypes.d.ts
└── version-history.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
106 | # vscode files
107 | .vscode
108 |
109 | # dev server output folder
110 | /test-server/output/*
111 |
112 | # strapify test files
113 | /strapify/tests/html-tests-unvalidated/*
114 |
115 | # strapify test log files
116 | /strapify/tests/test-logs/*
117 |
118 | # gitkeep files
119 | !.gitkeep
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Strapify
2 |
3 | Strapify is a javascript tool for the automatic client side injection of Strapi CMS data into a website.
4 |
5 | Documentation https://www.strapify.dev/docs
6 |
7 | ## How to Run For Development
8 | For a website with files stored locally, build Strapify and add /strapify/bundle/main.js to your HTML file.
9 |
10 | For a website which is hosted, such as a Webflow site, it is easiest to develop Strapify using the development server and client, which will allow you to scrape the site and add the Strapify script with a single button press.
11 |
12 | #### Strapify
13 | - cd into the /strapify folder and install npm deps
14 | ```shell
15 | npm install
16 | ```
17 | - install peggy (must be installed globally) and build the peggy parser with
18 | ```shell
19 | npm install -g peggy
20 | npm run buildpeggy
21 | ```
22 | - and start webpack with hot reloding in another terminal (used to bundle the source scripts) with
23 | ```shell
24 | npm run bundlehot
25 | ```
26 |
27 |
28 | #### Development Server
29 | - cd into the /test-server folder and install npm deps
30 | ```shell
31 | npm install
32 | ```
33 | - run the server with
34 | ```shell
35 | npm run starthot
36 | ```
37 |
38 |
39 | #### Development Client
40 | - cd into the /test-client folder and install npm deps
41 | ```shell
42 | npm install
43 | ```
44 | - run the client with
45 | ```shell
46 | npm run dev
47 | ```
48 | the app will be available on localhost:8080. You can test it with these links:
49 | - webflow: https://strapify-demo.webflow.io/
50 | - strapi: http://54.163.229.233:1337
51 |
52 |
53 | ## How to build
54 | For development builds cd into /strapify and run the following commands
55 | ```shell
56 | npm install -g peggy
57 | npm run buildpeggy
58 | ```
59 | ```shell
60 | npm run bundle
61 | ```
62 | the script can then be found in /strapify/bundle/main.js
63 |
64 | For production builds cd into /strapify and run the following commands
65 | ```shell
66 | npm install -g peggy
67 | npm run buildpeggy
68 | ```
69 | ```shell
70 | npm run bundleprod
71 | ```
72 | the script can then be found in /strapify/bundle/strapify.js
73 |
74 | ## How to make changes
75 | The source files for Strapify are found in /strapify/src. Make any changes and build.
76 |
77 | ## Testing
78 | Strapify uses Jest for testing. Some functions are unit tested as usual but since Strapify is all about modifying the DOM, we use a more elaborate system that requires manual human validation initially, and then automated difference testing afterwards.
79 |
80 | This system involves three directories
81 | 1. /strapify/tests/html-templates (place any tests you make in here)
82 | 2. /strapify/tests/html-tests-unvalidated (never add anything here)
83 | 3. /strapify/tests/html-tests-validated (move files from html-tests-unvalidated to this directory after manual validation)
84 |
85 | The DOM based testing process is as follows:
86 | 1. create any tests and add them to the html-templates directory
87 | 2. run the tests in DOM.test.js. This will result in a file for each template, with the same name as the template, being created in html-tests-unvalidated. These files contain a dump of the DOM after Strapify runs.
88 | 3. if the test has not been manually validated, the test will fail. In this case, open the test file in html-tests-unvalidated and validate that everything is correct. You must disable javascript when you open the file in a browser. If everything is ok, move it to html-tests-validated and run Jest again
89 | 4. if a validated file does exist, the dumped DOM will be compared to the content of the validated file to detect any differences.
90 |
91 | This system allows for unexpected changes in behaviour to be detected automatically.
92 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | The MIT License (MIT)
4 | =====================
5 |
6 | Copyright © `2023` `Strapify Contributors (Austin Goodman, Ray Keating, Civiconnect)`
7 |
8 | Permission is hereby granted, free of charge, to any person
9 | obtaining a copy of this software and associated documentation
10 | files (the “Software”), to deal in the Software without
11 | restriction, including without limitation the rights to use,
12 | copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the
14 | Software is furnished to do so, subject to the following
15 | conditions:
16 |
17 | The above copyright notice and this permission notice shall be
18 | included in all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 | OTHER DEALINGS IN THE SOFTWARE.
28 |
--------------------------------------------------------------------------------
/strapify/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "sourceMaps": true
4 | }
--------------------------------------------------------------------------------
/strapify/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 4,
4 | "printWidth": 120,
5 | "singleQuote": false
6 | }
7 |
--------------------------------------------------------------------------------
/strapify/bundle/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/strapify/bundle/.gitkeep
--------------------------------------------------------------------------------
/strapify/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: "jest-puppeteer",
3 | moduleFileExtensions: ['js'],
4 | moduleDirectories: ['node_modules'],
5 | //testEnvironment: 'jsdom'
6 | testTimeout: 20000
7 | };
--------------------------------------------------------------------------------
/strapify/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "strapify",
3 | "version": "0.0.6",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "jest",
8 | "bundle": "webpack --mode development",
9 | "bundlehot": "webpack --watch --mode development",
10 | "bundleprod": "webpack --mode production",
11 | "bundlegzip": "webpack --mode production --env gzip=true",
12 | "bundleanalyze": "webpack --mode production --env analyze=true",
13 | "buildpeggy": "peggy -o ./src/strapify-parser.js ./src/strapify-parser.js.pegjs",
14 | "build": "npm run buildpeggy && npm run bundleprod && npm run bundlegzip"
15 | },
16 | "author": "Austin Goodman, Ray Keating",
17 | "license": "UNLICENSED",
18 | "dependencies": {
19 | "axios": "^1.1.3",
20 | "dotenv": "^16.0.3",
21 | "marked": "^4.2.2"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.21.4",
25 | "@babel/preset-env": "^7.21.4",
26 | "babel-jest": "^29.3.1",
27 | "babel-loader": "^9.1.2",
28 | "compression-webpack-plugin": "^10.0.0",
29 | "diff-dom": "^4.2.8",
30 | "jest": "^29.3.1",
31 | "jest-cli": "^29.3.1",
32 | "jest-environment-jsdom": "^29.3.1",
33 | "jest-puppeteer": "^6.2.0",
34 | "webpack": "^5.80.0",
35 | "webpack-bundle-analyzer": "^4.7.0",
36 | "webpack-cli": "^4.10.0"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/strapify/src/StrapifyEZFormsForm.js:
--------------------------------------------------------------------------------
1 | import Strapify from "./Strapify";
2 | import { strapiEZFormsSubmit } from "./util/strapiRequest";
3 |
4 | class StrapifyEZFormsForm {
5 | #formContainerElm;
6 | #formElm;
7 | #formSubmitElm;
8 | #state = "initial";
9 | #stateElms;
10 |
11 | #attributes = {
12 | "strapi-ezforms-form": undefined,
13 | "strapi-success-redirect": undefined,
14 | "strapi-error-redirect": undefined,
15 | "strapi-hide-on-success": undefined,
16 | "strapi-hide-on-error": undefined,
17 | }
18 |
19 | constructor(formContainerElement) {
20 | this.#formContainerElm = formContainerElement;
21 | this.#updateAttributes();
22 |
23 | //check if the formContainerElm is a form element
24 | if (this.#formContainerElm.tagName === "FORM") {
25 | this.#formElm = this.#formContainerElm;
26 | } else {
27 | //find the child form which is closest to the formContainerElm
28 | this.#formElm = this.#formContainerElm.querySelector("form");
29 | }
30 |
31 | this.#stateElms = Strapify.findStateElements(this.#formContainerElm);
32 | this.#reflectState();
33 |
34 | this.#formSubmitElm = Strapify.findEZFormSubmitElms(this.#formContainerElm)[0];
35 | }
36 |
37 | #updateAttributes() {
38 | Object.keys(this.#attributes).forEach((attribute) => {
39 | this.#attributes[attribute] = this.#formContainerElm.getAttribute(attribute);
40 | })
41 | }
42 |
43 | #reflectState() {
44 | this.#stateElms.forEach(stateElm => {
45 | const stateKey = stateElm.getAttribute("strapi-state-element");
46 |
47 | if (stateKey === this.#state) {
48 | stateElm.classList.remove("strapify-hide");
49 | } else {
50 | stateElm.classList.add("strapify-hide");
51 | }
52 | });
53 | }
54 |
55 | async process() {
56 | const ezFormsElm = this.#formElm;
57 | const submitElm = this.#formSubmitElm;
58 |
59 | submitElm.addEventListener("click", (event) => {
60 | event.preventDefault();
61 |
62 | this.#state = "loading";
63 | this.#reflectState();
64 |
65 | strapiEZFormsSubmit(ezFormsElm).then((data) => {
66 | this.#state = "success";
67 | this.#reflectState();
68 |
69 | //dispatch a custom event with the data
70 | this.#formContainerElm.dispatchEvent(new CustomEvent("strapiEZFormsSubmitted", {
71 | bubbles: false,
72 | detail: {
73 | data: data
74 | }
75 | }));
76 |
77 | if(this.#attributes["strapi-hide-on-success"] !== null && this.#attributes["strapi-hide-on-success"] !== undefined) {
78 | this.#formContainerElm.classList.add("strapify-hide");
79 | }
80 |
81 | if (this.#attributes["strapi-success-redirect"]) {
82 | window.location.href = this.#attributes["strapi-success-redirect"];
83 | }
84 | }).catch((error) => {
85 | this.#state = "error";
86 | this.#reflectState();
87 |
88 | //dispatch a custom event with the error
89 | this.#formContainerElm.dispatchEvent(new CustomEvent("strapiEZFormsError", {
90 | bubbles: false,
91 | detail: {
92 | error: error
93 | }
94 | }));
95 |
96 | if(this.#attributes["strapi-hide-on-error"] !== null && this.#attributes["strapi-hide-on-error"] !== undefined) {
97 | this.#formContainerElm.classList.add("strapify-hide");
98 | }
99 |
100 | if (this.#attributes["strapi-error-redirect"]) {
101 | window.location.href = this.#attributes["strapi-error-redirect"];
102 | }
103 | });
104 | });
105 | }
106 | }
107 |
108 | export default StrapifyEZFormsForm;
--------------------------------------------------------------------------------
/strapify/src/StrapifyErrors.js:
--------------------------------------------------------------------------------
1 | // internal state that keeps track of how many errors have been logged
2 | let errorCount = 0;
3 |
4 | let thrownLogs = [];
5 |
6 | function logIfUnseen(message, logType) {
7 | // logType can be "warn", or "error"
8 | if (!thrownLogs.includes(error)) {
9 | thrownLogs.push(error);
10 | console.group(
11 | `%cSTRAPIFY ${logType === "warn" ? "WARNING" : "ERROR"}`,
12 | `background-color: ${
13 | logType === "warn" ? "#9b9023" : "#aa3d3d"
14 | }; color: #ffffff; font-weight: bold; padding: 4px;`
15 | );
16 | console[logType](message);
17 | console.groupEnd();
18 | }
19 | }
20 |
21 | function toast(message) {
22 | const toast = document.createElement("div");
23 | toast.classList.add("toast");
24 | toast.textContent = message;
25 |
26 | // Create the close button
27 | const closeButton = document.createElement("button");
28 | closeButton.textContent = "×";
29 | closeButton.classList.add("close-button");
30 | closeButton.style.backgroundColor = "transparent";
31 | closeButton.style.border = "none";
32 | closeButton.style.color = "#fff";
33 | closeButton.style.fontSize = "20px";
34 | closeButton.style.marginLeft = "12px";
35 | closeButton.style.cursor = "pointer";
36 |
37 | // Set the toast styles
38 | toast.style.display = "flex";
39 | toast.style.alignItems = "center";
40 | toast.style.position = "fixed";
41 | toast.style.bottom = "16px";
42 | toast.style.left = "16px";
43 | toast.style.padding = "12px";
44 | toast.style.backgroundColor = "#333";
45 | toast.style.color = "#fff";
46 | toast.style.borderRadius = "4px";
47 | toast.style.boxShadow = "0 0 8px rgba(0, 0, 0, 0.3)";
48 | toast.style.opacity = "0";
49 | toast.style.transition = "opacity 0.3s ease-in-out";
50 | toast.style.zIndex = "9999";
51 |
52 | toast.appendChild(closeButton);
53 | document.body.appendChild(toast);
54 |
55 | // Close the toast when the close button is clicked
56 | closeButton.addEventListener("click", () => {
57 | toast.style.opacity = "0";
58 | setTimeout(() => {
59 | document.body.removeChild(toast);
60 | }, 300);
61 | });
62 |
63 | setTimeout(() => {
64 | toast.style.opacity = "1";
65 | }, 100);
66 | }
67 |
68 | function warn(message) {
69 | logIfUnseen(message, "warn");
70 | }
71 |
72 | function error(message) {
73 | errorCount++;
74 | if (errorCount > 0) {
75 | toast(
76 | `${errorCount} Strapify error${
77 | errorCount > 1 ? "s" : ""
78 | } logged. See console for details.`
79 | );
80 | }
81 | logIfUnseen(message, "error");
82 | }
83 |
84 | function checkForTemplateElement(templateElms, containerElement) {
85 | if (templateElms.length === 0) {
86 | if (containerElement.getAttribute("strapi-collection")) {
87 | error(
88 | `No template element found for collection "${containerElement.getAttribute(
89 | "strapi-collection"
90 | )}"`
91 | );
92 | }
93 | }
94 | }
95 |
96 | function checkIfText(strapiData, elm) {
97 | if (typeof strapiData === "object") {
98 | warn(
99 | `The field "${elm.getAttribute(
100 | "strapi-field"
101 | )}" is set on a text element (p, span, h) but does not contain text. If you are trying to set an image or video field, set it on an img or div element instead.`
102 | );
103 | }
104 | }
105 |
106 | function checkIfSingleMedia(strapiData, elm) {
107 | if (typeof strapiData !== "object") {
108 | error(
109 | `The field "${elm.getAttribute("strapi-field")}" in the "${elm
110 | .closest("[strapi-collection]")
111 | .getAttribute(
112 | "strapi-collection"
113 | )}" collection is not a media field, but is set on an element.`
114 | );
115 | }
116 | }
117 |
118 | function isMultipleMedia(strapiData, elm) {
119 | if (Array.isArray(strapiData.data)) {
120 | warn(
121 | `The field "${elm.getAttribute("strapi-field")}" in the "${elm
122 | .closest("[strapi-collection]")
123 | .getAttribute(
124 | "strapi-collection"
125 | )}" collection is a multiple media field. strapi-field only works on single media fields. To display multiple media fields, use strapi-repeatable with a strapi-template and strapi-field inside`
126 | );
127 | return true;
128 | } else {
129 | return false;
130 | }
131 | }
132 |
133 | function checkIfUndefinedStrapiDataValue(
134 | strapiDataValue,
135 | fieldPath,
136 | fieldElement
137 | ) {
138 | if (strapiDataValue === undefined) {
139 | error(
140 | `Error fetching strapi data for field "${fieldPath}" in collection "${fieldElement
141 | .closest("[strapi-collection]")
142 | .getAttribute("strapi-collection")}. Check that the field exists.`
143 | );
144 | }
145 | }
146 |
147 | function checkIfRichText(strapiData, elm) {
148 | // this is a bit of a hacky way to check if the strapiData is rich text, but it should help the webflow people stop using divs for text (text blocks)
149 | // if the strapiData contains a new line character or a #, it is likely rich text. If it doesn't, it is likely a string. Throw a warning if it is a string.
150 | if (
151 | typeof strapiData === "string" &&
152 | !/#+/.test(strapiData) &&
153 | !strapiData.includes("\n") &&
154 | !strapiData.includes("\r")
155 | ) {
156 | // if the strapiData is a youtube link, don't throw a warning
157 | if (strapiData.includes("http")) {
158 | return;
159 | }
160 | warn(
161 | `The text field "${elm.getAttribute("strapi-field")}" in the "${elm
162 | ?.closest("[strapi-collection]")
163 | ?.getAttribute(
164 | "strapi-collection"
165 | )}" collection is set on a div element rather than a p, span, or h. This may alter the styling of the text. If "${elm.getAttribute(
166 | "strapi-field"
167 | )}" is a rich text field, ignore this warning.`
168 | );
169 | }
170 | }
171 |
172 | const ErrorHandler = {
173 | checkForTemplateElement,
174 | checkIfText,
175 | checkIfSingleMedia,
176 | isMultipleMedia,
177 | checkIfUndefinedStrapiDataValue,
178 | checkIfRichText,
179 | warn,
180 | error,
181 | toast,
182 | };
183 |
184 | export default ErrorHandler;
185 |
--------------------------------------------------------------------------------
/strapify/src/StrapifyForm.js:
--------------------------------------------------------------------------------
1 | import Strapify from "./Strapify";
2 | import { strapiRegister, strapiAuthenticate } from "./util/strapiRequest";
3 |
4 | class StrapifyForm {
5 | #formElement;
6 | #mutationObserver;
7 |
8 | #formInputElms;
9 | #formSubmitElm;
10 |
11 | #attributes = {
12 | "strapi-form": undefined,
13 | "strapi-auth": undefined,
14 | "strapi-success-redirect": undefined,
15 | "strapi-error-redirect": undefined,
16 | }
17 |
18 | constructor(formElement) {
19 | this.#formElement = formElement;
20 | this.#updateAttributes();
21 |
22 | // this.#mutationObserver = new MutationObserver((mutations) => {
23 | // mutations.forEach((mutation) => {
24 | // if (mutation.type === "attributes") {
25 | // this.#updateAttributes();
26 | // this.process();
27 | // }
28 | // });
29 | // });
30 |
31 | // this.#mutationObserver.observe(this.#singleTypeElement, {
32 | // attributes: true,
33 | // attributeFilter: ["strapi-single-type"]
34 | // });
35 |
36 | this.#formInputElms = Strapify.findFormInputElms(this.#formElement);
37 | this.#formSubmitElm = Strapify.findFormSubmitElms(this.#formElement)[0];
38 |
39 | // set any strapi-auth forms to return false on submit
40 | if (this.#attributes["strapi-auth"]) {
41 | this.#formElement.addEventListener("submit", (e) => {
42 | e.preventDefault();
43 | return false;
44 | });
45 | }
46 |
47 | // this.#formElement.addEventListener("strapiAuthRegistered", (event) => {
48 | // console.log(event);
49 | // });
50 |
51 | // this.#formElement.addEventListener("strapiAuthLoggedIn", (event) => {
52 | // console.log(event);
53 | // });
54 | }
55 |
56 | destroy() {
57 | this.#mutationObserver.disconnect();
58 | }
59 |
60 | #updateAttributes() {
61 | Object.keys(this.#attributes).forEach((attribute) => {
62 | this.#attributes[attribute] = this.#formElement.getAttribute(attribute);
63 | })
64 | }
65 |
66 | #getFormData() {
67 | const formData = {};
68 |
69 | this.#formInputElms.forEach((inputElm) => {
70 | let name = inputElm.getAttribute("strapi-form-input");
71 | if (!name) {
72 | name = inputElm.getAttribute("strapi-auth-input");
73 | }
74 |
75 | // split input value by | separator, with optional whitespace (e.g. "username | email")
76 | const names = name.split(/\s*\|\s*/);
77 | names.forEach((name) => {
78 | name = name.trim();
79 | formData[name] = inputElm.value;
80 | })
81 |
82 | })
83 |
84 | return formData;
85 | }
86 |
87 | async #onAuthSubmit(e) {
88 | const formData = this.#getFormData()
89 |
90 | if (this.#attributes["strapi-auth"] === "register") {
91 | try {
92 | const responseData = await strapiRegister(formData);
93 |
94 | localStorage.setItem("jwt", responseData.jwt);
95 | localStorage.setItem("user", JSON.stringify(responseData.user));
96 |
97 | //dispatch custom event with registered user data
98 | this.#formElement.dispatchEvent(new CustomEvent("strapiAuthRegistered", {
99 | bubbles: false,
100 | detail: {
101 | user: responseData.user
102 | }
103 | }));
104 |
105 | if(this.#attributes["strapi-success-redirect"]) {
106 | window.location.href = this.#attributes["strapi-success-redirect"];
107 | }
108 | } catch (error) {
109 | //dispatch custom event with error
110 | this.#formElement.dispatchEvent(new CustomEvent("strapiAuthRegisterError", {
111 | bubbles: false,
112 | detail: {
113 | error: error,
114 | errorMessage: error.response.data.error.message
115 | }
116 | }));
117 |
118 | if(this.#attributes["strapi-error-redirect"]) {
119 | window.location.href = this.#attributes["strapi-error-redirect"];
120 | }
121 |
122 | console.error(error);
123 | console.error(error.response.data.error.message);
124 | }
125 |
126 |
127 | } else if (this.#attributes["strapi-auth"] === "authenticate") {
128 | try {
129 | const responseData = await strapiAuthenticate(formData.identifier, formData.password);
130 | localStorage.setItem("jwt", responseData.jwt);
131 | localStorage.setItem("user", JSON.stringify(responseData.user));
132 |
133 | //dispatch custom event with authenticated user data
134 | this.#formElement.dispatchEvent(new CustomEvent("strapiAuthLoggedIn", {
135 | bubbles: false,
136 | detail: {
137 | user: responseData.user
138 | }
139 | }));
140 |
141 | if(this.#attributes["strapi-success-redirect"]) {
142 | window.location.href = this.#attributes["strapi-success-redirect"];
143 | }
144 | } catch (error) {
145 | //dispatch custom event with error
146 | this.#formElement.dispatchEvent(new CustomEvent("strapiAuthLogInError", {
147 | bubbles: false,
148 | detail: {
149 | error: error,
150 | errorMessage: error.response.data.error.message
151 | }
152 | }));
153 |
154 | if(this.#attributes["strapi-error-redirect"]) {
155 | window.location.href = this.#attributes["strapi-error-redirect"];
156 | }
157 |
158 | console.error(error);
159 | console.error(error.response.data.error.message);
160 | }
161 |
162 | }
163 | }
164 |
165 | async #processForm() {
166 |
167 | }
168 |
169 | async #processAuth() {
170 | //remove any existing event listeners
171 | this.#formSubmitElm.removeEventListener("click", this.#onAuthSubmit.bind(this));
172 | this.#formSubmitElm.addEventListener("click", this.#onAuthSubmit.bind(this));
173 | }
174 |
175 | async process() {
176 | if (this.#attributes["strapi-form"]) {
177 | await this.#processForm();
178 | }
179 |
180 | if (this.#attributes["strapi-auth"]) {
181 | await this.#processAuth();
182 | }
183 | }
184 | }
185 |
186 | export default StrapifyForm;
--------------------------------------------------------------------------------
/strapify/src/StrapifyRelation.js:
--------------------------------------------------------------------------------
1 | import Strapify from "./Strapify.js";
2 | import StrapifyCollection from "./StrapifyCollection.js";
3 | import StrapifyField from "./StrapifyField";
4 | import strapiRequest from "./util/strapiRequest";
5 |
6 | class StrapifyTemplate {
7 | #relationElement;
8 | #strapifyCollection;
9 | #mutationObserver;
10 |
11 | #strapiDataId;
12 | #strapiDataAttributes;
13 |
14 | #attributes = {
15 | "strapi-relation": undefined,
16 | "strapi-single-type-relation": undefined,
17 | }
18 |
19 | constructor(relationElement, strapiDataId, strapiDataAttributes) {
20 | //set the collection element and update the attributes
21 | this.#relationElement = relationElement;
22 | this.#strapiDataId = strapiDataId;
23 | this.#strapiDataAttributes = strapiDataAttributes;
24 | this.#updateAttributes();
25 |
26 | //create mutation observer to watch for attribute changes
27 | this.#mutationObserver = new MutationObserver((mutations) => {
28 | mutations.forEach((mutation) => {
29 | if (mutation.type === "attributes") {
30 | this.#updateAttributes();
31 | this.process();
32 | }
33 | });
34 | });
35 |
36 | //observe the collection element for attribute changes
37 | this.#mutationObserver.observe(this.#relationElement, {
38 | attributes: true,
39 | attributeFilter: ["strapi-relation"]
40 | });
41 | }
42 |
43 | destroy() {
44 | this.#mutationObserver.disconnect();
45 | this.#strapifyCollection.destroy();
46 | this.#relationElement.remove();
47 | }
48 |
49 | #updateAttributes() {
50 | Object.keys(this.#attributes).forEach((attribute) => {
51 | this.#attributes[attribute] = this.#relationElement.getAttribute(attribute);
52 | })
53 | }
54 |
55 | async process() {
56 | const relationElement = this.#relationElement;
57 |
58 | if (this.#strapifyCollection) {
59 | this.#strapifyCollection.destroy()
60 | }
61 |
62 | const strapiDataId = this.#strapiDataId;
63 | const strapiDataAttributes = this.#strapiDataAttributes;
64 |
65 | //use the relation ids to generate a filter string
66 | let relationArgs
67 | let relationFieldName
68 | let relationCollectionName
69 | if (this.#attributes["strapi-relation"]) {
70 | relationArgs = this.#attributes["strapi-relation"].split(",").map(arg => arg.trim());
71 | relationFieldName = relationArgs[0];
72 | relationCollectionName = relationArgs[1];
73 | }
74 | else if (this.#attributes["strapi-single-type-relation"]) {
75 | relationArgs = this.#attributes["strapi-single-type-relation"].split(",").map(arg => arg.trim());
76 | relationFieldName = relationArgs[0].split(".")[1];
77 | relationCollectionName = relationArgs[1];
78 | }
79 |
80 | //if the relation field is empty, delete all templates and return
81 | if (strapiDataAttributes[relationFieldName].data == null) {
82 | const templates = Strapify.findTemplateElms(relationElement);
83 | templates.forEach(template => template.remove());
84 | return;
85 | }
86 |
87 | //get the relation data
88 | const relationData = Strapify.getStrapiComponentValue(relationFieldName, strapiDataAttributes).data;
89 |
90 | //get the relation ids
91 | let relationIDs = [];
92 | if (Array.isArray(relationData)) {
93 | relationIDs = relationData.map(relation => relation.id);
94 | } else {
95 | relationIDs = [relationData.id];
96 | }
97 |
98 | //query string arg offset to allow for the first 10 relations to be used by user
99 | const qsOffset = 10;
100 |
101 | //use the relation ids to generate a filter string
102 | let filterString = relationIDs.reduce((acc, cur, i) => {
103 | let filter = `[id][$in][${qsOffset + i}]=${cur}`;
104 | i < relationIDs.length - 1 && (filter += " | ");
105 | return acc + filter;
106 | }, "");
107 |
108 | //when the filter string is empty, change it to filter for a non-existent id
109 | if (!filterString) {
110 | filterString = "[id][$eq]=-1";
111 | }
112 |
113 | // let filterString
114 | // if (Array.isArray(relationData)) {
115 | // filterString = relationData.map(relation => `[id][$eq]=${relation.id}`).join(" | ");
116 | // } else {
117 | // filterString = `[id][$eq]=${relationData.id}`;
118 | // }
119 |
120 |
121 |
122 | //add the filter string to the relation element
123 | relationElement.setAttribute("strapi-filter-internal-relation", filterString);
124 |
125 | //create a strapify collection with the relationelement
126 | this.#strapifyCollection = new StrapifyCollection(relationElement);
127 | await this.#strapifyCollection.process()
128 |
129 | }
130 | }
131 |
132 | export default StrapifyTemplate;
--------------------------------------------------------------------------------
/strapify/src/StrapifyRepeatable.js:
--------------------------------------------------------------------------------
1 | import Strapify from "./Strapify.js";
2 | import StrapifyCollection from "./StrapifyCollection.js";
3 | import StrapifyField from "./StrapifyField";
4 | import strapiRequest from "./util/strapiRequest";
5 |
6 | class StrapifyRepeatable {
7 | #repeatableElement;
8 | #strapifyCollection;
9 | #strapiDataId;
10 | #strapiDataAttributes
11 | #mutationObserver;
12 |
13 | #attributes = {
14 | "strapi-repeatable": undefined,
15 | "strapi-single-type-repeatable": undefined,
16 | }
17 |
18 | constructor(repeatableElement, strapiDataId, strapiDataAttributes) {
19 | //set the collection element and update the attributes
20 | this.#repeatableElement = repeatableElement;
21 | this.#strapiDataId = strapiDataId;
22 | this.#strapiDataAttributes = strapiDataAttributes;
23 | this.#updateAttributes();
24 |
25 | //create mutation observer to watch for attribute changes
26 | // this.#mutationObserver = new MutationObserver((mutations) => {
27 | // mutations.forEach((mutation) => {
28 | // if (mutation.type === "attributes") {
29 | // //this.#strapifyCollection.destroy();
30 | // //this.#updateAttributes();
31 | // //this.process();
32 | // }
33 | // });
34 | // });
35 |
36 | // //observe the collection element for attribute changes
37 | // this.#mutationObserver.observe(this.#repeatableElement, {
38 | // attributes: true,
39 | // attributeFilter: ["strapi-repeatable", "strapi-single-type-repeatable", "strapi-page", "strapi-page-size"]
40 | // });
41 | }
42 |
43 | destroy() {
44 | this.#mutationObserver.disconnect();
45 | this.#strapifyCollection.destroy();
46 | this.#repeatableElement.remove();
47 | }
48 |
49 | #updateAttributes() {
50 | Object.keys(this.#attributes).forEach((attribute) => {
51 | this.#attributes[attribute] = this.#repeatableElement.getAttribute(attribute);
52 | })
53 | }
54 |
55 | getOverrideData() {
56 | const fieldName = this.#attributes["strapi-repeatable"] ? this.#attributes["strapi-repeatable"] : this.#attributes["strapi-single-type-repeatable"].split(".")[1];
57 |
58 | //when the data field is null (explicitly not undefined), we have an empty media field
59 | //StrapifyCollection will delete the element if the data is null
60 | if (this.#strapiDataAttributes[fieldName].data === null) {
61 | Strapify.findTemplateElms(this.#repeatableElement).forEach((collectionElm) => {
62 | collectionElm.remove();
63 | })
64 | return null;
65 | }
66 |
67 | //if data is not null or undefined, we have a media field
68 | let overrideData
69 | if (this.#strapiDataAttributes[fieldName].data) {
70 | overrideData = {
71 | data: this.#strapiDataAttributes[fieldName].data.map((fieldData) => {
72 | return { attributes: { [fieldName]: { data: fieldData } } }
73 | }),
74 | meta: {}
75 | }
76 | }
77 | //otherwise we must have a component field
78 | else {
79 | overrideData = {
80 | data: this.#strapiDataAttributes[fieldName].map((fieldData) => {
81 | return { attributes: { [fieldName]: fieldData } }
82 | }),
83 | meta: {}
84 | }
85 | }
86 |
87 | //need to manually paginate since strapi doesn't support pagination on repeatable fields
88 | const pageSize = parseInt(this.#repeatableElement.getAttribute("strapi-page-size")) || 25;
89 | const page = parseInt(this.#repeatableElement.getAttribute("strapi-page")) || 1;
90 | const pageCount = Math.ceil(overrideData.data.length / pageSize);
91 | const total = overrideData.data.length;
92 |
93 | //split override data into pages
94 | const pagedOverrideData = [];
95 | for (let i = 0; i < overrideData.data.length; i += pageSize) {
96 | pagedOverrideData.push(overrideData.data.slice(i, i + pageSize));
97 | }
98 |
99 | //replace the data with the page we want
100 | overrideData.data = pagedOverrideData[page - 1];
101 |
102 | //update the meta
103 | overrideData.meta.pagination = {
104 | page,
105 | pageSize,
106 | pageCount,
107 | total
108 | }
109 |
110 | return overrideData;
111 | }
112 |
113 | async process() {
114 | const repeatableElement = this.#repeatableElement;
115 |
116 | //why on earth do I need to bind this to the function?
117 | const strapifyCollection = new StrapifyCollection(repeatableElement, this.getOverrideData.bind(this));
118 | this.#strapifyCollection = strapifyCollection;
119 |
120 | await strapifyCollection.process()
121 | }
122 | }
123 |
124 | export default StrapifyRepeatable;
--------------------------------------------------------------------------------
/strapify/src/StrapifyTemplate.js:
--------------------------------------------------------------------------------
1 | import Strapify from "./Strapify.js";
2 | import StrapifyRelation from "./StrapifyRelation.js";
3 | import StrapifyField from "./StrapifyField";
4 | import StrapifyRepeatable from "./StrapifyRepeatable.js";
5 |
6 | class StrapifyTemplate {
7 | //the template element this class manages
8 | #templateElement;
9 |
10 | //the strapi data id and attributes
11 | #strapiDataId
12 | #strapiDataAttributes
13 |
14 | //the strapify field, relation, and repeatable objects which belong to this template
15 | #strapifyFields = [];
16 | #strapifyRelations = [];
17 | #strapifyRepeatables = [];
18 |
19 | //the allowed attributes for the template element
20 | #attributes = {
21 | "strapi-template": undefined,
22 | "strapi-template-conditional": undefined
23 | }
24 |
25 | constructor(templateElement, strapiDataId, strapiDataAttributes, strapifyCollection) {
26 | this.#templateElement = templateElement;
27 | this.#strapiDataId = strapiDataId;
28 | this.#strapiDataAttributes = strapiDataAttributes;
29 | this.#updateAttributes();
30 | this.#addIds();
31 | }
32 |
33 | //destroy all descendant strapify objects and delete the template element
34 | destroy() {
35 | this.#strapifyFields.forEach(field => field.destroy());
36 | this.#strapifyRelations.forEach(relation => relation.destroy());
37 | this.#strapifyRepeatables.forEach(repeatable => repeatable.destroy());
38 | this.#templateElement.remove();
39 | }
40 |
41 | #updateAttributes() {
42 | Object.keys(this.#attributes).forEach((attribute) => {
43 | this.#attributes[attribute] = this.#templateElement.getAttribute(attribute);
44 | })
45 | }
46 |
47 | #addIds() {
48 | if (this.#strapiDataId) {
49 | this.#templateElement.setAttribute("strapi-template-id", this.#strapiDataId);
50 | }
51 | };
52 |
53 | async process() {
54 | //find strapify field elements, instatiate strapify field objects, and process them
55 | const strapifyFieldElements = Strapify.findFieldElms(this.#templateElement);
56 | strapifyFieldElements.forEach(fieldElement => {
57 | const strapifyField = new StrapifyField(fieldElement)
58 | this.#strapifyFields.push(strapifyField);
59 |
60 | strapifyField.process(this.#strapiDataAttributes)
61 | });
62 |
63 | const processPromises = [];
64 |
65 | //find strapify repeatable elements, instatiate strapify repeatable objects, and process them
66 | const strapifyRepeatableElements = Strapify.findRepeatableElms(this.#templateElement);
67 | for (const repeatableElement of strapifyRepeatableElements) {
68 | const strapifyRepeatable = new StrapifyRepeatable(repeatableElement, this.#strapiDataId, this.#strapiDataAttributes)
69 | this.#strapifyRepeatables.push(strapifyRepeatable);
70 |
71 | processPromises.push(strapifyRepeatable.process())
72 | }
73 |
74 | //find strapify relation elements, instatiate strapify relation objects, and process them
75 | const strapifyRelationElements = Strapify.findRelationElms(this.#templateElement);
76 | strapifyRelationElements.forEach(relationElement => {
77 | const strapifyRelation = new StrapifyRelation(relationElement, this.#strapiDataId, this.#strapiDataAttributes)
78 | this.#strapifyRelations.push(strapifyRelation);
79 |
80 | processPromises.push(strapifyRelation.process())
81 | })
82 |
83 | //wait for all strapify objects to process
84 | await Promise.allSettled(processPromises);
85 |
86 | //remove strapify-hide class from template element
87 | this.#templateElement.classList.remove("strapify-hide");
88 | }
89 | }
90 |
91 | export default StrapifyTemplate;
--------------------------------------------------------------------------------
/strapify/src/injector.js:
--------------------------------------------------------------------------------
1 | import StrapifyCollection from "./StrapifyCollection"
2 | import StrapifySingleType from "./StrapifySingleType";
3 | import StrapifyForm from "./StrapifyForm";
4 | import StrapifyEZFormsForm from "./StrapifyEZFormsForm";
5 | import Strapify from "./Strapify";
6 | import { strapiRequest } from "./util/strapiRequest";
7 |
8 | const version = process.env.VERSION;
9 | const debugMode = Strapify.debugMode;
10 |
11 | const hiddenTemplateElms = [];
12 | const hiddenSingleTypeElms = [];
13 |
14 | //wait for content to load and scripts to execute
15 | document.addEventListener("DOMContentLoaded", () => {
16 | if (debugMode) {
17 | //log the version
18 | console.log(`running strapify version ${version}`);
19 | }
20 |
21 | //create a class called strapify-hide and insert it into the head
22 | const strapifyHideStyle = document.createElement("style");
23 | strapifyHideStyle.innerHTML = ".strapify-hide { display: none !important; }";
24 | document.head.appendChild(strapifyHideStyle);
25 |
26 | //do a preparse for any template elms and hide them
27 | const templateElms = document.querySelectorAll("[strapi-template]");
28 | templateElms.forEach((templateElm) => {
29 | templateElm.classList.add("strapify-hide");
30 | hiddenTemplateElms.push(templateElm);
31 | });
32 |
33 | //do a preparse for any single type elms and hide them
34 | const singleTypeElms = document.querySelectorAll("[strapi-single-type]");
35 | singleTypeElms.forEach((singleTypeElm) => {
36 | singleTypeElm.classList.add("strapify-hide");
37 | hiddenSingleTypeElms.push(singleTypeElm);
38 | });
39 |
40 | //try to get the user from local storage
41 | const user = localStorage.getItem("user");
42 |
43 | //if the user exists, make a request to the user endpoint to test the jwt
44 | if (user) {
45 | strapiRequest("/api/users/me").then((response) => {
46 | //when we succeed, dispatch a custom event with the user data
47 | document.dispatchEvent(new CustomEvent("strapiUserAuthenticated", {
48 | bubbles: false,
49 | detail: {
50 | user: response
51 | }
52 | }));
53 | }).catch((error) => {
54 | //when we fail, dispatch a custom event to indicate that the user authentication failed
55 | document.dispatchEvent(new CustomEvent("strapiUserAuthenticationError", {
56 | bubbles: false,
57 | detail: {
58 | error: error
59 | }
60 | }));
61 |
62 | //then remove the user and jwt from local storage
63 | localStorage.removeItem("user");
64 | localStorage.removeItem("jwt");
65 |
66 | //then refresh the page
67 | window.location.reload();
68 | }).finally(() => {
69 | //in any case, strapify!!!
70 | strapify();
71 | });
72 | } else {
73 | //if there was no user in local storage, strapify!!!
74 | strapify();
75 | }
76 | });
77 |
78 | //when the strapify has initialized, write a message to the console
79 | document.addEventListener("strapifyInitialized", () => {
80 | if (debugMode) console.log("strapify finished");
81 | });
82 |
83 | //this is essentially the entry point for Strapify. It is called when the DOM is ready and user authenticated has been handled
84 | async function strapify() {
85 | //find all elements with the strapi-delete attribute and remove them
86 | const deleteElms = document.body.querySelectorAll("[strapi-delete]");
87 | deleteElms.forEach(deleteElm => deleteElm.remove());
88 |
89 | //find all top level elements (not descendents/processed by other strapify elements)
90 | const singleTypeElms = document.querySelectorAll(Strapify.validStrapifySingleTypeAttributes.map((attr) => `[${attr}]`).join(", "));
91 | const collectionElms = document.body.querySelectorAll("[strapi-collection]");
92 | const formElms = document.body.querySelectorAll("[strapi-form], [strapi-auth]");
93 | const logoutElms = document.body.querySelectorAll("[strapi-logout]");
94 | const ezFormsElms = Strapify.findEZFormElms();
95 |
96 | //the elements will be processed asynchronously, so we store the promises in an array on which we can await
97 | const processPromises = []
98 |
99 | //instantiate the strapify objects and process them
100 | for (let i = 0; i < formElms.length; i++) {
101 | const formElm = formElms[i]
102 | const strapifyForm = new StrapifyForm(formElm)
103 | processPromises.push(strapifyForm.process())
104 | }
105 | for (let i = 0; i < singleTypeElms.length; i++) {
106 | const singleTypeElm = singleTypeElms[i]
107 | const strapifySingleType = new StrapifySingleType(singleTypeElm);
108 | processPromises.push(strapifySingleType.process());
109 | }
110 | for (let i = 0; i < collectionElms.length; i++) {
111 | const collectionElm = collectionElms[i]
112 | const strapifyCollection = new StrapifyCollection(collectionElm);
113 | processPromises.push(strapifyCollection.process());
114 | }
115 | for (let i = 0; i < ezFormsElms.length; i++) {
116 | const ezFormsElm = ezFormsElms[i]
117 | const strapifyEZFormsForm = new StrapifyEZFormsForm(ezFormsElm);
118 | processPromises.push(strapifyEZFormsForm.process());
119 | }
120 |
121 | //logout elements are a simple case, so we just handle them here
122 | for (let i = 0; i < logoutElms.length; i++) {
123 | const logoutElm = logoutElms[i]
124 | const logoutRedirect = logoutElm.getAttribute("strapi-logout-redirect");
125 | logoutElm.addEventListener("click", () => {
126 | localStorage.removeItem("user");
127 | localStorage.removeItem("jwt");
128 | if (logoutRedirect) {
129 | window.location = logoutRedirect;
130 | } else {
131 | window.location.reload();
132 | }
133 | });
134 | }
135 |
136 | //wait for all the strapify objects to finish processing
137 | await Promise.allSettled(processPromises)
138 |
139 | //webflow cancer treatment
140 | // if (window.Webflow && window.Webflow.require) {
141 | // console.log("reinitializing ix2 (in strapify-injector)")
142 | // window.Webflow.destroy();
143 | // window.Webflow.ready();
144 | // window.Webflow.require("ix2").init();
145 | // document.dispatchEvent(new Event("readystatechange"));
146 | // }
147 |
148 | //dispatch the strapifyInitialized event
149 | document.dispatchEvent(new CustomEvent("strapifyInitialized", {
150 | bubbles: false,
151 | detail: {
152 | userAuthenticated: !!localStorage.getItem("user"),
153 | user: JSON.parse(localStorage.getItem("user"))
154 | }
155 | }));
156 | }
--------------------------------------------------------------------------------
/strapify/src/strapify-parser.js.pegjs:
--------------------------------------------------------------------------------
1 | {
2 | const operatorDict = {
3 | "&&": "and", "||": "or",
4 | "==": "eq", "!=": "ne",
5 | "<=": "le", ">=": "ge",
6 | "<": "lt", ">": "gt"
7 | }
8 | }
9 |
10 | entry =
11 | operator / comparison
12 |
13 | group =
14 | "(" _ exp: (operator / comparison) _ ")"
15 | {
16 | return exp
17 | }
18 |
19 | /* operators */
20 | operator =
21 | left: (group / comparison) _ op: ("||" / "&&") _ right: (group / comparison)
22 | {
23 | return {
24 | type: operatorDict[op],
25 | left: left,
26 | right: right
27 | }
28 | }
29 |
30 | comparison =
31 | left: (literal / variable) _
32 | op: ("==" / "<=" / ">=" / "!=" / "<" / ">") _
33 | right: (literal / variable) _
34 | {
35 | return {
36 | type: operatorDict[op],
37 | left: left,
38 | right: right
39 | }
40 | }
41 |
42 |
43 | /* variables */
44 | variable =
45 | variables: (simpleVariable "."?)+
46 | {
47 | let val = ""
48 | for(let i = 0; i < variables.length; i++) {
49 | val += variables[i][0].value
50 | if(variables[i][1]) {
51 | val += "."
52 | }
53 | }
54 |
55 | return {
56 | type: "variable",
57 | value: val
58 | }
59 | }
60 |
61 | simpleVariable =
62 | variable: [A-Za-z0-9\-\_]+
63 | {
64 | return {
65 | type: "variable",
66 | value: variable.join("")
67 | }
68 | }
69 |
70 | /* literals */
71 | literal =
72 | val: (string / number / boolean / null)
73 |
74 | string =
75 | "'" string: [^']* "'"
76 | {
77 | return {
78 | type: "string",
79 | value: string.join("")
80 | }
81 | }
82 |
83 | null =
84 | "null"
85 | {
86 | return {
87 | type: "null",
88 | value: null
89 | }
90 | }
91 |
92 | boolean =
93 | bool: ("true" / "false")
94 | {
95 | return {
96 | type: "boolean",
97 | value: bool
98 | }
99 | }
100 |
101 | number =
102 | num: float / integer
103 |
104 | float =
105 | first: integer '.' second: integer
106 | {
107 | return {
108 | type: "float",
109 | value: first.value + "." + second.value
110 | }
111 | }
112 |
113 | integer =
114 | digits: [0-9]+
115 | {
116 | return {
117 | type: "integer",
118 | value: digits.join("")
119 | }
120 | }
121 |
122 | _ "whitespace"
123 | = [ \t\n\r]*
--------------------------------------------------------------------------------
/strapify/src/util/strapiRequest.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import Strapify from "../Strapify";
3 | import ErrorHandler from "../StrapifyErrors";
4 |
5 | const strapiRequest = async (slug, queryString) => {
6 | const url = `${Strapify.apiURL}${slug}${queryString ? queryString : ""}`
7 | const jwt = localStorage.getItem("jwt");
8 |
9 | try {
10 | const headers = {}
11 |
12 | if (jwt) {
13 | headers["Authorization"] = `Bearer ${jwt}`;
14 | }
15 |
16 | const response = await axios.get(
17 | url, {
18 | headers: headers,
19 | });
20 | return response.data;
21 | } catch (err) {
22 | if (!err.response) {
23 | ErrorHandler.toast(`An unexpected error occurred trying to fetch data from ${url}. (No response)`);
24 | console.error(err);
25 | throw err
26 | }
27 | switch (err?.response.status) {
28 | case 401:
29 | ErrorHandler.warn(`Unable to access the collection or single type: "${slug.replace("/api/", "")}" due to missing or bad authentication. (401)`)
30 | break;
31 | case 403:
32 | ErrorHandler.warn(`You are not authorized to access the collection or single type: "${slug.replace("/api/", "")}". (403)`)
33 | break;
34 | case 404:
35 | ErrorHandler.error(`Invalid collection or single type: "${slug.replace("/api/", "")}" (404)`)
36 | break;
37 | default:
38 | ErrorHandler.toast(`An unexpected error occurred trying to fetch data from ${url}. (${err.response.status})`);
39 | console.error(err);
40 | break;
41 | }
42 | throw err
43 | }
44 | };
45 |
46 | const strapiRegister = async (formData) => {
47 | try {
48 | const response = await axios.post(`${Strapify.apiURL}/api/auth/local/register`, formData);
49 | return response.data;
50 | } catch (err) {
51 | throw err
52 | }
53 | };
54 |
55 | const strapiAuthenticate = async (identifier, password) => {
56 | try {
57 | const response = await axios.post(`${Strapify.apiURL}/api/auth/local`, {
58 | identifier: identifier,
59 | password: password,
60 | });
61 | return response.data;
62 | } catch (err) {
63 | throw err
64 | }
65 | }
66 |
67 | const strapiEZFormsSubmit = async (formElement) => {
68 | const formData = new FormData(formElement);
69 | const formDataJson = Object.fromEntries(formData.entries());
70 | const jwt = localStorage.getItem("jwt");
71 |
72 | try {
73 | const headers = {}
74 |
75 | if (jwt) {
76 | headers["Authorization"] = `Bearer ${jwt}`;
77 | }
78 |
79 | const response = await axios.post(
80 | `${Strapify.apiURL}/api/ezforms/submit`,
81 | { headers: headers, formData: formDataJson }
82 | );
83 | return response.data;
84 | } catch (err) {
85 | throw err
86 | }
87 | }
88 |
89 | export default strapiRequest;
90 | export { strapiRequest, strapiRegister, strapiAuthenticate, strapiEZFormsSubmit }
91 |
--------------------------------------------------------------------------------
/strapify/tests/DOM.test.js:
--------------------------------------------------------------------------------
1 | import { fail } from 'assert'
2 | import { DiffDOM } from "diff-dom"
3 | import htmlTemplates from './html-templates'
4 | import { writeFile, readFile, fileExists } from './util'
5 | const path = require('path')
6 |
7 | describe("DOM tests", () => {
8 | Object.keys(htmlTemplates).forEach((htmlTemplateName) => {
9 | //test each of the test definitions
10 | test(htmlTemplateName.replace(/-/g, " "), async () => {
11 | //we read the template into filePath, write the unvalidated file to unvalidatedFilePath, and compare it to the validated file at validatedFilePath
12 | const filePath = path.join(__dirname, `./html-templates/${htmlTemplateName}.html`)
13 | const unvalidatedFilePath = path.join(__dirname, `./html-tests-unvalidated/${htmlTemplateName}.html`)
14 | const validatedFilePath = path.join(__dirname, `./html-tests-validated/${htmlTemplateName}.html`)
15 |
16 | //restart puppeteer
17 | await jestPuppeteer.resetBrowser()
18 |
19 | //use this to block until strapify is finished
20 | const strapifyInitializedPromise = new Promise(async (resolve, reject) => {
21 | await page.exposeFunction("onStrapifyInitialized", () => {
22 | resolve()
23 | })
24 | })
25 |
26 | //add a listener for strapifyInitialized
27 | await page.evaluateOnNewDocument(() => {
28 | document.addEventListener("strapifyInitialized", () => {
29 | window.onStrapifyInitialized()
30 | })
31 | })
32 |
33 | //navigate to the template file
34 | await page.goto(filePath)
35 |
36 | //wait for strapify to finish
37 | await strapifyInitializedPromise
38 |
39 | //wait a bit for good measure
40 | //await page.waitForTimeout(500)
41 |
42 | //remove the strapify script element
43 | await page.evaluate(() => {
44 | document.querySelector("script").remove()
45 | })
46 |
47 | //write the unvalidated file
48 | const pageContents = await page.content()
49 | writeFile(unvalidatedFilePath, pageContents)
50 |
51 | //check for the validated file
52 | if (!fileExists(validatedFilePath)) {
53 | fail(`No validated file to compare to. Create the validated file with path ${validatedFilePath}`)
54 | }
55 |
56 | //read the validated file
57 | const validatedFileContents = readFile(validatedFilePath)
58 |
59 | //remove all tabs, newlines and double or more spaces from the page contents and validated file contents
60 | const cleanedPageContents = pageContents.replace(/\t|\n|\s{2,}/g, '')
61 | const cleanedValidatedFileContents = validatedFileContents.replace(/\t|\n|\s{2,}/g, '')
62 |
63 | //diff the two DOMs
64 | const diff = new DiffDOM().diff(cleanedPageContents, cleanedValidatedFileContents)
65 |
66 | //if the diff is not empty, write the diff to a file
67 | if (diff.length > 0) {
68 | writeFile(path.join(__dirname, `./test-logs/${htmlTemplateName}.log`), JSON.stringify(diff, null, 2))
69 | }
70 |
71 | await expect(diff).toEqual([])
72 | })
73 | })
74 | })
--------------------------------------------------------------------------------
/strapify/tests/Strapify.test.js:
--------------------------------------------------------------------------------
1 | import Strapify from '../strapify-src/strapify';
2 | import htmlTemplates from './html-templates'
3 |
4 | describe("Strapify.js", () => {
5 |
6 | describe("query string functions", () => {
7 |
8 | describe("getQueryStringVariables", () => {
9 | test("works with a single variable", () => {
10 | delete window.location
11 | window.location = new URL("https://www.example.com?var=Hello%20World")
12 |
13 | expect(Strapify.getQueryStringVariables()).toStrictEqual({ var: "Hello%20World" })
14 | })
15 | test("works with two variables", () => {
16 | delete window.location
17 | window.location = new URL("https://www.example.com?var1=Hello&var2=World")
18 |
19 | expect(Strapify.getQueryStringVariables()).toStrictEqual({ var1: "Hello", var2: "World" })
20 | })
21 | test("works with no variables", () => {
22 | delete window.location
23 | window.location = new URL("https://www.example.com")
24 |
25 | expect(Strapify.getQueryStringVariables()).toStrictEqual({})
26 | })
27 | })
28 |
29 | describe("substituteQueryStringVariables", () => {
30 | test("works with a single variable", () => {
31 | let input = "qs.var"
32 | delete window.location
33 | window.location = new URL("https://www.example.com?var=Hello%20World")
34 |
35 | expect(Strapify.substituteQueryStringVariables(input)).toBe("Hello%20World")
36 | })
37 | test("works with two variables", () => {
38 | let input = "qs.var1.qs.var2"
39 | delete window.location
40 | window.location = new URL("https://www.example.com?var1=Hello&var2=World")
41 |
42 | expect(Strapify.substituteQueryStringVariables(input)).toBe("Hello.World")
43 | })
44 | test("works with no variables", () => {
45 | let input = ""
46 | delete window.location
47 | window.location = new URL("https://www.example.com?var1=Hello&var2=World")
48 |
49 | expect(Strapify.substituteQueryStringVariables(input)).toBe("")
50 | })
51 | })
52 |
53 | describe("removeQueryStringVariableReferences", () => {
54 | test("works with a single occurance", () => {
55 | const input = "qs.var"
56 | expect(Strapify.removeQueryStringVariableReferences(input)).toBe("")
57 | })
58 |
59 | test("works with a double occurance", () => {
60 | const input = "qs.var.qs.var2"
61 | expect(Strapify.removeQueryStringVariableReferences(input)).toBe("")
62 | })
63 |
64 | test("works with leading word", () => {
65 | const input = "leading.qs.var"
66 | expect(Strapify.removeQueryStringVariableReferences(input)).toBe("leading")
67 | })
68 |
69 | test("works with trailing word", () => {
70 | const input = "qs.var.trailing"
71 | expect(Strapify.removeQueryStringVariableReferences(input)).toBe("trailing")
72 | })
73 |
74 | test("works with leading and trailing word", () => {
75 | const input = "leading.qs.var.trailing"
76 | expect(Strapify.removeQueryStringVariableReferences(input)).toBe("leading.trailing")
77 | })
78 |
79 | test("works with complex combination", () => {
80 | const input = "qs.var0.word0.qs.var1.word1.qs.var2.qs.var3.word2.qs.var4"
81 | expect(Strapify.removeQueryStringVariableReferences(input)).toBe("word0.word1.word2")
82 | })
83 |
84 | })
85 |
86 | })
87 | })
--------------------------------------------------------------------------------
/strapify/tests/html-templates.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const htmlTemplatePath = path.join(__dirname, 'html-templates');
5 | const htmlTemplates = {};
6 |
7 | //read in all the files in ./html-templates
8 | const files = fs.readdirSync(htmlTemplatePath);
9 |
10 | //for each file, read it in and add it to the htmlTemplates object
11 | files.forEach((file) => {
12 | const filePath = path.join(htmlTemplatePath, file);
13 | const fileContents = fs.readFileSync(filePath, 'utf8');
14 | htmlTemplates[file.replace(".html", "")] = fileContents;
15 | });
16 |
17 | function composeTemplates(templateNames, development = true) {
18 | //choose the base template
19 | const base = development ? htmlTemplates["base-development"] : htmlTemplates["base"];
20 |
21 | //content is inserted into the base template before the occurance of this string
22 | const insertBeforeString = "";
23 |
24 | //insert the content into the base template
25 | const insertionString = templateNames.reduce((acc, templateName) => {
26 | acc += htmlTemplates[templateName];
27 | acc += "\n"
28 | return acc;
29 | }, "");
30 |
31 | //insert the insertionString into the base template and return the result
32 | return base.replace(insertBeforeString, insertionString);
33 | }
34 |
35 | export default htmlTemplates
36 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/collection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | collection test
11 |
12 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/combined-filter-sort-page.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 | combined strapi-filter, strapi-sort and strapi-page test
21 |
22 | no sort, filter, page:
23 |
24 |
25 |
name
26 |
first last
27 |
number
28 |
boolean
29 |
enum
30 |
date
31 |
32 |
33 |
34 |
35 | sort by full_name, filter by number:
36 |
38 |
39 |
name
40 |
first last
41 |
number
42 |
boolean
43 |
enum
44 |
date
45 |
46 |
47 |
48 |
49 | sort by date enum, filter by number or enum:
50 |
52 |
53 |
name
54 |
first last
55 |
number
56 |
boolean
57 |
enum
58 |
date
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/components.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | components test
11 |
12 |
13 |
14 |
p
15 |
16 |
p
17 |
p
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/empty.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/nested-collection-deep.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | nested collection test
11 |
12 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/nested-collection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | nested collection test
11 |
12 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/nested-collections-and-relations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
24 |
25 |
26 |
27 | nested collections and relations test
28 |
29 |
30 |
33 |
34 |
35 |
40 |
41 |
42 |
collection A: element number
43 |
44 |
45 |
collection B: element number
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/single-type-components.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | single type components test
11 |
12 |
13 |
14 | p
15 |
16 |
17 |
18 | p
19 |
20 |
21 |
23 | p
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-background-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | collection test
11 |
12 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-class-add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
32 |
33 | strapi-class-add test
34 |
35 |
36 |
37 |
background only:
38 |
41 |
42 |
background and font:
43 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-class-conditional.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
32 |
33 | strapi-class-conditional test
34 |
35 |
36 |
37 |
38 |
blue if should_be_blue, transparent otherwise
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-class-replace.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
38 |
39 |
40 |
41 | strapi-class-replace test
42 |
43 |
44 |
45 |
background only:
46 |
49 |
50 |
background and font:
51 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-css-rule.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi-css-rule test
11 |
12 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-delete.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | collection test
11 |
12 |
17 |
18 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-field.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi field test
11 |
12 |
13 |
14 |
text
15 |
email
16 |
19 |
20 |
integer
21 |
big integer
22 |
decimal
23 |
float
24 |
25 |
enum
26 |
27 |
date
28 |
datetime
29 |
time
30 |
31 |
boolean
32 |
33 |
34 |
35 |
video from div:
36 |
37 |
38 |
video from video:
39 |
40 |
41 |
video from iframe nested in div:
42 |
43 |
44 |
45 |
46 |
video from iframe:
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-filter.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 | strapi-filter test
21 |
22 | no filter:
23 |
24 |
25 |
name
26 |
first last
27 |
number
28 |
boolean
29 |
enum
30 |
date
31 |
32 |
33 |
34 |
35 | filter by full_name:
36 |
38 |
39 |
name
40 |
first last
41 |
number
42 |
boolean
43 |
enum
44 |
date
45 |
46 |
47 |
48 |
49 | filter by full_name and age:
50 |
52 |
53 |
name
54 |
first last
55 |
number
56 |
boolean
57 |
enum
58 |
date
59 |
60 |
61 |
62 |
63 | filter by full_name or boolean:
64 |
66 |
67 |
name
68 |
first last
69 |
number
70 |
boolean
71 |
enum
72 |
date
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-into.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi-into test
11 |
12 |
13 |
14 |
url into src
15 |
16 |
17 |
url and alt text (multiple arguments)
18 |
19 |
20 |
url into style with template
21 |
22 |
23 |
url into style with and name (multiple arguments with template)
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-page-and-strapi-page-size.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 | strapi-page and strapi-page-size test
21 |
22 | no pagination:
23 |
24 |
25 |
name
26 |
first last
27 |
number
28 |
boolean
29 |
enum
30 |
date
31 |
32 |
33 |
34 |
35 | page size 3:
36 |
37 |
38 |
name
39 |
first last
40 |
number
41 |
boolean
42 |
enum
43 |
date
44 |
45 |
46 |
47 |
48 | page size 3 on page 2:
49 |
50 |
51 |
name
52 |
first last
53 |
number
54 |
boolean
55 |
enum
56 |
date
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-relation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
24 |
25 |
26 |
27 | strapi relation test
28 |
29 | one to many with collection A as parent:
30 |
31 |
32 |
collection A: element number
33 |
34 |
35 |
collection B: element number
36 |
37 |
38 |
39 |
40 |
41 |
42 | one to many with collection B as parent:
43 |
44 |
45 |
collection B: element number
46 |
47 |
48 |
collection A: element number
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | many to many with collection A as parent:
57 |
58 |
59 |
collection A: element number
60 |
61 |
62 |
collection B: element number
63 |
64 |
65 |
66 |
67 |
68 |
69 | many to many with collection B as parent:
70 |
71 |
72 |
collection B: element number
73 |
74 |
75 |
collection A: element number
76 |
77 |
78 |
79 |
80 |
81 |
82 | one to one with collection A as parent:
83 |
84 |
85 |
collection A: element number
86 |
87 |
88 |
collection B: element number
89 |
90 |
91 |
92 |
93 |
94 |
95 | one to one with collection B as parent:
96 |
97 |
98 |
collection B: element number
99 |
100 |
101 |
collection A: element number
102 |
103 |
104 |
105 |
106 |
107 |
108 | one to many A to B only:
109 |
110 |
111 |
collection A: element number
112 |
113 |
114 |
collection B: element number
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-background-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | single type background image test
11 |
12 |
13 |
this should have a background (:
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-class-add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
32 |
33 | strapi-single-type-class-add test
34 |
35 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-class-conditional.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
32 |
33 | strapi-single-type-class-conditional test
34 |
35 |
36 |
38 |
blue if should_be_blue, transparent otherwise
39 |
40 |
41 |
43 |
red if should_be_blue, transparent otherwise
44 |
45 |
46 |
48 |
blue if should_be_blue, red otherwise
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-class-replace.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
30 |
31 |
32 |
33 | strapi-single-type-class-replace test
34 |
35 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-css-rule.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi-single-type-css-rule test
11 |
12 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-field.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi single type field test
11 |
12 |
13 |
text
14 |
email
15 |
18 |
19 |
integer
20 |
big integer
21 |
decimal
22 |
float
23 |
24 |
enum
25 |
26 |
date
27 |
datetime
28 |
time
29 |
30 |
boolean
31 |
32 |
33 |
34 |
video from div:
35 |
36 |
37 |
video from video:
38 |
39 |
40 |
video from iframe nested in div:
41 |
42 |
43 |
44 |
45 |
video from iframe:
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-into.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi-single-type-into test
11 |
12 |
13 |
url into src
14 |
15 |
16 |
url and alt text (multiple arguments)
17 |
19 |
20 |
url into style with template
21 |
23 |
24 |
url into style with and name (multiple arguments with template)
25 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-relation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
24 |
25 |
26 |
27 | strapi-single-type-relation test
28 |
29 | one to one:
30 |
32 |
33 |
collection B: element number
34 |
35 |
36 |
37 |
38 | one to many:
39 |
41 |
42 |
collection B: element number
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-single-type-repeatable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | strapi-single-type-repeatable test
11 |
12 |
13 |
images:
14 |
15 |
16 |
17 |
18 |
19 |
20 |
videos:
21 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/strapify/tests/html-templates/strapi-sort.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
17 |
18 |
19 |
20 | strapi-sort test
21 |
22 | no sort:
23 |
24 |
25 |
name
26 |
first last
27 |
number
28 |
boolean
29 |
enum
30 |
date
31 |
32 |
33 |
34 |
35 | sort by name:
36 |
37 |
38 |
name
39 |
first last
40 |
number
41 |
boolean
42 |
enum
43 |
date
44 |
45 |
46 |
47 |
48 | sort by name and number desc:
49 |
50 |
51 |
name
52 |
first last
53 |
number
54 |
boolean
55 |
enum
56 |
date
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/strapify/tests/html-tests-validated/.gitkeep
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/collection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | collection test
8 |
9 |
10 |
11 |
12 |
Collection1 - entry 1
13 |
14 |
Collection1 - entry 2
15 |
16 |
Collection1 - entry 3
17 |
18 |
Collection1 - entry 4
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/components.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | components test
8 |
9 |
10 |
11 |
12 |
1A
13 |
14 |
1A
15 |
1B
16 |
17 |
18 |
19 |
2A
20 |
21 |
2A
22 |
2B
23 |
24 |
25 |
26 |
3A
27 |
28 |
3A
29 |
3B
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/empty.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/nested-collection-deep.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | nested collection test
8 |
9 |
10 |
11 |
12 |
13 |
Collection1 - entry 1
14 |
15 |
Collection1 - entry 2
16 |
17 |
Collection1 - entry 3
18 |
19 |
Collection1 - entry 4
20 |
21 |
22 |
23 |
24 |
Collection1 - entry 1
25 |
26 |
Collection1 - entry 2
27 |
28 |
Collection1 - entry 3
29 |
30 |
Collection1 - entry 4
31 |
32 |
33 |
34 |
35 |
Collection1 - entry 1
36 |
37 |
Collection1 - entry 2
38 |
39 |
Collection1 - entry 3
40 |
41 |
Collection1 - entry 4
42 |
43 |
44 |
45 |
Collection1 - entry 1
46 |
47 |
Collection1 - entry 2
48 |
49 |
Collection1 - entry 3
50 |
51 |
Collection1 - entry 4
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/nested-collection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | nested collection test
8 |
9 |
10 |
11 |
12 |
13 |
Collection1 - entry 1
14 |
15 |
Collection1 - entry 2
16 |
17 |
Collection1 - entry 3
18 |
19 |
Collection1 - entry 4
20 |
21 |
22 |
23 |
Collection1 - entry 1
24 |
25 |
Collection1 - entry 2
26 |
27 |
Collection1 - entry 3
28 |
29 |
Collection1 - entry 4
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/nested-collections-and-relations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
23 |
24 | nested collections and relations test
25 |
26 |
27 |
28 |
29 |
30 |
Collection1 - entry 1
31 |
32 |
Collection1 - entry 2
33 |
34 |
Collection1 - entry 3
35 |
36 |
Collection1 - entry 4
37 |
38 |
39 |
40 |
41 |
Collection1 - entry 1
42 |
43 |
Collection1 - entry 2
44 |
45 |
Collection1 - entry 3
46 |
47 |
Collection1 - entry 4
48 |
49 |
50 |
51 |
52 |
collection A: element 0
53 |
54 |
55 |
56 |
collection B: element 0
57 |
58 |
59 |
collection A: element 1
60 |
61 |
62 |
63 |
collection B: element 1
64 |
65 |
collection B: element 2
66 |
67 |
68 |
collection A: element 2
69 |
70 |
71 |
72 |
collection B: element 3
73 |
74 |
collection B: element 4
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/single-type-components.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | single type components test
8 |
9 |
10 |
A
11 |
12 |
A
13 |
14 |
B
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-background-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | collection test
8 |
9 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-class-add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
29 |
30 | strapi-class-add test
31 |
32 |
33 |
34 |
35 |
background only:
36 |
39 |
40 |
background and font:
41 |
44 |
45 |
46 |
47 |
background only:
48 |
51 |
52 |
background and font:
53 |
56 |
57 |
58 |
59 |
background only:
60 |
63 |
64 |
background and font:
65 |
68 |
69 |
70 |
71 |
background only:
72 |
75 |
76 |
background and font:
77 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-class-conditional.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
29 |
30 | strapi-class-conditional test
31 |
32 |
33 |
34 |
35 |
36 |
blue if should_be_blue, transparent otherwise
37 |
38 |
39 |
40 |
blue if should_be_blue, transparent otherwise
41 |
42 |
43 |
44 |
blue if should_be_blue, transparent otherwise
45 |
46 |
47 |
48 |
blue if should_be_blue, transparent otherwise
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-class-replace.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
35 |
36 |
37 |
38 | strapi-class-replace test
39 |
40 |
41 |
42 |
43 |
background only:
44 |
47 |
48 |
background and font:
49 |
52 |
53 |
54 |
55 |
background only:
56 |
59 |
60 |
background and font:
61 |
64 |
65 |
66 |
67 |
background only:
68 |
71 |
72 |
background and font:
73 |
76 |
77 |
78 |
79 |
background only:
80 |
83 |
84 |
background and font:
85 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-css-rule.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi-css-rule test
8 |
9 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-delete.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | collection test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Collection1 - entry 1
15 |
16 |
Collection1 - entry 2
17 |
18 |
Collection1 - entry 3
19 |
20 |
Collection1 - entry 4
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-field.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi field test
8 |
9 |
10 |
11 |
12 |
test text 1
13 |
testemail1@hotmail.com
14 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed scelerisque, sem sit amet accumsan dictum, leo neque finibus turpis, iaculis accumsan magna lectus et tellus. Praesent maximus elementum finibus. Donec aliquet tortor justo, eu ultrices velit mollis sit amet. In vitae blandit orci. Maecenas accumsan diam ligula, eu tristique dui eleifend id.
15 |
16 | point 1
17 | point 2
18 |
19 |
20 | point 1
21 | point 2
22 |
23 |
24 |
25 |
1000
26 |
100000000000
27 |
0.4443
28 |
0.6666
29 |
30 |
enum value 0
31 |
32 |
2023-01-10
33 |
2023-01-26T20:14:00.000Z
34 |
00:38:00.000
35 |
36 |
false
37 |
38 |
39 |
40 |
video from div:
41 |
42 |
43 |
video from video:
44 |
45 |
46 |
video from iframe nested in div:
47 |
48 | VIDEO
49 |
50 |
51 |
video from iframe:
52 |
VIDEOhttps://www.youtube.com/embed/jNQXAC9IVRw
53 |
54 |
55 |
56 |
57 |
test text 2
58 |
testemail2@hotmail.com
59 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed scelerisque, sem sit amet accumsan dictum, leo neque finibus turpis, iaculis accumsan magna lectus et tellus. Praesent maximus elementum finibus. Donec aliquet tortor justo, eu ultrices velit mollis sit amet. In vitae blandit orci. Maecenas accumsan diam ligula, eu tristique dui eleifend id.
60 |
61 | point 1
62 | point 2
63 |
64 |
65 | point 1
66 | point 2
67 |
68 |
69 |
70 |
1000
71 |
100000000000
72 |
0.4443
73 |
0.6666
74 |
75 |
enum value 0
76 |
77 |
2023-01-10
78 |
2023-01-26T20:14:00.000Z
79 |
00:38:00.000
80 |
81 |
false
82 |
83 |
84 |
85 |
video from div:
86 |
87 |
88 |
video from video:
89 |
90 |
91 |
video from iframe nested in div:
92 |
93 | VIDEO
94 |
95 |
96 |
video from iframe:
97 |
VIDEOhttps://www.youtube.com/watch?v=jNQXAC9IVRw
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-into.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi-into test
8 |
9 |
10 |
11 |
12 |
url into src
13 |
14 |
15 |
url and alt text (multiple arguments)
16 |
17 |
18 |
url into style with template
19 |
20 |
21 |
url into style with and name (multiple arguments with template)
22 |
23 |
24 |
doggy
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-repeatable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | repeatble test
11 |
12 |
13 |
14 |
text
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-background-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | single type background image test
8 |
9 |
10 |
this should have a background (:
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-class-add.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
29 |
30 | strapi-single-type-class-add test
31 |
32 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-class-conditional.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
29 |
30 | strapi-single-type-class-conditional test
31 |
32 |
33 |
34 |
blue if should_be_blue, transparent otherwise
35 |
36 |
37 |
38 |
red if should_be_blue, transparent otherwise
39 |
40 |
41 |
42 |
blue if should_be_blue, red otherwise
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-class-replace.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
28 |
29 |
30 | strapi-single-type-class-replace test
31 |
32 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-css-rule.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi-single-type-css-rule test
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-field.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi single type field test
8 |
9 |
10 |
test text 1
11 |
testemail1@hotmail.com
12 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed scelerisque, sem sit amet accumsan dictum, leo neque finibus turpis, iaculis accumsan magna lectus et tellus. Praesent maximus elementum finibus. Donec aliquet tortor justo, eu ultrices velit mollis sit amet. In vitae blandit orci. Maecenas accumsan diam ligula, eu tristique dui eleifend id.
13 |
14 | point 1
15 | point 2
16 |
17 |
18 | point 1
19 | point 2
20 |
21 |
22 |
23 |
1000
24 |
100000000000
25 |
0.4443
26 |
0.6666
27 |
28 |
enum value 0
29 |
30 |
2023-01-10
31 |
2023-01-14T05:25:00.000Z
32 |
22:57:00.000
33 |
34 |
false
35 |
36 |
37 |
38 |
video from div:
39 |
40 |
41 |
video from video:
42 |
43 |
44 |
video from iframe nested in div:
45 |
46 | VIDEO
47 |
48 |
49 |
video from iframe:
50 |
VIDEOhttps://www.youtube.com/embed/jNQXAC9IVRw
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-into.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi-single-type-into test
8 |
9 |
10 |
url into src
11 |
12 |
13 |
url and alt text (multiple arguments)
14 |
15 |
16 |
url into style with template
17 |
18 |
19 |
url into style with and name (multiple arguments with template)
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-relation.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
23 |
24 | strapi-single-type-relation test
25 |
26 | one to one:
27 |
28 |
29 |
30 |
collection B: element 0
31 |
32 |
33 |
34 | one to many:
35 |
36 |
37 |
38 |
collection B: element 0
39 |
40 |
collection B: element 1
41 |
42 |
collection B: element 2
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/strapify/tests/html-tests-validated/strapi-single-type-repeatable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | strapi-single-type-repeatable test
8 |
9 |
10 |
images:
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
videos:
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/strapify/tests/manual-tests/strapi-repeatable-pagination.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | repeatble pagination test
11 |
12 |
13 |
14 |
text
15 |
16 |
17 |
18 |
19 |
20 |
prev
21 |
next
22 |
23 |
24 |
25 |
28 |
29 |
prev
30 |
next
31 |
32 |
33 |
34 |
37 |
38 |
prev
39 |
next
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/strapify/tests/test-logs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/strapify/tests/test-logs/.gitkeep
--------------------------------------------------------------------------------
/strapify/tests/util.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 |
3 | function writeFile(filePath, contents) {
4 | //delete the file if it already exists
5 | if (fs.existsSync(filePath)) {
6 | fs.unlinkSync(filePath, (err) => {
7 | err && console.error(err)
8 | })
9 | }
10 |
11 | //create the file
12 | fs.writeFile(filePath, contents, (err) => {
13 | err && console.error(err)
14 | })
15 | }
16 |
17 | function readFile(filePath) {
18 | return fs.readFileSync(filePath, 'utf8')
19 | }
20 |
21 | function fileExists(filePath) {
22 | return fs.existsSync(filePath)
23 | }
24 |
25 | export {
26 | writeFile, readFile, fileExists
27 | }
--------------------------------------------------------------------------------
/strapify/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const { EnvironmentPlugin } = require('webpack');
3 | require('dotenv').config()
4 | //const WebpackBundleAnalyzer = require('webpack-bundle-analyzer')
5 | const CompressionPlugin = require("compression-webpack-plugin");
6 |
7 | module.exports = (env, argv) => {
8 | const plugins = [];
9 | if (env.analyze) {
10 | // plugins.push(new WebpackBundleAnalyzer.BundleAnalyzerPlugin());
11 | }
12 | if (env.gzip) {
13 | plugins.push(new CompressionPlugin({
14 | algorithm: 'gzip',
15 | }));
16 | }
17 |
18 |
19 |
20 | const version = process.env.VERSION;
21 | if (!version) throw new Error("VERSION environment variable not set. Please set it in the .env file.");
22 |
23 | plugins.push(new EnvironmentPlugin({
24 | VERSION: version,
25 | DEBUG: false
26 | }));
27 |
28 | return {
29 | entry: [path.resolve(__dirname, './src/injector.js')],
30 | output: {
31 | path: path.resolve(__dirname, './bundle'),
32 | filename: argv.mode === "development" ? `main.js` : `strapify-v${version}.js`
33 | },
34 | plugins: plugins,
35 | devtool: 'source-map',
36 | module: {
37 | rules: [
38 | {
39 | test: /\.m?js$/,
40 | exclude: /node_modules/,
41 | use: {
42 | loader: 'babel-loader',
43 | options: {
44 | presets: [
45 | ['@babel/preset-env', { targets: "defaults" }],
46 | ]
47 | }
48 | }
49 | }
50 | ]
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/test-client/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | public/build/bundle.*
4 |
--------------------------------------------------------------------------------
/test-client/README.md:
--------------------------------------------------------------------------------
1 | # test client
2 |
--------------------------------------------------------------------------------
/test-client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-app",
3 | "version": "1.0.0",
4 | "devDependencies": {
5 | "cross-env": "^7.0.3",
6 | "css-loader": "^5.0.1",
7 | "file-loader": "^6.2.0",
8 | "mini-css-extract-plugin": "^1.3.4",
9 | "svelte": "^3.31.2",
10 | "svelte-loader": "^3.0.0",
11 | "webpack": "^5.16.0",
12 | "webpack-cli": "^4.4.0",
13 | "webpack-dev-server": "^4.11.1"
14 | },
15 | "scripts": {
16 | "build": "cross-env NODE_ENV=production webpack",
17 | "dev": "webpack serve"
18 | },
19 | "dependencies": {
20 | "debounce": "^1.2.1",
21 | "url-exist": "^3.0.1"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test-client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 | Svelte app
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/test-client/src/components/App.svelte:
--------------------------------------------------------------------------------
1 |
94 |
95 |
96 |
97 |
98 |
99 |
111 |
112 |
113 | {#if successMessage && successMessage !== "waiting for url" && successMessage !== "webflow url successfully downloaded"}
114 |
{successMessage}
115 | {/if}
116 |
117 | {#if successMessage === "webflow url successfully downloaded"}
118 |
119 | {/if}
120 |
121 |
122 |
123 |
124 |
198 |
--------------------------------------------------------------------------------
/test-client/src/components/Header.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
STRAPIFY
12 |
13 |
14 |
21 |
29 |
36 |
37 |
42 |
43 |
44 |
45 |
90 |
--------------------------------------------------------------------------------
/test-client/src/components/StatusIndicator.svelte:
--------------------------------------------------------------------------------
1 |
30 |
31 |
32 |
{$$props.text}
33 |
34 |
35 |
36 |
57 |
--------------------------------------------------------------------------------
/test-client/src/components/URLInput.svelte:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/test-client/src/global.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap');
2 |
3 | html,
4 | body,
5 | div,
6 | span,
7 | applet,
8 | object,
9 | iframe,
10 | h1,
11 | h2,
12 | h3,
13 | h4,
14 | h5,
15 | h6,
16 | p,
17 | blockquote,
18 | pre,
19 | a,
20 | abbr,
21 | acronym,
22 | address,
23 | big,
24 | cite,
25 | code,
26 | del,
27 | dfn,
28 | em,
29 | img,
30 | ins,
31 | kbd,
32 | q,
33 | s,
34 | samp,
35 | small,
36 | strike,
37 | strong,
38 | sub,
39 | sup,
40 | tt,
41 | var,
42 | b,
43 | u,
44 | i,
45 | center,
46 | dl,
47 | dt,
48 | dd,
49 | ol,
50 | ul,
51 | li,
52 | fieldset,
53 | form,
54 | label,
55 | legend,
56 | table,
57 | caption,
58 | tbody,
59 | tfoot,
60 | thead,
61 | tr,
62 | th,
63 | td,
64 | article,
65 | aside,
66 | canvas,
67 | details,
68 | embed,
69 | figure,
70 | figcaption,
71 | footer,
72 | header,
73 | hgroup,
74 | menu,
75 | nav,
76 | output,
77 | ruby,
78 | section,
79 | summary,
80 | time,
81 | mark,
82 | audio,
83 | video,
84 | canvas,
85 | button {
86 | margin: 0;
87 | padding: 0;
88 | border: 0;
89 | font-family: 'Lato', sans-serif;
90 | box-sizing: border-box;
91 | }
92 |
93 | * {
94 | font-family: 'Lato', sans-serif;
95 | }
--------------------------------------------------------------------------------
/test-client/src/main.js:
--------------------------------------------------------------------------------
1 | import './global.css';
2 | import App from './components/App.svelte';
3 |
4 | const app = new App({
5 | target: document.body,
6 | props: {}
7 | });
8 |
9 | export default app;
10 |
--------------------------------------------------------------------------------
/test-client/src/scripts/post-webflow-url.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-client/src/scripts/post-webflow-url.js
--------------------------------------------------------------------------------
/test-client/webpack.config.js:
--------------------------------------------------------------------------------
1 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
2 | const path = require('path');
3 |
4 | const mode = process.env.NODE_ENV || 'development';
5 | const prod = mode === 'production';
6 |
7 | module.exports = {
8 | entry: {
9 | 'build/bundle': ['./src/main.js']
10 | },
11 | resolve: {
12 | alias: {
13 | svelte: path.dirname(require.resolve('svelte/package.json'))
14 | },
15 | extensions: ['.mjs', '.js', '.svelte'],
16 | mainFields: ['svelte', 'browser', 'module', 'main']
17 | },
18 | output: {
19 | path: path.join(__dirname, '../dist'),
20 | filename: '[name].js',
21 | chunkFilename: '[name].[id].js'
22 | },
23 | module: {
24 | rules: [
25 | {
26 | test: /\.svelte$/,
27 | use: {
28 | loader: 'svelte-loader',
29 | options: {
30 | compilerOptions: {
31 | dev: !prod
32 | },
33 | emitCss: prod,
34 | hotReload: !prod
35 | }
36 | }
37 | },
38 | {
39 | test: /\.css$/,
40 | use: [
41 | MiniCssExtractPlugin.loader,
42 | 'css-loader'
43 | ]
44 | },
45 | {
46 | // required to prevent errors from Svelte on Webpack 5+
47 | test: /node_modules\/svelte\/.*\.mjs$/,
48 | resolve: {
49 | fullySpecified: false
50 | }
51 | },
52 | {
53 | test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
54 | use: [
55 | {
56 | loader: 'file-loader',
57 | options: {
58 | name: '[name].[ext]',
59 | outputPath: 'fonts/'
60 | }
61 | }
62 | ]
63 | }
64 | ],
65 | },
66 | mode,
67 | plugins: [
68 | new MiniCssExtractPlugin({
69 | filename: '[name].css'
70 | })
71 | ],
72 | devtool: prod ? false : 'source-map',
73 | devServer: {
74 | static: path.resolve(__dirname, 'public'),
75 | open: true,
76 | hot: true,
77 | proxy: {
78 | '/api': {
79 | target: 'http://localhost:8080',
80 | router: () => 'http://localhost:3000',
81 | logLevel: 'debug' /*optional*/
82 | },
83 | }
84 | }
85 | };
86 |
--------------------------------------------------------------------------------
/test-server/output/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-server/output/.gitkeep
--------------------------------------------------------------------------------
/test-server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "strapify",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "node index",
8 | "starthot": "npx nodemon index"
9 | },
10 | "author": "Austin Goodman, Ray Keating",
11 | "license": "UNLICENSED",
12 | "dependencies": {
13 | "archiver": "^5.3.1",
14 | "cors": "^2.8.5",
15 | "dotenv": "^16.0.1",
16 | "express": "^4.18.1",
17 | "node-html-parser": "^6.1.1",
18 | "url-exist": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "nodemon": "^2.0.19"
22 | }
23 | }
--------------------------------------------------------------------------------
/test-strapi/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [{package.json,*.yml}]
12 | indent_style = space
13 | indent_size = 2
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/test-strapi/.env.example:
--------------------------------------------------------------------------------
1 | HOST=0.0.0.0
2 | PORT=1337
3 | APP_KEYS="toBeModified1,toBeModified2"
4 | API_TOKEN_SALT=tobemodified
5 | ADMIN_JWT_SECRET=tobemodified
6 | JWT_SECRET=tobemodified
7 |
--------------------------------------------------------------------------------
/test-strapi/.eslintignore:
--------------------------------------------------------------------------------
1 | .cache
2 | build
3 | **/node_modules/**
4 |
--------------------------------------------------------------------------------
/test-strapi/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "eslint:recommended",
4 | "env": {
5 | "commonjs": true,
6 | "es6": true,
7 | "node": true,
8 | "browser": false
9 | },
10 | "parserOptions": {
11 | "ecmaFeatures": {
12 | "experimentalObjectRestSpread": true,
13 | "jsx": false
14 | },
15 | "sourceType": "module"
16 | },
17 | "globals": {
18 | "strapi": true
19 | },
20 | "rules": {
21 | "indent": ["error", 2, { "SwitchCase": 1 }],
22 | "linebreak-style": ["error", "unix"],
23 | "no-console": 0,
24 | "quotes": ["error", "single"],
25 | "semi": ["error", "always"]
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test-strapi/.gitignore:
--------------------------------------------------------------------------------
1 | ############################
2 | # OS X
3 | ############################
4 |
5 | .DS_Store
6 | .AppleDouble
7 | .LSOverride
8 | Icon
9 | .Spotlight-V100
10 | .Trashes
11 | ._*
12 |
13 |
14 | ############################
15 | # Linux
16 | ############################
17 |
18 | *~
19 |
20 |
21 | ############################
22 | # Windows
23 | ############################
24 |
25 | Thumbs.db
26 | ehthumbs.db
27 | Desktop.ini
28 | $RECYCLE.BIN/
29 | *.cab
30 | *.msi
31 | *.msm
32 | *.msp
33 |
34 |
35 | ############################
36 | # Packages
37 | ############################
38 |
39 | *.7z
40 | *.csv
41 | *.dat
42 | *.dmg
43 | *.gz
44 | *.iso
45 | *.jar
46 | *.rar
47 | *.tar
48 | *.zip
49 | *.com
50 | *.class
51 | *.dll
52 | *.exe
53 | *.o
54 | *.seed
55 | *.so
56 | *.swo
57 | *.swp
58 | *.swn
59 | *.swm
60 | *.out
61 | *.pid
62 |
63 |
64 | ############################
65 | # Logs and databases
66 | ############################
67 |
68 | .tmp
69 | *.log
70 | *.sql
71 | *.sqlite
72 | *.sqlite3
73 |
74 |
75 | ############################
76 | # Misc.
77 | ############################
78 |
79 | *#
80 | ssl
81 | .idea
82 | nbproject
83 | public/uploads/*
84 | !public/uploads/.gitkeep
85 |
86 | ############################
87 | # Node.js
88 | ############################
89 |
90 | lib-cov
91 | lcov.info
92 | pids
93 | logs
94 | results
95 | node_modules
96 | .node_history
97 |
98 | ############################
99 | # Tests
100 | ############################
101 |
102 | testApp
103 | coverage
104 |
105 | ############################
106 | # Strapi
107 | ############################
108 |
109 | .env
110 | license.txt
111 | exports
112 | *.cache
113 | dist
114 | build
115 | .strapi-updater.json
116 |
--------------------------------------------------------------------------------
/test-strapi/README.md:
--------------------------------------------------------------------------------
1 | # 🚀 Getting started with Strapi
2 |
3 | Strapi comes with a full featured [Command Line Interface](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html) (CLI) which lets you scaffold and manage your project in seconds.
4 |
5 | ### `develop`
6 |
7 | Start your Strapi application with autoReload enabled. [Learn more](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html#strapi-develop)
8 |
9 | ```
10 | npm run develop
11 | # or
12 | yarn develop
13 | ```
14 |
15 | ### `start`
16 |
17 | Start your Strapi application with autoReload disabled. [Learn more](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html#strapi-start)
18 |
19 | ```
20 | npm run start
21 | # or
22 | yarn start
23 | ```
24 |
25 | ### `build`
26 |
27 | Build your admin panel. [Learn more](https://docs.strapi.io/developer-docs/latest/developer-resources/cli/CLI.html#strapi-build)
28 |
29 | ```
30 | npm run build
31 | # or
32 | yarn build
33 | ```
34 |
35 | ## ⚙️ Deployment
36 |
37 | Strapi gives you many possible deployment options for your project. Find the one that suits you on the [deployment section of the documentation](https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/deployment.html).
38 |
39 | ## 📚 Learn more
40 |
41 | - [Resource center](https://strapi.io/resource-center) - Strapi resource center.
42 | - [Strapi documentation](https://docs.strapi.io) - Official Strapi documentation.
43 | - [Strapi tutorials](https://strapi.io/tutorials) - List of tutorials made by the core team and the community.
44 | - [Strapi blog](https://docs.strapi.io) - Official Strapi blog containing articles made by the Strapi team and the community.
45 | - [Changelog](https://strapi.io/changelog) - Find out about the Strapi product updates, new features and general improvements.
46 |
47 | Feel free to check out the [Strapi GitHub repository](https://github.com/strapi/strapi). Your feedback and contributions are welcome!
48 |
49 | ## ✨ Community
50 |
51 | - [Discord](https://discord.strapi.io) - Come chat with the Strapi community including the core team.
52 | - [Forum](https://forum.strapi.io/) - Place to discuss, ask questions and find answers, show your Strapi project and get feedback or just talk with other Community members.
53 | - [Awesome Strapi](https://github.com/strapi/awesome-strapi) - A curated list of awesome things related to Strapi.
54 |
55 | ---
56 |
57 | 🤫 Psst! [Strapi is hiring](https://strapi.io/careers).
58 |
--------------------------------------------------------------------------------
/test-strapi/config/admin.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | auth: {
3 | secret: env('ADMIN_JWT_SECRET'),
4 | },
5 | apiToken: {
6 | salt: env('API_TOKEN_SALT'),
7 | },
8 | });
9 |
--------------------------------------------------------------------------------
/test-strapi/config/api.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | rest: {
3 | defaultLimit: 25,
4 | maxLimit: 100,
5 | withCount: true,
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/test-strapi/config/database.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = ({ env }) => ({
4 | connection: {
5 | client: 'sqlite',
6 | connection: {
7 | filename: path.join(__dirname, '..', env('DATABASE_FILENAME', '.tmp/data.db')),
8 | },
9 | useNullAsDefault: true,
10 | },
11 | });
12 |
--------------------------------------------------------------------------------
/test-strapi/config/middlewares.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | 'strapi::errors',
3 | 'strapi::security',
4 | 'strapi::cors',
5 | 'strapi::poweredBy',
6 | 'strapi::logger',
7 | 'strapi::query',
8 | 'strapi::body',
9 | 'strapi::session',
10 | 'strapi::favicon',
11 | 'strapi::public',
12 | ];
13 |
--------------------------------------------------------------------------------
/test-strapi/config/plugins.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | ezforms: {
3 | config: {
4 | captchaProvider: {
5 | name: 'none',
6 | },
7 | notificationProviders: []
8 | }
9 | }
10 | });
--------------------------------------------------------------------------------
/test-strapi/config/server.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ env }) => ({
2 | host: env('HOST', '0.0.0.0'),
3 | port: env.int('PORT', 1337),
4 | app: {
5 | keys: env.array('APP_KEYS'),
6 | },
7 | });
8 |
--------------------------------------------------------------------------------
/test-strapi/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/database/migrations/.gitkeep
--------------------------------------------------------------------------------
/test-strapi/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/favicon.png
--------------------------------------------------------------------------------
/test-strapi/media-src-files/Human Feeding The Little Squirrel.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/media-src-files/Human Feeding The Little Squirrel.mp4
--------------------------------------------------------------------------------
/test-strapi/media-src-files/clowfish.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/media-src-files/clowfish.mp4
--------------------------------------------------------------------------------
/test-strapi/media-src-files/dog tea.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/media-src-files/dog tea.jpg
--------------------------------------------------------------------------------
/test-strapi/media-src-files/mammal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/media-src-files/mammal.jpg
--------------------------------------------------------------------------------
/test-strapi/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "strapi-test",
3 | "private": true,
4 | "version": "0.1.0",
5 | "description": "A Strapi application",
6 | "scripts": {
7 | "develop": "strapi develop",
8 | "start": "strapi start",
9 | "build": "strapi build",
10 | "strapi": "strapi"
11 | },
12 | "dependencies": {
13 | "@strapi/plugin-i18n": "4.14.0",
14 | "@strapi/plugin-users-permissions": "4.14.0",
15 | "@strapi/strapi": "4.14.0",
16 | "better-sqlite3": "7.4.6",
17 | "strapi-plugin-ezforms": "^0.1.3"
18 | },
19 | "author": {
20 | "name": "A Strapi developer"
21 | },
22 | "strapi": {
23 | "uuid": "1b8a7640-976e-4d8a-aad3-999172cd4611"
24 | },
25 | "engines": {
26 | "node": ">=14.19.1 <=18.x.x",
27 | "npm": ">=6.0.0"
28 | },
29 | "license": "MIT"
30 | }
31 |
--------------------------------------------------------------------------------
/test-strapi/public/robots.txt:
--------------------------------------------------------------------------------
1 | # To prevent search engines from seeing the site altogether, uncomment the next two lines:
2 | # User-Agent: *
3 | # Disallow: /
4 |
--------------------------------------------------------------------------------
/test-strapi/public/uploads/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/public/uploads/.gitkeep
--------------------------------------------------------------------------------
/test-strapi/src/admin/app.example.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | locales: [
3 | // 'ar',
4 | // 'fr',
5 | // 'cs',
6 | // 'de',
7 | // 'dk',
8 | // 'es',
9 | // 'he',
10 | // 'id',
11 | // 'it',
12 | // 'ja',
13 | // 'ko',
14 | // 'ms',
15 | // 'nl',
16 | // 'no',
17 | // 'pl',
18 | // 'pt-BR',
19 | // 'pt',
20 | // 'ru',
21 | // 'sk',
22 | // 'sv',
23 | // 'th',
24 | // 'tr',
25 | // 'uk',
26 | // 'vi',
27 | // 'zh-Hans',
28 | // 'zh',
29 | ],
30 | };
31 |
32 | const bootstrap = (app) => {
33 | console.log(app);
34 | };
35 |
36 | export default {
37 | config,
38 | bootstrap,
39 | };
40 |
--------------------------------------------------------------------------------
/test-strapi/src/admin/webpack.config.example.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /* eslint-disable no-unused-vars */
4 | module.exports = (config, webpack) => {
5 | // Note: we provide webpack above so you should not `require` it
6 | // Perform customizations to webpack config
7 | // Important: return the modified config
8 | return config;
9 | };
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/src/api/.gitkeep
--------------------------------------------------------------------------------
/test-strapi/src/api/collection1/content-types/collection1/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "collection1_entries",
4 | "info": {
5 | "singularName": "collection1",
6 | "pluralName": "collection1-entries",
7 | "displayName": "Collection1",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "text": {
16 | "type": "string",
17 | "unique": true,
18 | "required": true
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test-strapi/src/api/collection1/controllers/collection1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * collection1 controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::collection1.collection1');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/collection1/routes/collection1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * collection1 router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::collection1.collection1');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/collection1/services/collection1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * collection1 service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::collection1.collection1');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-class-test/content-types/strapi-class-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_class_tests",
4 | "info": {
5 | "singularName": "strapi-class-test",
6 | "pluralName": "strapi-class-tests",
7 | "displayName": "Strapi Class Test"
8 | },
9 | "options": {
10 | "draftAndPublish": true
11 | },
12 | "pluginOptions": {},
13 | "attributes": {
14 | "background": {
15 | "type": "string"
16 | },
17 | "font": {
18 | "type": "string"
19 | },
20 | "should_be_blue": {
21 | "type": "boolean"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-class-test/controllers/strapi-class-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-class-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-class-test.strapi-class-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-class-test/routes/strapi-class-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-class-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-class-test.strapi-class-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-class-test/services/strapi-class-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-class-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-class-test.strapi-class-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-components-test/content-types/strapi-components-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_components_tests",
4 | "info": {
5 | "singularName": "strapi-components-test",
6 | "pluralName": "strapi-components-tests",
7 | "displayName": "Strapi Components Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "one_level_deep": {
16 | "displayName": "Component One Level Deep",
17 | "type": "component",
18 | "repeatable": false,
19 | "component": "nesting-tests.component-one-level-deep"
20 | },
21 | "two_levels_deep": {
22 | "type": "component",
23 | "repeatable": false,
24 | "component": "nesting-tests.component-two-levels-deep"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-components-test/controllers/strapi-components-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-components-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-components-test.strapi-components-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-components-test/routes/strapi-components-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-components-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-components-test.strapi-components-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-components-test/services/strapi-components-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-components-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-components-test.strapi-components-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-css-rule-test/content-types/strapi-css-rule-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_css_rule_tests",
4 | "info": {
5 | "singularName": "strapi-css-rule-test",
6 | "pluralName": "strapi-css-rule-tests",
7 | "displayName": "Strapi CSS Rule Test"
8 | },
9 | "options": {
10 | "draftAndPublish": true
11 | },
12 | "pluginOptions": {},
13 | "attributes": {
14 | "img_url": {
15 | "type": "string"
16 | },
17 | "color": {
18 | "type": "enumeration",
19 | "enum": [
20 | "red",
21 | "green",
22 | "blue"
23 | ]
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-css-rule-test/controllers/strapi-css-rule-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-css-rule-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-css-rule-test.strapi-css-rule-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-css-rule-test/routes/strapi-css-rule-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-css-rule-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-css-rule-test.strapi-css-rule-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-css-rule-test/services/strapi-css-rule-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-css-rule-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-css-rule-test.strapi-css-rule-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-field-test/content-types/strapi-field-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_field_tests",
4 | "info": {
5 | "singularName": "strapi-field-test",
6 | "pluralName": "strapi-field-tests",
7 | "displayName": "Strapi Field Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "text": {
16 | "type": "string"
17 | },
18 | "email": {
19 | "type": "email"
20 | },
21 | "rich_text": {
22 | "type": "richtext"
23 | },
24 | "number_integer": {
25 | "type": "integer"
26 | },
27 | "number_big_integer": {
28 | "type": "biginteger"
29 | },
30 | "number_decimal": {
31 | "type": "decimal"
32 | },
33 | "number_float": {
34 | "type": "float"
35 | },
36 | "enum": {
37 | "type": "enumeration",
38 | "enum": [
39 | "enum value 0",
40 | "enum value 1",
41 | "enum value 2"
42 | ]
43 | },
44 | "date": {
45 | "type": "date"
46 | },
47 | "datetime": {
48 | "type": "datetime"
49 | },
50 | "time": {
51 | "type": "time"
52 | },
53 | "image": {
54 | "type": "media",
55 | "multiple": false,
56 | "required": false,
57 | "allowedTypes": [
58 | "images"
59 | ]
60 | },
61 | "video": {
62 | "type": "media",
63 | "multiple": false,
64 | "required": false,
65 | "allowedTypes": [
66 | "videos"
67 | ]
68 | },
69 | "boolean": {
70 | "type": "boolean"
71 | },
72 | "video_url": {
73 | "type": "string"
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-field-test/controllers/strapi-field-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-field-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-field-test.strapi-field-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-field-test/routes/strapi-field-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-field-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-field-test.strapi-field-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-field-test/services/strapi-field-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-field-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-field-test.strapi-field-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-filter-sort-page-test/content-types/strapi-filter-sort-page-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_filter_sort_page_tests",
4 | "info": {
5 | "singularName": "strapi-filter-sort-page-test",
6 | "pluralName": "strapi-filter-sort-page-tests",
7 | "displayName": "Strapi Filter Sort Page Test"
8 | },
9 | "options": {
10 | "draftAndPublish": true
11 | },
12 | "pluginOptions": {},
13 | "attributes": {
14 | "full_name": {
15 | "type": "string"
16 | },
17 | "name": {
18 | "displayName": "Name",
19 | "type": "component",
20 | "repeatable": false,
21 | "component": "general.name"
22 | },
23 | "boolean": {
24 | "type": "boolean"
25 | },
26 | "number": {
27 | "type": "float"
28 | },
29 | "enum": {
30 | "type": "enumeration",
31 | "enum": [
32 | "enum0",
33 | "enum1",
34 | "enum2",
35 | "enum3"
36 | ]
37 | },
38 | "date": {
39 | "type": "date"
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-filter-sort-page-test/controllers/strapi-filter-sort-page-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-filter-sort-page-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-filter-sort-page-test.strapi-filter-sort-page-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-filter-sort-page-test/routes/strapi-filter-sort-page-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-filter-sort-page-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-filter-sort-page-test.strapi-filter-sort-page-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-filter-sort-page-test/services/strapi-filter-sort-page-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-filter-sort-page-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-filter-sort-page-test.strapi-filter-sort-page-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-into-test/content-types/strapi-into-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_into_tests",
4 | "info": {
5 | "singularName": "strapi-into-test",
6 | "pluralName": "strapi-into-tests",
7 | "displayName": "Strapi Into Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "image_info": {
16 | "displayName": "Image Info",
17 | "type": "component",
18 | "repeatable": false,
19 | "component": "general.image-info"
20 | },
21 | "name": {
22 | "type": "string"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-into-test/controllers/strapi-into-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-into-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-into-test.strapi-into-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-into-test/routes/strapi-into-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-into-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-into-test.strapi-into-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-into-test/services/strapi-into-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-into-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-into-test.strapi-into-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-a/content-types/strapi-relation-test-a/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_relation_test_as",
4 | "info": {
5 | "singularName": "strapi-relation-test-a",
6 | "pluralName": "strapi-relation-test-as",
7 | "displayName": "Strapi Relation Test A",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "text": {
16 | "type": "string"
17 | },
18 | "one_a_many_b": {
19 | "type": "relation",
20 | "relation": "oneToMany",
21 | "target": "api::strapi-relation-test-b.strapi-relation-test-b",
22 | "mappedBy": "many_b_one_a"
23 | },
24 | "many_b_many_a": {
25 | "type": "relation",
26 | "relation": "manyToMany",
27 | "target": "api::strapi-relation-test-b.strapi-relation-test-b",
28 | "inversedBy": "many_a_many_b"
29 | },
30 | "one_b_one_a": {
31 | "type": "relation",
32 | "relation": "oneToOne",
33 | "target": "api::strapi-relation-test-b.strapi-relation-test-b",
34 | "inversedBy": "one_a_one_b"
35 | },
36 | "one_way": {
37 | "type": "relation",
38 | "relation": "oneToMany",
39 | "target": "api::strapi-relation-test-b.strapi-relation-test-b"
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-a/controllers/strapi-relation-test-a.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-relation-test-a controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-relation-test-a.strapi-relation-test-a');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-a/routes/strapi-relation-test-a.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-relation-test-a router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-relation-test-a.strapi-relation-test-a');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-a/services/strapi-relation-test-a.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-relation-test-a service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-relation-test-a.strapi-relation-test-a');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-b/content-types/strapi-relation-test-b/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_relation_test_bs",
4 | "info": {
5 | "singularName": "strapi-relation-test-b",
6 | "pluralName": "strapi-relation-test-bs",
7 | "displayName": "Strapi Relation Test B",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "text": {
16 | "type": "string",
17 | "required": true,
18 | "unique": true
19 | },
20 | "many_b_one_a": {
21 | "type": "relation",
22 | "relation": "manyToOne",
23 | "target": "api::strapi-relation-test-a.strapi-relation-test-a",
24 | "inversedBy": "one_a_many_b"
25 | },
26 | "many_a_many_b": {
27 | "type": "relation",
28 | "relation": "manyToMany",
29 | "target": "api::strapi-relation-test-a.strapi-relation-test-a",
30 | "mappedBy": "many_b_many_a"
31 | },
32 | "one_a_one_b": {
33 | "type": "relation",
34 | "relation": "oneToOne",
35 | "target": "api::strapi-relation-test-a.strapi-relation-test-a",
36 | "mappedBy": "one_b_one_a"
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-b/controllers/strapi-relation-test-b.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-relation-test-b controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-relation-test-b.strapi-relation-test-b');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-b/routes/strapi-relation-test-b.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-relation-test-b router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-relation-test-b.strapi-relation-test-b');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-relation-test-b/services/strapi-relation-test-b.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-relation-test-b service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-relation-test-b.strapi-relation-test-b');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-repeatable-test/content-types/strapi-repeatable-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "collectionType",
3 | "collectionName": "strapi_repeatable_tests",
4 | "info": {
5 | "singularName": "strapi-repeatable-test",
6 | "pluralName": "strapi-repeatable-tests",
7 | "displayName": "Strapi Repeatable Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "text": {
16 | "type": "string"
17 | },
18 | "images": {
19 | "type": "media",
20 | "multiple": true,
21 | "required": false,
22 | "allowedTypes": [
23 | "images"
24 | ]
25 | },
26 | "videos": {
27 | "type": "media",
28 | "multiple": true,
29 | "required": false,
30 | "allowedTypes": [
31 | "videos"
32 | ]
33 | },
34 | "component": {
35 | "displayName": "Repeatable Test Component",
36 | "type": "component",
37 | "repeatable": true,
38 | "component": "general.repeatable-test-component"
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-repeatable-test/controllers/strapi-repeatable-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-repeatable-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-repeatable-test.strapi-repeatable-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-repeatable-test/routes/strapi-repeatable-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-repeatable-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-repeatable-test.strapi-repeatable-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-repeatable-test/services/strapi-repeatable-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-repeatable-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-repeatable-test.strapi-repeatable-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-class-test/content-types/strapi-single-type-class-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_class_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-class-test",
6 | "pluralName": "strapi-single-type-class-tests",
7 | "displayName": "Strapi Single Type Class Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "font": {
16 | "type": "string"
17 | },
18 | "background": {
19 | "type": "string"
20 | },
21 | "should_be_blue": {
22 | "type": "boolean"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-class-test/controllers/strapi-single-type-class-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-class-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-class-test.strapi-single-type-class-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-class-test/routes/strapi-single-type-class-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-class-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-class-test.strapi-single-type-class-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-class-test/services/strapi-single-type-class-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-class-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-class-test.strapi-single-type-class-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-components-test/content-types/strapi-single-type-components-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_components_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-components-test",
6 | "pluralName": "strapi-single-type-components-tests",
7 | "displayName": "Strapi Single Type Components Test"
8 | },
9 | "options": {
10 | "draftAndPublish": true
11 | },
12 | "pluginOptions": {},
13 | "attributes": {
14 | "one_level_deep": {
15 | "type": "component",
16 | "repeatable": false,
17 | "component": "nesting-tests.component-one-level-deep"
18 | },
19 | "two_levels_deep": {
20 | "type": "component",
21 | "repeatable": false,
22 | "component": "nesting-tests.component-two-levels-deep"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-components-test/controllers/strapi-single-type-components-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-components-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-components-test.strapi-single-type-components-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-components-test/routes/strapi-single-type-components-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-components-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-components-test.strapi-single-type-components-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-components-test/services/strapi-single-type-components-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-components-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-components-test.strapi-single-type-components-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-css-rule-test/content-types/strapi-single-type-css-rule-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_css_rule_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-css-rule-test",
6 | "pluralName": "strapi-single-type-css-rule-tests",
7 | "displayName": "Strapi Single Type CSS Rule Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "img_url": {
16 | "type": "string"
17 | },
18 | "color": {
19 | "type": "enumeration",
20 | "enum": [
21 | "red",
22 | "green",
23 | "blue"
24 | ]
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-css-rule-test/controllers/strapi-single-type-css-rule-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-css-rule-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-css-rule-test.strapi-single-type-css-rule-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-css-rule-test/routes/strapi-single-type-css-rule-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-css-rule-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-css-rule-test.strapi-single-type-css-rule-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-css-rule-test/services/strapi-single-type-css-rule-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-css-rule-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-css-rule-test.strapi-single-type-css-rule-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-field-test/content-types/strapi-single-type-field-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_field_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-field-test",
6 | "pluralName": "strapi-single-type-field-tests",
7 | "displayName": "Strapi Single Type Field Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "text": {
16 | "type": "string"
17 | },
18 | "email": {
19 | "type": "email"
20 | },
21 | "rich_text": {
22 | "type": "richtext"
23 | },
24 | "number_integer": {
25 | "type": "integer"
26 | },
27 | "number_big_integer": {
28 | "type": "biginteger"
29 | },
30 | "number_decimal": {
31 | "type": "decimal"
32 | },
33 | "number_float": {
34 | "type": "float"
35 | },
36 | "enum": {
37 | "type": "enumeration",
38 | "enum": [
39 | "enum value 0",
40 | "enum value 1",
41 | "enum value 2"
42 | ]
43 | },
44 | "date": {
45 | "type": "date"
46 | },
47 | "datetime": {
48 | "type": "datetime"
49 | },
50 | "time": {
51 | "type": "time"
52 | },
53 | "image": {
54 | "type": "media",
55 | "multiple": false,
56 | "required": false,
57 | "allowedTypes": [
58 | "images"
59 | ]
60 | },
61 | "video": {
62 | "type": "media",
63 | "multiple": false,
64 | "required": false,
65 | "allowedTypes": [
66 | "videos"
67 | ]
68 | },
69 | "boolean": {
70 | "type": "boolean"
71 | },
72 | "video_url": {
73 | "type": "string"
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-field-test/controllers/strapi-single-type-field-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-field-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-field-test.strapi-single-type-field-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-field-test/routes/strapi-single-type-field-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-field-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-field-test.strapi-single-type-field-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-field-test/services/strapi-single-type-field-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-field-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-field-test.strapi-single-type-field-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-into-test/content-types/strapi-single-type-into-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_into_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-into-test",
6 | "pluralName": "strapi-single-type-into-tests",
7 | "displayName": "Strapi Single Type Into Test"
8 | },
9 | "options": {
10 | "draftAndPublish": true
11 | },
12 | "pluginOptions": {},
13 | "attributes": {
14 | "image_info": {
15 | "type": "component",
16 | "repeatable": false,
17 | "component": "general.image-info"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-into-test/controllers/strapi-single-type-into-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-into-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-into-test.strapi-single-type-into-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-into-test/routes/strapi-single-type-into-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-into-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-into-test.strapi-single-type-into-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-into-test/services/strapi-single-type-into-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-into-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-into-test.strapi-single-type-into-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-relation-test/content-types/strapi-single-type-relation-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_relation_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-relation-test",
6 | "pluralName": "strapi-single-type-relation-tests",
7 | "displayName": "Strapi Single Type Relation Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "one_to_one": {
16 | "type": "relation",
17 | "relation": "oneToOne",
18 | "target": "api::strapi-relation-test-b.strapi-relation-test-b"
19 | },
20 | "one_to_many": {
21 | "type": "relation",
22 | "relation": "oneToMany",
23 | "target": "api::strapi-relation-test-b.strapi-relation-test-b"
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-relation-test/controllers/strapi-single-type-relation-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-relation-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-relation-test.strapi-single-type-relation-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-relation-test/routes/strapi-single-type-relation-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-relation-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-relation-test.strapi-single-type-relation-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-relation-test/services/strapi-single-type-relation-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-relation-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-relation-test.strapi-single-type-relation-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-repeatable-test/content-types/strapi-single-type-repeatable-test/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "kind": "singleType",
3 | "collectionName": "strapi_single_type_repeatable_tests",
4 | "info": {
5 | "singularName": "strapi-single-type-repeatable-test",
6 | "pluralName": "strapi-single-type-repeatable-tests",
7 | "displayName": "Strapi Single Type Repeatable Test",
8 | "description": ""
9 | },
10 | "options": {
11 | "draftAndPublish": true
12 | },
13 | "pluginOptions": {},
14 | "attributes": {
15 | "images": {
16 | "type": "media",
17 | "multiple": true,
18 | "required": false,
19 | "allowedTypes": [
20 | "images"
21 | ]
22 | },
23 | "videos": {
24 | "type": "media",
25 | "multiple": true,
26 | "required": false,
27 | "allowedTypes": [
28 | "videos"
29 | ]
30 | },
31 | "components": {
32 | "type": "component",
33 | "repeatable": true,
34 | "component": "general.repeatable-test-component"
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-repeatable-test/controllers/strapi-single-type-repeatable-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-repeatable-test controller
5 | */
6 |
7 | const { createCoreController } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreController('api::strapi-single-type-repeatable-test.strapi-single-type-repeatable-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-repeatable-test/routes/strapi-single-type-repeatable-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-repeatable-test router
5 | */
6 |
7 | const { createCoreRouter } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreRouter('api::strapi-single-type-repeatable-test.strapi-single-type-repeatable-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/api/strapi-single-type-repeatable-test/services/strapi-single-type-repeatable-test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * strapi-single-type-repeatable-test service
5 | */
6 |
7 | const { createCoreService } = require('@strapi/strapi').factories;
8 |
9 | module.exports = createCoreService('api::strapi-single-type-repeatable-test.strapi-single-type-repeatable-test');
10 |
--------------------------------------------------------------------------------
/test-strapi/src/components/general/image-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_general_image_infos",
3 | "info": {
4 | "displayName": "Image Info"
5 | },
6 | "options": {},
7 | "attributes": {
8 | "alt_text": {
9 | "type": "string"
10 | },
11 | "url": {
12 | "type": "string"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test-strapi/src/components/general/name.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_general_names",
3 | "info": {
4 | "displayName": "Name"
5 | },
6 | "options": {},
7 | "attributes": {
8 | "first": {
9 | "type": "string"
10 | },
11 | "last": {
12 | "type": "string"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/test-strapi/src/components/general/repeatable-test-component.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_general_repeatable_test_components",
3 | "info": {
4 | "displayName": "Repeatable Test Component"
5 | },
6 | "options": {},
7 | "attributes": {
8 | "text": {
9 | "type": "string"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test-strapi/src/components/nesting-tests/component-one-level-deep.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_nesting_tests_component_one_level_deeps",
3 | "info": {
4 | "displayName": "Component One Level Deep"
5 | },
6 | "options": {},
7 | "attributes": {
8 | "text": {
9 | "type": "string"
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test-strapi/src/components/nesting-tests/component-two-levels-deep.json:
--------------------------------------------------------------------------------
1 | {
2 | "collectionName": "components_nesting_tests_component_two_levels_deeps",
3 | "info": {
4 | "displayName": "Component Two Levels Deep"
5 | },
6 | "options": {},
7 | "attributes": {
8 | "text": {
9 | "type": "string"
10 | },
11 | "one_level_deep": {
12 | "type": "component",
13 | "repeatable": false,
14 | "component": "nesting-tests.component-one-level-deep"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test-strapi/src/extensions/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/strapify-dev/Strapify/021dfcdf383a85e79f8ad8195473e23787765881/test-strapi/src/extensions/.gitkeep
--------------------------------------------------------------------------------
/test-strapi/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | /**
5 | * An asynchronous register function that runs before
6 | * your application is initialized.
7 | *
8 | * This gives you an opportunity to extend code.
9 | */
10 | register(/*{ strapi }*/) {},
11 |
12 | /**
13 | * An asynchronous bootstrap function that runs before
14 | * your application gets started.
15 | *
16 | * This gives you an opportunity to set up your data model,
17 | * run jobs, or perform some special logic.
18 | */
19 | bootstrap(/*{ strapi }*/) {},
20 | };
21 |
--------------------------------------------------------------------------------
/test-strapi/types/generated/components.d.ts:
--------------------------------------------------------------------------------
1 | import type { Schema, Attribute } from '@strapi/strapi';
2 |
3 | export interface GeneralImageInfo extends Schema.Component {
4 | collectionName: 'components_general_image_infos';
5 | info: {
6 | displayName: 'Image Info';
7 | };
8 | attributes: {
9 | alt_text: Attribute.String;
10 | url: Attribute.String;
11 | };
12 | }
13 |
14 | export interface GeneralName extends Schema.Component {
15 | collectionName: 'components_general_names';
16 | info: {
17 | displayName: 'Name';
18 | };
19 | attributes: {
20 | first: Attribute.String;
21 | last: Attribute.String;
22 | };
23 | }
24 |
25 | export interface GeneralRepeatableTestComponent extends Schema.Component {
26 | collectionName: 'components_general_repeatable_test_components';
27 | info: {
28 | displayName: 'Repeatable Test Component';
29 | };
30 | attributes: {
31 | text: Attribute.String;
32 | };
33 | }
34 |
35 | export interface NestingTestsComponentOneLevelDeep extends Schema.Component {
36 | collectionName: 'components_nesting_tests_component_one_level_deeps';
37 | info: {
38 | displayName: 'Component One Level Deep';
39 | };
40 | attributes: {
41 | text: Attribute.String;
42 | };
43 | }
44 |
45 | export interface NestingTestsComponentTwoLevelsDeep extends Schema.Component {
46 | collectionName: 'components_nesting_tests_component_two_levels_deeps';
47 | info: {
48 | displayName: 'Component Two Levels Deep';
49 | };
50 | attributes: {
51 | text: Attribute.String;
52 | one_level_deep: Attribute.Component<'nesting-tests.component-one-level-deep'>;
53 | };
54 | }
55 |
56 | declare module '@strapi/types' {
57 | export module Shared {
58 | export interface Components {
59 | 'general.image-info': GeneralImageInfo;
60 | 'general.name': GeneralName;
61 | 'general.repeatable-test-component': GeneralRepeatableTestComponent;
62 | 'nesting-tests.component-one-level-deep': NestingTestsComponentOneLevelDeep;
63 | 'nesting-tests.component-two-levels-deep': NestingTestsComponentTwoLevelsDeep;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/version-history.md:
--------------------------------------------------------------------------------
1 | ## 0.0.0
2 | - initial release
3 |
4 | ## 0.0.1
5 | - Strapify now hides strapi-single-type and strapi-template elements until their content has been loaded (only when script is not deferred)
6 |
7 | ## 0.0.2
8 | - Enable pagination with strapi-repeatable
9 |
10 | ## 0.0.3
11 | - Added strapi-background-image, allow strapi-field and strapi-template to be defined on the same element
12 |
13 | ## 0.0.4
14 | - Fix breaking bug caused by lookbehind regex on mobile, added console message for basic errors
15 |
16 | ## 0.0.5
17 | - Add strapi-template-id attribute containing the ID to template elms (only on standard templates, not repeatables or relations).
18 |
19 | ## 0.0.6
20 | - allow absolute paths for images, fix bug where alt text is null if not defined
21 |
22 | ## 0.0.7
23 | - Update population to work with strapi v4.14.0
24 |
--------------------------------------------------------------------------------