@linktr.ee/create-link-app 0.3.0-next.38 → 0.3.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -29
- package/dist/commands/build.js +2 -3
- package/dist/commands/dev.js +1 -2
- package/dist/lib/create/create-project.js +0 -3
- package/dist/lib/deploy/pack-project.js +1 -12
- package/dist/webpack/webpack.config.js +40 -40
- package/html-template/development.html +2 -2
- package/html-template/production.html +2 -2
- package/oclif.manifest.json +1 -32
- package/package.json +5 -24
- package/templates/common/README.md +17 -38
- package/templates/common/fixtures/props-data.json +2 -1
- package/templates/common/gitignore +0 -1
- package/templates/common/settings.json +23 -11
- package/templates/react/package.json +2 -5
- package/templates/react/src/images/logo.png +0 -0
- package/templates/react/src/index.jsx +13 -4
- package/templates/react-ts/package.json +2 -5
- package/templates/react-ts/src/images/logo.png +0 -0
- package/templates/react-ts/src/index.tsx +19 -0
- package/templates/react-ts/src/types/global.d.ts +5 -11
- package/templates/react-ts/src/types/index.ts +7 -8
- package/dist/commands/generate-types.js +0 -111
- package/dist/commands/storybook.js +0 -28
- package/dist/lib/schema/compile.js +0 -30
- package/dist/postcss/postcss.config.js +0 -31
- package/dist/storybook/global.css +0 -53
- package/dist/storybook/main.js +0 -53
- package/dist/storybook/preview.js +0 -21
- package/templates/common/schema/editablePrivate.jtd.json +0 -6
- package/templates/common/schema/editablePublic.jtd.json +0 -10
- package/templates/common/schema/readonlyPrivate.jtd.json +0 -8
- package/templates/common/schema/readonlyPublic.jtd.json +0 -6
- package/templates/common/schema/system.jtd.json +0 -6
- package/templates/react/src/tailwind.css +0 -5
- package/templates/react-ts/src/App.tsx +0 -23
- package/templates/react-ts/src/Editor.tsx +0 -7
- package/templates/react-ts/src/Sheet.tsx +0 -7
- package/templates/react-ts/src/components/Layouts.tsx +0 -59
- package/templates/react-ts/src/stories/LinkApp.stories.tsx +0 -94
- package/templates/react-ts/src/stories/tailwind.sb.css +0 -5
- package/templates/react-ts/src/tailwind.css +0 -4
- package/templates/react-ts/src/types/schema/index.ts +0 -33
package/README.md
CHANGED
|
@@ -23,12 +23,10 @@ yarn create @linktr.ee/create-link-app my-link-app
|
|
|
23
23
|
* [`create-link-app create NAME`](#create-link-app-create-name)
|
|
24
24
|
* [`create-link-app deploy`](#create-link-app-deploy)
|
|
25
25
|
* [`create-link-app dev`](#create-link-app-dev)
|
|
26
|
-
* [`create-link-app generate-types`](#create-link-app-generate-types)
|
|
27
26
|
* [`create-link-app grant-access LINK_APP_ID USERNAME`](#create-link-app-grant-access-link_app_id-username)
|
|
28
27
|
* [`create-link-app help [COMMANDS]`](#create-link-app-help-commands)
|
|
29
28
|
* [`create-link-app login`](#create-link-app-login)
|
|
30
29
|
* [`create-link-app logout`](#create-link-app-logout)
|
|
31
|
-
* [`create-link-app storybook`](#create-link-app-storybook)
|
|
32
30
|
|
|
33
31
|
## `create-link-app build`
|
|
34
32
|
|
|
@@ -108,18 +106,6 @@ EXAMPLES
|
|
|
108
106
|
$ create-link-app dev --https
|
|
109
107
|
```
|
|
110
108
|
|
|
111
|
-
## `create-link-app generate-types`
|
|
112
|
-
|
|
113
|
-
Generate Typescript types from the schema definitions
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
USAGE
|
|
117
|
-
$ create-link-app generate-types
|
|
118
|
-
|
|
119
|
-
DESCRIPTION
|
|
120
|
-
Generate Typescript types from the schema definitions
|
|
121
|
-
```
|
|
122
|
-
|
|
123
109
|
## `create-link-app grant-access LINK_APP_ID USERNAME`
|
|
124
110
|
|
|
125
111
|
Grant access to other developers to push updates for your Link App
|
|
@@ -182,19 +168,4 @@ USAGE
|
|
|
182
168
|
DESCRIPTION
|
|
183
169
|
Logout and clear browser session
|
|
184
170
|
```
|
|
185
|
-
|
|
186
|
-
## `create-link-app storybook`
|
|
187
|
-
|
|
188
|
-
Start the Storybook development server
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
USAGE
|
|
192
|
-
$ create-link-app storybook [-p <value>]
|
|
193
|
-
|
|
194
|
-
FLAGS
|
|
195
|
-
-p, --port=<value> [default: 6006] Port to run the Storybook server on
|
|
196
|
-
|
|
197
|
-
DESCRIPTION
|
|
198
|
-
Start the Storybook development server
|
|
199
|
-
```
|
|
200
171
|
<!-- commandsstop -->
|
package/dist/commands/build.js
CHANGED
|
@@ -10,10 +10,9 @@ const webpack_config_1 = __importDefault(require("../webpack/webpack.config"));
|
|
|
10
10
|
class Build extends base_1.default {
|
|
11
11
|
async run() {
|
|
12
12
|
const { flags } = await this.parse(Build);
|
|
13
|
-
|
|
13
|
+
(0, webpack_1.default)((0, webpack_config_1.default)('production', {
|
|
14
14
|
allowAnyOrigin: flags['allow-any-origin'],
|
|
15
|
-
})
|
|
16
|
-
(0, webpack_1.default)(config, (err, stats) => {
|
|
15
|
+
}), (err, stats) => {
|
|
17
16
|
if (err) {
|
|
18
17
|
this.error(err);
|
|
19
18
|
}
|
package/dist/commands/dev.js
CHANGED
|
@@ -11,7 +11,6 @@ const webpack_config_1 = __importDefault(require("../webpack/webpack.config"));
|
|
|
11
11
|
class Dev extends base_1.default {
|
|
12
12
|
async run() {
|
|
13
13
|
const { flags } = await this.parse(Dev);
|
|
14
|
-
const config = await (0, webpack_config_1.default)('development');
|
|
15
14
|
const devServer = new webpack_dev_server_1.default({
|
|
16
15
|
client: {
|
|
17
16
|
overlay: false,
|
|
@@ -19,7 +18,7 @@ class Dev extends base_1.default {
|
|
|
19
18
|
hot: false,
|
|
20
19
|
https: flags.https,
|
|
21
20
|
port: flags.port,
|
|
22
|
-
}, (0, webpack_1.default)(
|
|
21
|
+
}, (0, webpack_1.default)((0, webpack_config_1.default)('development')));
|
|
23
22
|
await devServer.start();
|
|
24
23
|
}
|
|
25
24
|
}
|
|
@@ -14,9 +14,6 @@ const createProject = async (template, targetDir) => {
|
|
|
14
14
|
await fs_extra_1.default.copy(templateDir, targetDir);
|
|
15
15
|
await fs_extra_1.default.copy(templateCommonDir, targetDir);
|
|
16
16
|
await fs_extra_1.default.move(`${targetDir}/gitignore`, `${targetDir}/.gitignore`);
|
|
17
|
-
if (await fs_extra_1.default.existsSync(`${targetDir}/src/types/global.d.ts`)) {
|
|
18
|
-
await fs_extra_1.default.unlink(`${targetDir}/src/types/global.d.ts`);
|
|
19
|
-
}
|
|
20
17
|
// update `name` field in project manifest
|
|
21
18
|
const manifest = await fs_extra_1.default.readJson(`${targetDir}/manifest.json`);
|
|
22
19
|
manifest.name = (0, project_name_to_title_1.default)(path_1.default.basename(targetDir));
|
|
@@ -8,13 +8,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
/**
|
|
10
10
|
* Pack the Link App source files into `package.tgz`. This includes the following:
|
|
11
|
-
* - `schema/editablePublic.jtd.json`
|
|
12
|
-
* - `schema/readonlyPublic.jtd.json`
|
|
13
|
-
* - `schema/editablePrivate.jtd.json`
|
|
14
|
-
* - `schema/readonlyPrivate.jtd.json`
|
|
15
|
-
* - `schema/system.jtd.json`
|
|
16
11
|
* - `src/`
|
|
17
|
-
* - `schema.json`
|
|
18
12
|
* - `package.json`
|
|
19
13
|
* - `package-lock.json` - *optional*
|
|
20
14
|
* - `yarn.lock` - *optional*
|
|
@@ -36,7 +30,7 @@ async function packProject() {
|
|
|
36
30
|
gzipOptions: { level: 9 },
|
|
37
31
|
});
|
|
38
32
|
archive.on('warning', (err) => {
|
|
39
|
-
if (err
|
|
33
|
+
if (err.code === 'ENOENT') {
|
|
40
34
|
// lock files and tsconfig may or may not exist
|
|
41
35
|
const fileName = path_1.default.basename(err.path);
|
|
42
36
|
if (fileName === 'package-lock.json' || fileName === 'yarn.lock' || fileName === 'tsconfig.json') {
|
|
@@ -49,11 +43,6 @@ async function packProject() {
|
|
|
49
43
|
handleFailure(err);
|
|
50
44
|
});
|
|
51
45
|
archive.pipe(outputWriteStream);
|
|
52
|
-
archive.file(resolveProjPath('schema/editablePublic.jtd.json'), { name: 'schema/editablePublic.jtd.json' });
|
|
53
|
-
archive.file(resolveProjPath('schema/readonlyPublic.jtd.json'), { name: 'schema/readonlyPublic.jtd.json' });
|
|
54
|
-
archive.file(resolveProjPath('schema/editablePrivate.jtd.json'), { name: 'schema/editablePrivate.jtd.json' });
|
|
55
|
-
archive.file(resolveProjPath('schema/readonlyPrivate.jtd.json'), { name: 'schema/readonlyPrivate.jtd.json' });
|
|
56
|
-
archive.file(resolveProjPath('schema/system.jtd.json'), { name: 'schema/system.jtd.json' });
|
|
57
46
|
archive.file(resolveProjPath('package.json'), { name: 'package.json' });
|
|
58
47
|
archive.file(resolveProjPath('package-lock.json'), { name: 'package-lock.json' });
|
|
59
48
|
archive.file(resolveProjPath('yarn.lock'), { name: 'yarn.lock' });
|
|
@@ -13,35 +13,19 @@ const path_1 = __importDefault(require("path"));
|
|
|
13
13
|
const webpack_1 = require("webpack");
|
|
14
14
|
const camelcase_1 = __importDefault(require("camelcase"));
|
|
15
15
|
const slugify_1 = __importDefault(require("slugify"));
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const tailwindcss_1 = __importDefault(require("tailwindcss"));
|
|
17
|
+
const autoprefixer_1 = __importDefault(require("autoprefixer"));
|
|
18
18
|
const { ModuleFederationPlugin } = webpack_1.container;
|
|
19
|
-
function
|
|
20
|
-
const base64 = Buffer.from(code).toString('base64');
|
|
21
|
-
return `data:text/javascript;base64,${base64}`;
|
|
22
|
-
}
|
|
23
|
-
function hasEntrypoint(appDir, file) {
|
|
24
|
-
try {
|
|
25
|
-
fs_1.default.accessSync(path_1.default.resolve(appDir, 'src', file));
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
async function default_1(env, options) {
|
|
19
|
+
function default_1(env, options) {
|
|
33
20
|
const appDir = process.cwd();
|
|
34
21
|
const entryFile = path_1.default.resolve(__dirname, `${env}.entry`);
|
|
35
22
|
const htmlTemplateFile = path_1.default.resolve(__dirname, '..', '..', 'html-template', `${env}.html`);
|
|
36
|
-
const useAppEntry = hasEntrypoint(appDir, 'App.tsx');
|
|
37
|
-
const useSheetEntry = hasEntrypoint(appDir, 'Sheet.tsx');
|
|
38
|
-
const useEditorEntry = hasEntrypoint(appDir, 'Editor.tsx');
|
|
39
|
-
const appEntry = useAppEntry ? path_1.default.resolve(appDir, 'src/App') : path_1.default.resolve(appDir, 'src');
|
|
40
23
|
const manifestJson = JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(appDir, 'manifest.json'), 'utf8'));
|
|
41
24
|
const linkTypeName = manifestJson.name.replace(/[^A-Za-z0-9 ]/g, '');
|
|
42
25
|
const linkTypeSlug = (0, slugify_1.default)(linkTypeName, { lower: true });
|
|
43
26
|
const linkTypeId = (0, camelcase_1.default)(linkTypeSlug, { pascalCase: true });
|
|
44
27
|
const hasTsconfig = fileExists(path_1.default.resolve(appDir, 'tsconfig.json'));
|
|
28
|
+
const componentLibraryContentPath = path_1.default.join(require.resolve('@linktr.ee/component-library/tailwind.config').split('/').slice(0, -1).join('/'), 'dist', '**', '*.js');
|
|
45
29
|
const config = {
|
|
46
30
|
target: 'web',
|
|
47
31
|
mode: env,
|
|
@@ -49,9 +33,7 @@ async function default_1(env, options) {
|
|
|
49
33
|
output: {
|
|
50
34
|
publicPath: 'auto',
|
|
51
35
|
path: path_1.default.resolve(appDir, 'dist'),
|
|
52
|
-
assetModuleFilename: 'images/[hash]
|
|
53
|
-
chunkFilename: '[id].[contenthash].js',
|
|
54
|
-
filename: '[name].[contenthash].js',
|
|
36
|
+
assetModuleFilename: 'images/[hash][ext][query]',
|
|
55
37
|
},
|
|
56
38
|
module: {
|
|
57
39
|
rules: [
|
|
@@ -70,7 +52,7 @@ async function default_1(env, options) {
|
|
|
70
52
|
},
|
|
71
53
|
{
|
|
72
54
|
test: /\.(png|jpe?g|gif|svg)$/i,
|
|
73
|
-
type: 'asset/inline',
|
|
55
|
+
type: 'asset/inline',
|
|
74
56
|
},
|
|
75
57
|
{
|
|
76
58
|
test: /\.css$/,
|
|
@@ -80,7 +62,33 @@ async function default_1(env, options) {
|
|
|
80
62
|
{
|
|
81
63
|
loader: 'postcss-loader',
|
|
82
64
|
options: {
|
|
83
|
-
postcssOptions: {
|
|
65
|
+
postcssOptions: {
|
|
66
|
+
plugins: [
|
|
67
|
+
(0, tailwindcss_1.default)({
|
|
68
|
+
content: [`${appDir}/src/**/*.{js,jsx,ts,tsx}`, componentLibraryContentPath],
|
|
69
|
+
important: `.ui-link-app-${linkTypeSlug}`,
|
|
70
|
+
presets: [require('@linktr.ee/component-library/tailwind.config')],
|
|
71
|
+
plugins: [],
|
|
72
|
+
theme: {
|
|
73
|
+
extend: {
|
|
74
|
+
backgroundImage: {
|
|
75
|
+
loading: 'linear-gradient(90deg,#f3f3f1,#fff,#f3f3f1);',
|
|
76
|
+
},
|
|
77
|
+
keyframes: {
|
|
78
|
+
loading: {
|
|
79
|
+
'75%': { transform: 'translateX(100%)' },
|
|
80
|
+
'100%': { transform: 'translateX(100%)' },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
animation: {
|
|
84
|
+
loading: 'loading 1.5s ease-in-out infinite',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
(0, autoprefixer_1.default)(),
|
|
90
|
+
],
|
|
91
|
+
},
|
|
84
92
|
},
|
|
85
93
|
},
|
|
86
94
|
],
|
|
@@ -93,12 +101,15 @@ async function default_1(env, options) {
|
|
|
93
101
|
// TODO: The behaviour here with module resolution is confusing, can we make it more explicit?
|
|
94
102
|
modules: [path_1.default.resolve(appDir, 'node_modules'), 'node_modules'],
|
|
95
103
|
alias: {
|
|
96
|
-
'@linktr.ee/extension':
|
|
104
|
+
'@linktr.ee/extension': path_1.default.resolve(appDir, 'src'),
|
|
97
105
|
},
|
|
98
106
|
},
|
|
99
107
|
plugins: [
|
|
100
108
|
new html_webpack_plugin_1.default({
|
|
101
109
|
template: htmlTemplateFile,
|
|
110
|
+
templateParameters: {
|
|
111
|
+
tailwindBaseClass: `ui-link-app-${linkTypeSlug}`,
|
|
112
|
+
},
|
|
102
113
|
excludeChunks: [`LinkApp_${linkTypeId}`],
|
|
103
114
|
}),
|
|
104
115
|
],
|
|
@@ -116,17 +127,6 @@ async function default_1(env, options) {
|
|
|
116
127
|
config.plugins.push(new mini_css_extract_plugin_1.default());
|
|
117
128
|
}
|
|
118
129
|
if (env === 'production') {
|
|
119
|
-
const exposedEntryPoints = {
|
|
120
|
-
// Default entry points
|
|
121
|
-
['./App']: appEntry,
|
|
122
|
-
['./validate']: toVirtualModule((await (0, compile_1.default)())),
|
|
123
|
-
};
|
|
124
|
-
if (useEditorEntry) {
|
|
125
|
-
exposedEntryPoints['./Editor'] = path_1.default.resolve(appDir, 'src/Editor');
|
|
126
|
-
}
|
|
127
|
-
if (useSheetEntry) {
|
|
128
|
-
exposedEntryPoints['./Sheet'] = path_1.default.resolve(appDir, 'src/Sheet');
|
|
129
|
-
}
|
|
130
130
|
// TODO: Figure out how to manage externals with Module Federation
|
|
131
131
|
// Possibly make the index.html a host app, via separate webpack config
|
|
132
132
|
// config.externals = {
|
|
@@ -141,8 +141,6 @@ async function default_1(env, options) {
|
|
|
141
141
|
};
|
|
142
142
|
config.plugins.push(new webpack_1.DefinePlugin({
|
|
143
143
|
__ALLOW_ANY_ORIGIN__: options?.allowAnyOrigin,
|
|
144
|
-
__LINK_TYPE_SLUG__: JSON.stringify(linkTypeSlug),
|
|
145
|
-
__LINK_TYPE_ID__: JSON.stringify(linkTypeId),
|
|
146
144
|
}),
|
|
147
145
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
148
146
|
// @ts-ignore
|
|
@@ -152,7 +150,9 @@ async function default_1(env, options) {
|
|
|
152
150
|
}), new ModuleFederationPlugin({
|
|
153
151
|
name: `LinkApp_${linkTypeId}`,
|
|
154
152
|
filename: 'remoteEntry.js',
|
|
155
|
-
exposes:
|
|
153
|
+
exposes: {
|
|
154
|
+
['./App']: path_1.default.resolve(appDir, 'src'),
|
|
155
|
+
},
|
|
156
156
|
shared: {
|
|
157
157
|
react: {
|
|
158
158
|
singleton: true,
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.3.0-next.
|
|
2
|
+
"version": "0.3.0-next.4",
|
|
3
3
|
"commands": {
|
|
4
4
|
"build": {
|
|
5
5
|
"id": "build",
|
|
@@ -139,17 +139,6 @@
|
|
|
139
139
|
},
|
|
140
140
|
"args": {}
|
|
141
141
|
},
|
|
142
|
-
"generate-types": {
|
|
143
|
-
"id": "generate-types",
|
|
144
|
-
"description": "Generate Typescript types from the schema definitions",
|
|
145
|
-
"strict": true,
|
|
146
|
-
"pluginName": "@linktr.ee/create-link-app",
|
|
147
|
-
"pluginAlias": "@linktr.ee/create-link-app",
|
|
148
|
-
"pluginType": "core",
|
|
149
|
-
"aliases": [],
|
|
150
|
-
"flags": {},
|
|
151
|
-
"args": {}
|
|
152
|
-
},
|
|
153
142
|
"grant-access": {
|
|
154
143
|
"id": "grant-access",
|
|
155
144
|
"description": "Grant access to other developers to push updates for your Link App",
|
|
@@ -227,26 +216,6 @@
|
|
|
227
216
|
}
|
|
228
217
|
},
|
|
229
218
|
"args": {}
|
|
230
|
-
},
|
|
231
|
-
"storybook": {
|
|
232
|
-
"id": "storybook",
|
|
233
|
-
"description": "Start the Storybook development server",
|
|
234
|
-
"strict": true,
|
|
235
|
-
"pluginName": "@linktr.ee/create-link-app",
|
|
236
|
-
"pluginAlias": "@linktr.ee/create-link-app",
|
|
237
|
-
"pluginType": "core",
|
|
238
|
-
"aliases": [],
|
|
239
|
-
"flags": {
|
|
240
|
-
"port": {
|
|
241
|
-
"name": "port",
|
|
242
|
-
"type": "option",
|
|
243
|
-
"char": "p",
|
|
244
|
-
"description": "Port to run the Storybook server on",
|
|
245
|
-
"multiple": false,
|
|
246
|
-
"default": 6006
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
"args": {}
|
|
250
219
|
}
|
|
251
220
|
}
|
|
252
221
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linktr.ee/create-link-app",
|
|
3
|
-
"version": "0.3.0-next.
|
|
3
|
+
"version": "0.3.0-next.4",
|
|
4
4
|
"description": "Create a Link App on Linktr.ee.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "Linktree",
|
|
@@ -19,14 +19,13 @@
|
|
|
19
19
|
"/templates"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "shx rm -rf dist && tsc -b
|
|
22
|
+
"build": "shx rm -rf dist && tsc -b",
|
|
23
23
|
"postpack": "shx rm -f oclif.manifest.json",
|
|
24
24
|
"prepack": "yarn build && oclif manifest && oclif readme",
|
|
25
25
|
"test": "jest --watch",
|
|
26
26
|
"test:ci": "jest",
|
|
27
27
|
"test:cov": "jest --coverage",
|
|
28
|
-
"version": "oclif readme && git add README.md"
|
|
29
|
-
"copy-storybook-global-css": "cp ./src/storybook/global.css ./dist/storybook/global.css"
|
|
28
|
+
"version": "oclif readme && git add README.md"
|
|
30
29
|
},
|
|
31
30
|
"dependencies": {
|
|
32
31
|
"@babel/core": "^7.18.2",
|
|
@@ -35,22 +34,9 @@
|
|
|
35
34
|
"@babel/preset-react": "^7.17.12",
|
|
36
35
|
"@babel/preset-typescript": "^7.17.12",
|
|
37
36
|
"@babel/runtime": "^7.18.3",
|
|
38
|
-
"@linktr.ee/component-library": "
|
|
39
|
-
"@linktr.ee/ui-link-kit": "latest",
|
|
37
|
+
"@linktr.ee/component-library": "^7.0.17",
|
|
40
38
|
"@oclif/core": "^1.9.0",
|
|
41
39
|
"@oclif/plugin-help": "^5.1.12",
|
|
42
|
-
"@storybook/addon-actions": "^6.5.9",
|
|
43
|
-
"@storybook/addon-essentials": "^6.5.9",
|
|
44
|
-
"@storybook/addon-interactions": "^6.5.9",
|
|
45
|
-
"@storybook/addon-links": "^6.5.9",
|
|
46
|
-
"@storybook/addon-postcss": "^2.0.0",
|
|
47
|
-
"@storybook/builder-webpack5": "^6.5.9",
|
|
48
|
-
"@storybook/manager-webpack5": "^6.5.9",
|
|
49
|
-
"@storybook/react": "^6.5.9",
|
|
50
|
-
"@tailwindcss/line-clamp": "^0.4.4",
|
|
51
|
-
"@testing-library/react": "^12.1.4",
|
|
52
|
-
"@testing-library/user-event": "14",
|
|
53
|
-
"ajv": "^8.12.0",
|
|
54
40
|
"archiver": "^5.3.1",
|
|
55
41
|
"autoprefixer": "^10.4.14",
|
|
56
42
|
"axios": "^0.27.2",
|
|
@@ -67,17 +53,12 @@
|
|
|
67
53
|
"netrc-parser": "^3.1.6",
|
|
68
54
|
"openid-client": "^5.1.6",
|
|
69
55
|
"postcss": "^8.4.21",
|
|
70
|
-
"postcss-loader": "^4.3.0",
|
|
71
|
-
"prettier": "^2.8.8",
|
|
72
|
-
"prop-types": "^15.8.1",
|
|
73
56
|
"react": "^17.0.2",
|
|
74
57
|
"react-dom": "^17.0.2",
|
|
75
58
|
"slugify": "^1.6.6",
|
|
76
|
-
"storybook-addon-designs": "^6.3.1",
|
|
77
|
-
"storybook-addon-turbo-build": "^1.1.0",
|
|
78
59
|
"style-loader": "^3.3.2",
|
|
79
60
|
"styled-components": "^5.3.5",
|
|
80
|
-
"tailwindcss": "^3.3.
|
|
61
|
+
"tailwindcss": "^3.3.1",
|
|
81
62
|
"typescript": "^4.7.3",
|
|
82
63
|
"webpack": "^5.75.0",
|
|
83
64
|
"webpack-dev-server": "^4.11.1"
|
|
@@ -14,34 +14,13 @@ Optionally, you can specify a different port or serve over HTTPS. Run command wi
|
|
|
14
14
|
|
|
15
15
|
Several files were created during the bootstrapping of this project. Some of these files play a key role:
|
|
16
16
|
|
|
17
|
-
| File
|
|
18
|
-
|
|
|
19
|
-
| `src/index.jsx`
|
|
20
|
-
| `manifest.json`
|
|
21
|
-
| `settings.json`
|
|
22
|
-
| `fixtures/props-data.json` | Used during development, this file acts as mock data for the `settings.json` output, it is injected as props to the entry point component
|
|
23
|
-
| `url-match-rules.json`
|
|
24
|
-
| `schema/*.jtd.json` | These files define the shape of the data that is stored for each Link that uses this Link App. They are used to validate the data on the front and back end and to generate Typescript types shared between client and server. The format for these schemas adheres to the [JSON Type Definition](https://jsontypedef.com/), aka [RFC 8927](https://datatracker.ietf.org/doc/html/rfc8927), standard. |
|
|
25
|
-
|
|
26
|
-
## Generating types from your `schema/*.jtd.json` files
|
|
27
|
-
|
|
28
|
-
Under the hood Linktree uses the `jtd-codegen` package to generate types from your schema. If you want to generate types for local development, this package must first be installed on your system. You can install it with the following command:
|
|
29
|
-
|
|
30
|
-
```sh
|
|
31
|
-
brew install jsontypedef/jsontypedef/jtd-codegen
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
You will also require `prettier`
|
|
35
|
-
|
|
36
|
-
```sh
|
|
37
|
-
brew install prettier
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
When you have these packages installed, you can generate types by running one of the following commands:
|
|
41
|
-
|
|
42
|
-
`npm run generate:types` or `yarn generate:types`
|
|
43
|
-
|
|
44
|
-
For more information on using `jtd-codegen` to generate code see the [official documentation](https://jsontypedef.com/docs/jtd-codegen/), or for specifics on generating Typescript code [here](https://jsontypedef.com/docs/typescript-codegen/).
|
|
17
|
+
| File | Description |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `src/index.jsx` | The entry point for your Link App |
|
|
20
|
+
| `manifest.json` | Defines key information about your Link App, and helps users to discover your Link App via the [Linktree Marketplace](https://linktr.ee/marketplace) |
|
|
21
|
+
| `settings.json` | Defines the settings made available to Linktree users when configuring the Link App via [Linktree Admin](https://linktr.ee/admin) |
|
|
22
|
+
| `fixtures/props-data.json` | Used during development, this file acts as mock data for the `settings.json` output, it is injected as props to the entry point component |
|
|
23
|
+
| `url-match-rules.json` | Defines the URL pattern to match against when users add a link on Linktree via URL, its structure follows the [URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) |
|
|
45
24
|
|
|
46
25
|
## UI Components
|
|
47
26
|
|
|
@@ -93,18 +72,18 @@ Access to a Link App can be granted to additional users who may need to retrieve
|
|
|
93
72
|
|
|
94
73
|
Please note the user receiving access must also have a Linktree account with developer privileges. Maintainer access can be granted to as many developer accounts as required.
|
|
95
74
|
|
|
96
|
-
|
|
75
|
+
***Note: Only the Link App Owner can grant Maintainer access to additional users. You must be logged in with an Owner account in order to use the command.***
|
|
97
76
|
|
|
98
77
|
### Maintainer and Owner Permitted Actions
|
|
99
78
|
|
|
100
79
|
The following table compares which actions are permitted for Maintainers and Owners:
|
|
101
80
|
|
|
102
|
-
|
|
|
103
|
-
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
81
|
+
|Action |Owner |Maintainer|Notes |
|
|
82
|
+
|---------------------------|-------|----------|-----------------------------------------------|
|
|
83
|
+
|Create Link App |✓|N/A |Owner is defined when Link App is first created|
|
|
84
|
+
|Get Link App |✓|✓ | |
|
|
85
|
+
|Update Link App |✓|✓ | |
|
|
86
|
+
|Request Link App review |✓|✓ | |
|
|
87
|
+
|Get Link App maintainers |✓|✓ | |
|
|
88
|
+
|Add new Link App maintainer|✓|✗ | |
|
|
89
|
+
|Remove Link App maintainer |✓|✗ | |
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
"title": "Link
|
|
2
|
+
"title": "Link Type",
|
|
3
|
+
"overview": {
|
|
4
|
+
"title": "You can have a heading",
|
|
5
|
+
"description": "as well as a description to inform users on what the link does."
|
|
6
|
+
},
|
|
3
7
|
"elements": [
|
|
4
8
|
{
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
+
"inputType": "linkBehavior",
|
|
10
|
+
"id": "how_link_behaves",
|
|
11
|
+
"title": "How would you like the link to behave?",
|
|
12
|
+
"description": "When a user interacts with this link:",
|
|
13
|
+
"linkBehaviorLabels": {
|
|
14
|
+
"embedLabel": "Embed content on the profile",
|
|
15
|
+
"linkOffLabel": "Go directly to URL"
|
|
16
|
+
},
|
|
17
|
+
"defaultValue": "embedLabel"
|
|
9
18
|
},
|
|
10
19
|
{
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
20
|
+
"inputType": "switch",
|
|
21
|
+
"id": "toggle",
|
|
22
|
+
"title": "Use another title/description to break up content",
|
|
23
|
+
"description": "and describe what the next section of inputs will do",
|
|
24
|
+
"label": "Is feature enabled?",
|
|
25
|
+
"defaultValue": true
|
|
14
26
|
},
|
|
15
27
|
{
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
28
|
+
"inputType": "text",
|
|
29
|
+
"id": "your_name",
|
|
30
|
+
"label": "elements that only have a label will stick close the element above"
|
|
19
31
|
}
|
|
20
32
|
]
|
|
21
33
|
}
|
|
@@ -3,13 +3,10 @@
|
|
|
3
3
|
"scripts": {
|
|
4
4
|
"build": "create-link-app build",
|
|
5
5
|
"deploy": "create-link-app deploy",
|
|
6
|
-
"
|
|
7
|
-
"dev": "create-link-app dev",
|
|
8
|
-
"generate:types": "jtd-codegen ./schema.json --typescript-out src/types --root-name=LinkAppData"
|
|
6
|
+
"dev": "create-link-app dev"
|
|
9
7
|
},
|
|
10
8
|
"devDependencies": {
|
|
11
|
-
"@linktr.ee/
|
|
12
|
-
"@linktr.ee/create-link-app": "next",
|
|
9
|
+
"@linktr.ee/create-link-app": "latest",
|
|
13
10
|
"@linktr.ee/ui-link-kit": "latest"
|
|
14
11
|
}
|
|
15
12
|
}
|
|
Binary file
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Container, Description, Header } from '@linktr.ee/ui-link-kit'
|
|
2
2
|
|
|
3
|
-
import './
|
|
3
|
+
import logo from './images/logo.png'
|
|
4
4
|
|
|
5
|
-
function App({
|
|
6
|
-
return
|
|
5
|
+
function App({ toggle, your_name, __linkUrl }) {
|
|
6
|
+
return (
|
|
7
|
+
<Container
|
|
8
|
+
primaryCta={toggle ? { label: 'Visit our UI docs for more info', href: 'https://blstrco.github.io/ui-link-kit/' } : null}
|
|
9
|
+
secondaryCta={toggle ? { label: 'Original url for your Linktree link', href: __linkUrl } : null}
|
|
10
|
+
logo={logo}
|
|
11
|
+
>
|
|
12
|
+
<Header heading={`Hello ${your_name}!`} secondaryHeading="Congratulations, you now have a Linktree link!" layout="hero" />
|
|
13
|
+
<Description>{your_name}</Description>
|
|
14
|
+
</Container>
|
|
15
|
+
)
|
|
7
16
|
}
|
|
8
17
|
|
|
9
18
|
export default App
|
|
@@ -3,13 +3,10 @@
|
|
|
3
3
|
"scripts": {
|
|
4
4
|
"build": "create-link-app build",
|
|
5
5
|
"deploy": "create-link-app deploy",
|
|
6
|
-
"
|
|
7
|
-
"dev": "create-link-app dev",
|
|
8
|
-
"generate:types": "create-link-app generate-types"
|
|
6
|
+
"dev": "create-link-app dev"
|
|
9
7
|
},
|
|
10
8
|
"devDependencies": {
|
|
11
|
-
"@linktr.ee/
|
|
12
|
-
"@linktr.ee/create-link-app": "next",
|
|
9
|
+
"@linktr.ee/create-link-app": "latest",
|
|
13
10
|
"@linktr.ee/ui-link-kit": "latest",
|
|
14
11
|
"@types/react": "^17.0.0",
|
|
15
12
|
"@types/react-dom": "^17.0.0"
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Container, Description, Header } from '@linktr.ee/ui-link-kit'
|
|
2
|
+
import { SettingsData } from './types'
|
|
3
|
+
|
|
4
|
+
import logo from './images/logo.png'
|
|
5
|
+
|
|
6
|
+
function App({ toggle, your_name, __linkUrl }: SettingsData) {
|
|
7
|
+
return (
|
|
8
|
+
<Container
|
|
9
|
+
primaryCta={toggle ? { label: 'Visit our UI docs for more info', href: 'https://blstrco.github.io/ui-link-kit/' } : null}
|
|
10
|
+
secondaryCta={toggle ? { label: 'Original url for your Linktree link', href: __linkUrl } : null}
|
|
11
|
+
logo={logo}
|
|
12
|
+
>
|
|
13
|
+
<Header heading={`Hello ${your_name}!`} secondaryHeading="Congratulations, you now have a Linktree link!" layout="hero" />
|
|
14
|
+
<Description>{your_name}</Description>
|
|
15
|
+
</Container>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default App
|